Oracle
 sql >> Base de données >  >> RDS >> Oracle

Création d'une table/vue aplatie d'un ensemble de données défini hiérarchiquement

Donc, ce que vous voulez, c'est matérialiser les fermetures transitives. Autrement dit, étant donné cette table d'application ...

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

... le tableau graphique ressemblerait à ceci :

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

Il est possible de maintenir une table comme celle-ci dans Oracle, bien que vous deviez créer votre propre framework pour cela. La question est de savoir si cela vaut le surcoût. Si la table source est volatile, la mise à jour des données du graphique peut coûter plus de cycles que vous n'économiserez sur les requêtes. Vous seul connaissez le profil de vos données.

Je ne pense pas que vous puissiez maintenir une telle table graphique avec des requêtes CONNECT BY et des clés étrangères en cascade. Trop d'activité indirecte, trop difficile à faire correctement. De plus, une vue matérialisée est sortie, car nous ne pouvons pas écrire une requête SQL qui zappera le 1->5 record lorsque nous supprimons l'enregistrement source pour ID=4 .

Je vous suggère donc de lire un article intitulé Maintenir la fermeture transitive des graphes en SQL par Dong, Libkin, Su et Wong. Cela contient beaucoup de théorie et du SQL noueux (Oracle), mais cela vous donnera les bases pour construire le PL/SQL dont vous avez besoin pour maintenir une table de graphes.

"pouvez-vous développer la partie sur le fait qu'il est trop difficile à maintenir avec CONNECT BY/cascading FKs ? Si je contrôle l'accès à la table et que toutes les insertions/mises à jour/suppressions ont lieu via des procédures stockées, quels types de scénarios y a-t-il où cela échouerait ?"

Considérez l'enregistrement 1->5 qui est un court-circuit de 1->2->4->5 . Maintenant, que se passe-t-il si, comme je l'ai déjà dit, nous supprimons l'enregistrement source pour ID=4 ? Les clés étrangères en cascade pourraient supprimer les entrées pour 2->4 et 4->5 . Mais cela laisse 1->5 (et en effet 2->5 ) dans le tableau graphique bien qu'ils ne représentent plus une arête valide dans le graphique .

Ce qui pourrait fonctionner (je pense que je ne l'ai pas fait) serait d'utiliser une clé synthétique supplémentaire dans la table source, comme celle-ci.

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

Maintenant, le tableau graphique ressemblerait à ceci :

 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

Ainsi, la table graphique a une clé étrangère référençant la relation dans la table source qui l'a générée, plutôt que de la lier à l'ID. Puis suppression de l'enregistrement pour ID=4 supprimerait en cascade tous les enregistrements du tableau graphique où NEW_KEY=DDD .

Cela fonctionnerait si un identifiant donné ne pouvait avoir que zéro ou un identifiant parent. Mais cela ne fonctionnera pas s'il est permis que cela se produise :

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

Autrement dit l'arête 1->5 représente à la fois 1->2->4->5 et 1->2->5 . Ainsi, ce qui pourrait fonctionner dépend de la complexité de vos données.