Så det, du ønsker, er at materialisere de transitive lukninger. Det vil sige, givet denne applikationstabel ...
ID | PARENT_ID
------+----------
1 |
2 | 1
3 | 2
4 | 2
5 | 4
... graftabellen ville se sådan ud:
PARENT_ID | CHILD_ID
-----------+----------
1 | 2
1 | 3
1 | 4
1 | 5
2 | 3
2 | 4
2 | 5
4 | 5
Det er muligt at vedligeholde en tabel som denne i Oracle, selvom du bliver nødt til at rulle dine egne rammer for det. Spørgsmålet er, om det er omkostningerne værd. Hvis kildetabellen er flygtig, kan det koste flere cyklusser at holde grafdataene friske, end du vil spare på forespørgslerne. Kun du kender dine datas profil.
Jeg tror ikke, du kan vedligeholde sådan en graftabel med CONNECT BY-forespørgsler og cascading fremmednøgler. For meget indirekte aktivitet, for svært at få ret. Også en materialiseret visning er ude, fordi vi ikke kan skrive en SQL-forespørgsel, som vil zappe 1->5
optage, når vi sletter kildeposten for ID=4
.
Så hvad jeg foreslår, at du læser et papir kaldet Maintaining Transitive Closure of Graphs in SQL af Dong, Libkin, Su og Wong. Dette indeholder en masse teori og noget knudret (Oracle) SQL, men det vil give dig grundlaget for at bygge den PL/SQL, du skal bruge for at vedligeholde en graftabel.
"kan du uddybe den del om, at det er for svært at vedligeholde med CONNECT BY/cascading FK'er? Hvis jeg kontrollerer adgangen til tabellen og alle indsættelser/opdateringer/sletninger finder sted via lagrede procedurer, hvilken slags scenarier er der, hvor dette ville bryde sammen?"
Overvej posten 1->5
som er en kortslutning af 1->2->4->5
. Hvad sker der nu, hvis vi, som jeg sagde før, sletter kildeposten for ID=4
? Cascading fremmednøgler kunne slette indtastningerne for 2->4
og 4->5
. Men det efterlader 1->5
(og faktisk 2->5
) i graftabellen, selvom de ikke længere repræsenterer en gyldig kant i grafen .
Hvad der kunne virke (jeg tror, jeg har ikke gjort det) ville være at bruge en ekstra syntetisk nøgle i kildetabellen, som denne.
ID | PARENT_ID | NEW_KEY
------+-----------+---------
1 | | AAA
2 | 1 | BBB
3 | 2 | CCC
4 | 2 | DDD
5 | 4 | EEE
Nu ville graftabellen se sådan ud:
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
Så graftabellen har en fremmednøgle, der refererer til relationen i kildetabellen, som genererede den, i stedet for at linke til ID'et. Slet derefter posten for ID=4
ville kaskade sletninger af alle poster i graftabellen hvor NEW_KEY=DDD
.
Dette ville fungere, hvis et givet id kun kan have nul eller ét forældre-id. Men det virker ikke, hvis det er tilladt at dette sker:
ID | PARENT_ID
------+----------
5 | 2
5 | 4
Med andre ord kanten 1->5
repræsenterer både 1->2->4->5
og 1->2->5
. Så hvad der kan virke afhænger af kompleksiteten af dine data.