Więc to, czego chcesz, to zmaterializowanie zamknięć przechodnich. Oznacza to, że biorąc pod uwagę tę tabelę zastosowań ...
ID | PARENT_ID
------+----------
1 |
2 | 1
3 | 2
4 | 2
5 | 4
... tabela wykresów wyglądałaby tak:
PARENT_ID | CHILD_ID
-----------+----------
1 | 2
1 | 3
1 | 4
1 | 5
2 | 3
2 | 4
2 | 5
4 | 5
Możliwe jest utrzymanie takiej tabeli w Oracle, chociaż będziesz potrzebować do tego własnego frameworka. Pytanie brzmi, czy jest to warte kosztów ogólnych. Jeśli tabela źródłowa jest niestabilna, utrzymanie aktualności danych wykresu może kosztować więcej cykli, niż zaoszczędzisz na zapytaniach. Tylko Ty znasz profil swoich danych.
Nie sądzę, aby można było utrzymać taką tabelę wykresów z zapytaniami CONNECT BY i kaskadowymi kluczami obcymi. Zbyt dużo działań pośrednich, zbyt trudne do wykonania. Również widok zmaterializowany jest niedostępny, ponieważ nie możemy napisać zapytania SQL, które odrzuci 1->5
rekord, gdy usuniemy rekord źródłowy dla ID=4
.
Więc proponuję przeczytać artykuł zatytułowany Maintaining Transitive Closure of Graphs in SQL autorstwa Donga, Libkina, Su i Wonga. Zawiera dużo teorii i trochę gnarly (Oracle) SQL, ale da ci podstawy do zbudowania PL/SQL potrzebnego do utrzymania tabeli wykresów.
„Czy możesz rozwinąć część dotyczącą tego, że jest zbyt trudna do utrzymania za pomocą CONNECT BY/kaskadowego FK? Jeśli kontroluję dostęp do tabeli i wszystkie wstawiania/aktualizacje/usuwania odbywają się za pomocą procedur zapisanych w magazynie, jakie są rodzaje scenariuszy, w których mogłoby to się zepsuć?”
Rozważ rekord 1->5
co jest zwarciem 1->2->4->5
. A teraz, co się stanie, jeśli, jak powiedziałem wcześniej, usuniemy rekord źródłowy dla ID=4
? Kaskadowe klucze obce mogą usuwać wpisy dla 2->4
i 4->5
. Ale to pozostawia 1->5
(i rzeczywiście 2->5
) w tabeli wykresu, chociaż nie reprezentują już prawidłowej krawędzi wykresu .
To, co mogłoby zadziałać (myślę, że tego nie zrobiłem) to użycie dodatkowego klucza syntetycznego w tabeli źródłowej, tak jak ten.
ID | PARENT_ID | NEW_KEY
------+-----------+---------
1 | | AAA
2 | 1 | BBB
3 | 2 | CCC
4 | 2 | DDD
5 | 4 | EEE
Teraz tabela wykresów wyglądałaby tak:
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 więc tabela wykresu ma klucz obcy odwołujący się do relacji w tabeli źródłowej, która ją wygenerowała, a nie do identyfikatora. Następnie usuwam rekord dla ID=4
spowoduje kaskadowe usuwanie wszystkich rekordów w tabeli wykresów, gdzie NEW_KEY=DDD
.
To zadziała, jeśli dowolny identyfikator może mieć tylko zero lub jeden identyfikator rodzica. Ale to nie zadziała, jeśli jest to dozwolone:
ID | PARENT_ID
------+----------
5 | 2
5 | 4
Innymi słowy krawędź 1->5
reprezentuje oba 1->2->4->5
i 1->2->5
. To, co może działać, zależy od złożoności Twoich danych.