Oracle
 sql >> Database >  >> RDS >> Oracle

Creazione di una tabella/vista appiattita di un insieme di dati definito gerarchicamente

Quindi quello che vuoi è materializzare le chiusure transitive. Cioè, data questa tabella delle applicazioni ...

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

... la tabella del grafico sarebbe simile a questa:

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

È possibile mantenere una tabella come questa in Oracle, anche se sarà necessario eseguire il rollover del proprio framework. La domanda è se ne vale la pena. Se la tabella di origine è volatile, mantenere aggiornati i dati del grafico può costare più cicli di quelli che risparmierai sulle query. Solo tu conosci il profilo dei tuoi dati.

Non credo che tu possa mantenere una tale tabella grafica con query CONNECT BY e chiavi esterne a cascata. Troppa attività indiretta, troppo difficile da ottenere. Anche una vista materializzata è fuori, perché non possiamo scrivere una query SQL che farà lo zapping di 1->5 record quando eliminiamo il record di origine per ID=4 .

Quindi, quello che ti suggerisco di leggere un documento intitolato Maintaining Transitive Closure of Graphs in SQL di Dong, Libkin, Su e Wong. Questo contiene molta teoria e un po 'di SQL nodoso (Oracle), ma ti darà le basi per costruire il PL/SQL di cui hai bisogno per mantenere una tabella grafica.

"puoi approfondire la parte sul fatto che è troppo difficile da mantenere con CONNECT BY/FK a cascata? Se controllo l'accesso alla tabella e tutti gli inserimenti/aggiornamenti/eliminazioni avvengono tramite procedure memorizzate, che tipo di scenari ci sono in cui questo si interromperebbe?"

Considera il record 1->5 che è un cortocircuito di 1->2->4->5 . Ora cosa succede se, come ho detto prima, eliminiamo il record di origine per ID=4 ? Le chiavi esterne a cascata potrebbero eliminare le voci per 2->4 e 4->5 . Ma questo rimane 1->5 (e infatti 2->5 ) nella tabella del grafico sebbene non rappresentino più un bordo valido nel grafico .

Ciò che potrebbe funzionare (penso di non averlo fatto) sarebbe utilizzare una chiave sintetica aggiuntiva nella tabella di origine, come questa.

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

Ora la tabella del grafico sarebbe simile a questa:

 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

Quindi la tabella del grafico ha una chiave esterna che fa riferimento alla relazione nella tabella di origine che l'ha generata, anziché collegarsi all'ID. Quindi eliminando il record per ID=4 elimina a cascata tutti i record nella tabella del grafico dove NEW_KEY=DDD .

Ciò funzionerebbe se un determinato ID può avere solo zero o un ID genitore. Ma non funzionerà se è consentito che ciò accada:

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

In altre parole il bordo 1->5 rappresenta entrambi 1->2->4->5 e 1->2->5 . Quindi, ciò che potrebbe funzionare dipende dalla complessità dei tuoi dati.