Takže to, co chcete, je zhmotnit tranzitivní uzávěry. To znamená, že vzhledem k této tabulce aplikací ...
ID | PARENT_ID
------+----------
1 |
2 | 1
3 | 2
4 | 2
5 | 4
... tabulka grafu by vypadala takto:
PARENT_ID | CHILD_ID
-----------+----------
1 | 2
1 | 3
1 | 4
1 | 5
2 | 3
2 | 4
2 | 5
4 | 5
V Oracle je možné udržovat tabulku jako je tato, ačkoli pro ni budete muset vytvořit svůj vlastní rámec. Otázkou je, zda to za tu režii stojí. Pokud je zdrojová tabulka nestálá, může udržování aktuálních dat grafu stát více cyklů, než ušetříte na dotazech. Profil svých dat znáte pouze vy.
Nemyslím si, že můžete udržovat takovou tabulku grafů pomocí dotazů CONNECT BY a kaskádových cizích klíčů. Příliš mnoho nepřímé aktivity, příliš těžké na to, aby se to dalo správně. Také není k dispozici materializovaný pohled, protože nemůžeme napsat SQL dotaz, který přepne 1->5
záznam, když odstraníme zdrojový záznam pro ID=4
.
Doporučuji vám, abyste si přečetli článek s názvem Udržování tranzitivního uzavření grafů v SQL od Dong, Libkin, Su a Wong. To obsahuje spoustu teorie a některé drsné (Oracle) SQL, ale dá vám to základy k sestavení PL/SQL, které potřebujete k udržování tabulky grafů.
"můžete rozšířit část o tom, že je příliš obtížné ji udržovat pomocí CONNECT BY/kaskádových FK? Pokud řídím přístup k tabulce a všechna vkládání/aktualizace/mazání probíhají prostřednictvím uložených procedur, jaké existují druhy scénářů, kde by se to zhroutilo?"
Zvažte záznam 1->5
což je zkrat 1->2->4->5
. Co se nyní stane, když, jak jsem řekl dříve, smažeme zdrojový záznam pro ID=4
? Kaskádové cizí klíče by mohly smazat položky pro 2->4
a 4->5
. Ale zbývá 1->5
(a skutečně 2->5
) v tabulce grafu, ačkoli již nepředstavují platnou hranu v grafu .
Co by mohlo fungovat (myslím, že jsem to neudělal), by bylo použít další syntetický klíč ve zdrojové tabulce, jako je tento.
ID | PARENT_ID | NEW_KEY
------+-----------+---------
1 | | AAA
2 | 1 | BBB
3 | 2 | CCC
4 | 2 | DDD
5 | 4 | EEE
Nyní by tabulka grafu vypadala takto:
PARENT_ID | CHILD_ID | NEW_KEY
-----------+----------+---------
1 | 2 | BBB
1 | 3 | CCC
1 | 4 | DDD
1 | 5 | DDD
2 | 3 | CCC
2 | 4 | DDD
2 | 5 | DDD
4 | 5 | DDD
Takže tabulka grafu má cizí klíč odkazující na vztah ve zdrojové tabulce, která ji vygenerovala, spíše než odkazující na ID. Poté smažte záznam pro ID=4
by kaskádové mazání všech záznamů v tabulce grafů, kde NEW_KEY=DDD
.
To by fungovalo, pokud jakékoli dané ID může mít pouze nula nebo jedno rodičovské ID. Ale nebude to fungovat, pokud je to přípustné, aby se to stalo:
ID | PARENT_ID
------+----------
5 | 2
5 | 4
Jinými slovy hrana 1->5
představuje obě 1->2->4->5
a 1->2->5
. Co tedy může fungovat, závisí na složitosti vašich dat.