Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Erstellen einer vereinfachten Tabelle/Ansicht eines hierarchisch definierten Datensatzes

Was Sie also wollen, ist, die transitiven Abschlüsse zu materialisieren. Das heißt, angesichts dieser Anwendungstabelle ...

 ID   | PARENT_ID
------+----------
    1 | 
    2 |         1
    3 |         2
    4 |         2
    5 |         4

... würde die Grafiktabelle so aussehen:

 PARENT_ID | CHILD_ID
-----------+----------
         1 |        2
         1 |        3
         1 |        4
         1 |        5
         2 |        3
         2 |        4
         2 |        5
         4 |        5

Es ist möglich, eine solche Tabelle in Oracle zu pflegen, obwohl Sie dafür Ihr eigenes Framework erstellen müssen. Die Frage ist, ob sich der Mehraufwand lohnt. Wenn die Quelltabelle flüchtig ist, kann es mehr Zyklen kosten, die Diagrammdaten aktuell zu halten, als Sie bei den Abfragen einsparen. Nur Sie kennen das Profil Ihrer Daten.

Ich glaube nicht, dass Sie eine solche Diagrammtabelle mit CONNECT BY-Abfragen und kaskadierenden Fremdschlüsseln verwalten können. Zu viel indirekte Aktivität, zu schwer, es richtig zu machen. Auch eine materialisierte Ansicht ist out, weil wir keine SQL-Abfrage schreiben können, die 1->5 zappen wird Datensatz, wenn wir den Quelldatensatz für ID=4 löschen .

Ich schlage vor, Sie lesen ein Papier mit dem Titel Maintaining Transitive Closure of Graphs in SQL von Dong, Libkin, Su und Wong. Dies enthält viel Theorie und etwas knorriges (Oracle) SQL, aber es gibt Ihnen die Grundlage, um das PL/SQL zu erstellen, das Sie zum Verwalten einer Diagrammtabelle benötigen.

"Können Sie den Teil erläutern, dass es zu schwierig ist, es mit CONNECT BY/kaskadierenden FKs zu warten? Wenn ich den Zugriff auf die Tabelle kontrolliere und alle Einfügungen/Aktualisierungen/Löschungen über gespeicherte Prozeduren stattfinden, welche Arten von Szenarien gibt es, in denen dies zusammenbrechen würde?"

Betrachten Sie den Datensatz 1->5 was ein Kurzschluss von 1->2->4->5 ist . Was passiert nun, wenn wir, wie ich bereits sagte, den Quelldatensatz für ID=4 löschen ? Kaskadierende Fremdschlüssel könnten die Einträge für 2->4 löschen und 4->5 . Aber damit bleibt 1->5 (und tatsächlich 2->5 ) in der Diagrammtabelle, obwohl sie keine gültige Kante im Diagramm mehr darstellen .

Was funktionieren könnte (ich glaube, ich habe es nicht getan), wäre die Verwendung eines zusätzlichen synthetischen Schlüssels in der Quelltabelle, wie dieser.

 ID   | PARENT_ID | NEW_KEY
------+-----------+---------
    1 |           | AAA
    2 |         1 | BBB
    3 |         2 | CCC
    4 |         2 | DDD
    5 |         4 | EEE

Jetzt würde die Grafiktabelle so aussehen:

 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

Die Diagrammtabelle hat also einen Fremdschlüssel, der auf die Beziehung in der Quelltabelle verweist, die sie generiert hat, anstatt auf die ID zu verlinken. Löschen Sie dann den Datensatz für ID=4 würde Löschvorgänge aller Datensätze in der Diagrammtabelle kaskadieren, wobei NEW_KEY=DDD .

Dies würde funktionieren, wenn eine bestimmte ID nur null oder eine Eltern-ID haben kann. Aber es wird nicht funktionieren, wenn dies zulässig ist:

 ID   | PARENT_ID
------+----------
    5 |         2
    5 |         4

Also die Kante 1->5 steht für 1->2->4->5 und 1->2->5 . Was funktionieren könnte, hängt also von der Komplexität Ihrer Daten ab.