Så vad du vill är att förverkliga de transitiva stängningarna. Det vill säga, givet denna applikationstabell ...
ID | PARENT_ID
------+----------
1 |
2 | 1
3 | 2
4 | 2
5 | 4
... graftabellen skulle se ut så här:
PARENT_ID | CHILD_ID
-----------+----------
1 | 2
1 | 3
1 | 4
1 | 5
2 | 3
2 | 4
2 | 5
4 | 5
Det är möjligt att underhålla en tabell som denna i Oracle, även om du måste rulla ditt eget ramverk för det. Frågan är om det är värt omkostnaderna. Om källtabellen är flyktig kan det kosta fler cykler att hålla grafdata färska än du sparar på frågorna. Bara du känner till din datas profil.
Jag tror inte att du kan upprätthålla en sådan graftabell med CONNECT BY-frågor och överlappande främmande nycklar. För mycket indirekt aktivitet, för svårt att få rätt. En materialiserad vy är också ute, eftersom vi inte kan skriva en SQL-fråga som kommer att zappa 1->5
spela in när vi tar bort källposten för ID=4
.
Så vad jag föreslår att du läser en artikel som heter Maintaining Transitive Closure of Graphs in SQL av Dong, Libkin, Su och Wong. Det här innehåller mycket teori och lite knotiga (Oracle) SQL men det kommer att ge dig grunden för att bygga den PL/SQL du behöver för att upprätthålla en graftabell.
"kan du utvidga delen om att det är för svårt att underhålla med CONNECT BY/cascading FKs? Om jag kontrollerar åtkomst till tabellen och alla infogar/uppdateringar/borttagningar sker via lagrade procedurer, vilka typer av scenarier finns det där detta skulle gå sönder?"
Tänk på posten 1->5
vilket är en kortslutning av 1->2->4->5
. Vad händer nu om vi, som jag sa tidigare, tar bort källposten för ID=4
? Cascading främmande nycklar kan radera posterna för 2->4
och 4->5
. Men det lämnar 1->5
(och faktiskt 2->5
) i graftabellen även om de inte längre representerar en giltig kant i grafen .
Det som skulle kunna fungera (tror jag, jag har inte gjort det) skulle vara att använda en extra syntetisk nyckel i källtabellen, så här.
ID | PARENT_ID | NEW_KEY
------+-----------+---------
1 | | AAA
2 | 1 | BBB
3 | 2 | CCC
4 | 2 | DDD
5 | 4 | EEE
Nu skulle graftabellen se ut så här:
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 främmande nyckel som refererar till relationen i källtabellen som genererade den, snarare än att länka till ID:t. Ta sedan bort posten för ID=4
skulle överlappa raderingar av alla poster i graftabellen där NEW_KEY=DDD
.
Detta skulle fungera om ett givet ID bara kan ha noll eller ett föräldra-ID. Men det fungerar inte om det är tillåtet att detta händer:
ID | PARENT_ID
------+----------
5 | 2
5 | 4
Med andra ord kanten 1->5
representerar både 1->2->4->5
och 1->2->5
. Så vad som kan fungera beror på din datas komplexitet.