Reference Partitioning

Ve verzi 11g se objevilo několik zajímavých vylepšení v oblasti partitioningu.
Již poměrně známé vylepšení je nový typ partitioningu, který rozšiřuje stávající RANGE partitioning. Nový INTERVAL partitioning umožňuje automaticky vytvářet nové partitions, podle toho do jakého intervalu daná hodnota (NUMBER nebo DATE) patří. Pokud neexistuje partition do které by Oracle mohl daný řádek zařadit, tak automaticky vytvoří novou partition pojmenovanou SYS_Pxxxx.

Co už ale není tolik známé vylepšení, ale je velice důležité, je REFERENCE PARTITIONING. Pokud již nekdo pracoval s partitions a řešil problémy s referenční integritou nad partitionovanými tabulkami, které bylo nutné odstraňovat, tak tato nová vlastnost ho velice potěší.

O co tedy jde ?

Do verze 10g nebylo možné DROPnout partition, pokud se na ní odkazovala jiná tabulka přes cizí klíč.
Oracle nebyl schopen zajistit že odstraněním partition nedojde zároveň k odstranění nějakých řádků na které se odkazují záznamy v jiné tabulce.
Toto dokonce nešlo ani v případě kdy byly nejdříve všechny řádky vymazány. Bylo vždy nutné vypnout cizí klíč aby se mohla partition DROPnout, jenže při zapínání cizího klíče musel oracle zbytečně dlouho kontrolovat referenční integritu.
Ovšem pokud vytvoříte novou partition a nikdy do ní nevložíte žádná data, potom DROP funguje i se zapnutým cizím klíčem ve stavu NOVALIDATE. Této "vlastnosti" lze na 10g využít tak, že pokud chcete dropnout nějakou partition s daty a nechcete kvůli tomu vypínat constraint, tak lze využít partition exchange, který data místo dropnutí zamění s jinou (nově vytvořenou) tabulkou a starou partition můžete DROPnout. Tabulku pak samozřejmě také.
Tento trik byl popsán Jonathanem Lewisem zde (http://jonathanlewis.wordpress.com/2006/12/10/drop-parent-partition/).

Na 11g je vše ale výrazně jednodušší. Při definici partitionované tabulky která je závisla na jiné partitionované tabulce, lze použít REFERENCE PARTITIONIG tímto způsobem:

CREATE TABLE master_tab (
id NUMBER NOT NULL,
create_date DATE,
CONSTRAINT master_tab_pk PRIMARY KEY (id)
)
PARTITION BY RANGE (create_date)
(
PARTITION P_2010 VALUES LESS THAN (TO_DATE('01.01.2011','DD.MM.YYYY')),
PARTITION P_2011 VALUES LESS THAN (TO_DATE('01.01.2012','DD.MM.YYYY'))
);

CREATE TABLE detail_table (
id NUMBER NOT NULL,
master_tab_id NUMBER NOT NULL,
create_date DATE,
CONSTRAINT detail_tab_pk PRIMARY KEY (id),
CONSTRAINT detail_master_tab_fk FOREIGN KEY (master_tab_id)
REFERENCES master_tab (id)
)
PARTITION BY REFERENCE (detail_master_tab_fk);

Takto Oracle bude vždy držet synchronizovaná data v obou partitionách. Vytvořením nové partition v MASTER_TAB se vytvoří stejně pojmenovaná partition v DETAIL_TAB.
Oracle je schopen v tomto případě zajistit že odstraněním stejné partition z MASTER_TAB i DETAIL_TAB se nemůže porušit konzistence dat.
Odstranění partition z MASTER_TAB odstraní automaticky i všechny závislé partition v jiných tabulkách. PARTITION BY REFERENCE lze použít i kaskádovitě pro více tabulek.

Další výhodou je joinování takových tabulek. Oracle v tomto případě může použít "partition-wise join" což znamená že se joinují vždy jen spojené partition z každé tabulky.