Create parent table
create table orders (
order_id int
primary key
not null,
order_datetime date
not null,
customer_id int
not null
)
Table created.
Create child table
create table order_items (
order_id
constraint order_fk
references orders ( order_id )
on delete cascade -- we'll need this!
not null,
product_id integer
not null,
deprecated_column integer,
primary key (
order_id, product_id
)
)
Table created.
Deprecate a column by setting it unused
alter table order_items
set unused column deprecated_column
Table altered.
Add partitioning to parent table
alter table orders
modify partition by range ( order_datetime )
interval ( interval '1' month ) (
partition p0 values less than ( date'2022-01-01' )
)
Table altered.
Add reference partitioning to child table
alter table order_items
modify partition by reference ( order_fk )
Table altered.
Verify both tables are partitioned
select table_name, partition_name
from user_tab_partitions
where table_name like 'ORDER%'
TABLE_NAME | PARTITION_NAME | ORDERS | P0 | ORDER_ITEMS | P0 |
---|
Create a table to swap with partitions in the child
create table order_items_stage as
select * from order_items
where 1 = 0
Table created.
alter table order_items
exchange partition p0
with table order_items_stage
ORA-14097: column type or size mismatch in ALTER TABLE EXCHANGE PARTITIONMore Details: https://docs.oracle.com/error-help/db/ora-14097
Check columns in ORDER_ITEMS tables
select table_name, column_name, hidden_column
from user_tab_cols
where table_name like 'ORDER_ITEM%'
order by column_name
TABLE_NAME | COLUMN_NAME | HIDDEN_COLUMN | ORDER_ITEMS | ORDER_ID | NO | ORDER_ITEMS_STAGE | ORDER_ID | NO | ORDER_ITEMS | PRODUCT_ID | NO | ORDER_ITEMS_STAGE | PRODUCT_ID | NO | ORDER_ITEMS | SYS_C00003_22051708:52:34$ | YES |
---|
drop table order_items_stage
cascade constraints purge
Table dropped.
Create staging parent table for exchange
create table orders_stage
for exchange with table orders
Table created.
Create staging child table for exchange
create table order_items_stage
for exchange with table order_items
Table created.
Add parent constraints
alter table orders_stage
add primary key ( order_id )
Table altered.
Add constraint to child staging table
alter table order_items_stage
add foreign key ( order_id )
references orders_stage ( order_id )
on delete cascade
Table altered.
Load data
begin
insert into orders values ( 1, date'2022-05-01', 1 );
insert into order_items values ( 1, 1 );
commit;
end;
Statement processed.
Exchange partition
alter table orders
exchange partition for ( date'2022-05-01' )
with table orders_stage
ORA-02266: unique/primary keys in table referenced by enabled foreign keysMore Details: https://docs.oracle.com/error-help/db/ora-02266
Cascade partition exchange
alter table orders
exchange partition for ( date'2022-05-01' )
with table orders_stage
cascade
Table altered.
select * from order_items
no data found
select * from order_items_stage
ORDER_ID | PRODUCT_ID | 1 | 1 |
---|
Create a partitioned archive table
create table orders_archive
partition by range ( order_datetime )
interval ( interval '1' month ) (
partition p0 values less than ( date'2022-01-01' )
)
for exchange with table orders
Table created.
Create child archive table
create table order_items_archive
for exchange with table order_items
Table created.
alter table orders_archive
add primary key ( order_id )
Table altered.
alter table order_items_archive
add constraint order_archive_fk
foreign key ( order_id )
references orders_archive ( order_id )
on delete cascade
Table altered.
Partition child archive table
alter table order_items_archive
modify partition by reference ( order_archive_fk )
Table altered.
Transfer the data from the staging tables to the archives
alter table orders_archive
exchange partition for ( date'2022-05-01' )
with table orders_stage
cascade
Table altered.
select * from order_items_stage
no data found
select * from order_items_archive
ORDER_ID | PRODUCT_ID | 1 | 1 |
---|
How is partition exchange so fast?!
select object_name, subobject_name, object_id, data_object_id
from user_objects
where object_name like 'ORDER%'
and data_object_id is not null
and (
object_type = 'TABLE' or
object_type = 'TABLE PARTITION' and subobject_name like 'SYS%'
)
order by substr ( object_name, 1, 6 ), object_id
OBJECT_NAME | SUBOBJECT_NAME | OBJECT_ID | DATA_OBJECT_ID | ORDERS_STAGE | - | 123954182 | 123954215 | ORDERS | SYS_P443420 | 123954187 | 123954182 | ORDERS_ARCHIVE | SYS_P443421 | 123954215 | 123954187 | ORDER_ITEMS_STAGE | - | 123954185 | 123954216 | ORDER_ITEMS | SYS_P443420 | 123954188 | 123954185 | ORDER_ITEMS_ARCHIVE | SYS_P443421 | 123954216 | 123954188 |
---|
View the partitions
select table_name, partition_name
from user_tab_partitions
where table_name like 'ORDER%'
TABLE_NAME | PARTITION_NAME | ORDERS | P0 | ORDERS | SYS_P443420 | ORDERS_ARCHIVE | P0 | ORDERS_ARCHIVE | SYS_P443421 | ORDER_ITEMS | P0 | ORDER_ITEMS | SYS_P443420 | ORDER_ITEMS_ARCHIVE | P0 | ORDER_ITEMS_ARCHIVE | SYS_P443421 |
---|
Remove the archived partitions
alter table orders
drop partition for ( date'2022-05-01' )
Table altered.
select table_name, partition_name
from user_tab_partitions
where table_name like 'ORDER%'
TABLE_NAME | PARTITION_NAME | ORDERS | P0 | ORDERS_ARCHIVE | P0 | ORDERS_ARCHIVE | SYS_P443421 | ORDER_ITEMS | P0 | ORDER_ITEMS_ARCHIVE | P0 | ORDER_ITEMS_ARCHIVE | SYS_P443421 |
---|