Stockage et utilisation d un multi direct acyclique graphe pour PostgreSQL 8.2 Jonathan Winandy Juillet 2008 1
Table des matières 1 Introduction 3 2 Le modèle Nested set 3 2.1 Présentation du modèle.......................................... 3 2.2 Représentation du modèle......................................... 3 2.3 Utilisations du modèle........................................... 3 2.3.1 Récupération d un sous-arbre................................... 5 2.3.2 Trouver toutes les feuilles..................................... 5 2.3.3 Trouver le chemin vers la racine................................. 5 2.3.4 Trouver la profondeur des noeuds................................. 5 2.3.5 Trouver la profondeur des noeuds dans un sous arbre...................... 6 2.3.6 Trouver les fils directs d un noeud................................ 6 3 Annexes 8 Tables des figures................................................ 8 2
1 Introduction Cet article a pour but de documenter l utilisation des direct acyclique graphes en tant que structure hiearchique. De ce fait ce article survole un certain nombre de domaine liée à l informatique : 2 Le modèle Nested set 2.1 Présentation du modèle Le modèle connu généralement comme Nested set, est une façon de gérer la hierarchie (dans les arbres). Le modèle conçoit les arbres sous forme de boîtes imbriquées. Dans cette représenation, chaque enfant est contenu par son père comme on peut voir dans la figure 2.1. root root A B A B C D E C D E F G F G Fig. 2.1 Exemple d arbre dans le modèle classique (Adjacency List Model) et dans le modèle Nested set Ce modèle a un interêt particulier dès lors que l on veut parcourir de manière directe l arbre. C est à dire que dans la première représentation, pour connaître tout les fils de B, D-E-F-G, il faut parcourir de manière récursive tous les noeuds en dessous de B pour récupérer l information. Dans le cas du modèle Nested set, il suffit de prendre tous les éléments de la boite B. La différence est relativement importante puisquecela dimunue l ordre de complexité des algorythmes. 2.2 Représentation du modèle L idée de boite englobante se modèlise en ajoutant aux noeuds deux nouvelles propriètés qui sont la position sur un axe d entier naturel de l extrémité gauche et de l extrémité droite. Comme on le voit sur la figure 2.2, cette numérotation est suffisante pour décrire la structure d un arbre, et de plus est porteuse d un certain nombre d information complémentaires, en particulier sur les sous-arbres. On abandonne alors le classique modèle hierarchique en base de données qui consiste à stocker pour chaque noeud son noeud parent, pour stocker pour chaque noeud la position de sa partie gauche et de sa partie droite. Le calcul de la valeur des node left et node right ce fait en numérotant de gauche à droite les noeuds, comme sur la figure 2.2. Cette nouvelle structure perd donc la clès étrangère node parentid qui est remplacé par les valeurs contenues dans node left et node right. 2.3 Utilisations du modèle Le but ici est de montrer quelques utilisations du modèle dans une base données, ainsi les manières de gérer les différents cas d utilisation qui se présente. Dans les exemples suivants, je considère que le noeud N1 est le noeud E qui a pour node id = 6, node left = 9 et node left = 14 comme dans la figure 2.4. 3
root A B C D E F G 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Fig. 2.2 Numérotation des noeuds dans la méthode du nested set node pk node id fk node parentid node name modification node pk node id fk node parentid node name + node left + node right Fig. 2.3 Modification du type node CREATE TABLE node ( n o d e i d INT PRIMARY KEY, node name VARCHAR( 2 0) NOT NULL, n o d e l e f t INT NOT NULL, n o d e r i g h t INT NOT NULL ) ; INSERT INTO node VALUES ( 1, r o o t, 1, 1 6 ), ( 2, A, 2, 5 ), ( 3, C, 3, 4 ), ( 4, B, 6, 1 5 ), ( 5, D, 7, 8 ), ( 6, E, 9, 1 4 ), ( 7, F, 1 0, 1 1 ), ( 8, G, 1 2, 1 3 ) ; Fig. 2.4 Insertion du modèle et de quelques données test dans une base de données suportant le SQL 4
2.3.1 Récupération d un sous-arbre La récupération du sous-arbre donc le noeud N1 en est racine, ce fait en deux étapes : 1. Récupération des informations 1 sur le noeud N1 qui a pour id = N1id : SELECT INTO N1 FROM node WHERE n o d e i d = N1id ; S p é c i f i q u e 6 ; E ; 9 ; 1 4 PlpgSQL 2. Réquête avec les propriètes de N1 dans la clause W HERE : SELECT FROM node WHERE node. n o d e l e f t > N1. n o d e l e f t AND node. n o d e r i g h t < N1. n o d e r i g h t ; 7 ; F ; 1 0 ; 1 1 8 ; G ; 1 2 ; 1 3 On peut en faire la synthèse en une seule requète 2 : SELECT FROM node WHERE node. n o d e l e f t > (SELECT n o d e l e f t FROM node WHERE n o d e i d = N1id ) AND node. n o d e r i g h t < (SELECT n o d e r i g h t FROM node WHERE n o d e i d = N1id ) ; 7 ; F ; 1 0 ; 1 1 8 ; G ; 1 2 ; 1 3 2.3.2 Trouver toutes les feuilles Les feuilles sont caractèrisable par le fait que node right node left = 1, ce qui donne la requète suivante : SELECT FROM node WHERE node. n o d e r i g h t = node. n o d e l e f t + 1 ; 3 ; C ; 3 ; 4 5 ; D ; 7 ; 8 7 ; F ; 1 0 ; 1 1 8 ; G ; 1 2 ; 1 3 2.3.3 Trouver le chemin vers la racine Avec le modèle nested set, on peut retrouver un chemin vers la racine sans pour avoir à faire des multiples jointures : SELECT FROM node WHERE N1. n o d e l e f t BETWEEN node. n o d e l e f t AND node. n o d e r i g h t 1 ; r o o t ; 1 ; 1 6 4 ; B ; 6 ; 1 5 6 ; E ; 9 ; 1 4 2.3.4 Trouver la profondeur des noeuds En utilisant le cas d utilisation précedant, trouver le chemin vers la racine, et en utilisant la fonction d agrégat count, on est à même de trouver la profondeur des noeuds : 1 J utilise ici un syntaxe qui est spécifique à PlPgSQL, il serait adéquat de l adaper au language de programmation qui intéroge la base de données, ou d utiliser une requète imbriquée. 2 En suposant que la base de données que vous utilisez supporte les requètes imbriquèes, PostgreSQL le fait. 5
SELECT node. node id, node. node name, (COUNT( p a r e n t. n o d e i d ) 1) AS node depth FROM node, node AS p a r e n t WHERE node. n o d e l e f t BETWEEN p a r e n t. n o d e l e f t AND p a r e n t. n o d e r i g h t GROUP BY node. node id, node. n o d e l e f t, node. node name 1 ; r o o t ; 0 2 ; A ; 1 3 ; C ; 2 4 ; B ; 1 5 ; D ; 2 6 ; E ; 2 7 ; F ; 3 8 ; G ; 3 2.3.5 Trouver la profondeur des noeuds dans un sous arbre La méthode consiste à reprendre la requète précédente, et à limiter les parents au sous-arbre à l aide d un réquète imbriqué : SELECT node. node id, node. node name, COUNT( p a r e n t. n o d e i d ) AS node depth FROM node, (SELECT FROM node WHERE node. n o d e l e f t > B. n o d e l e f t AND node. n o d e r i g h t < B. n o d e r i g h t ) AS p a r e n t WHERE node. n o d e l e f t BETWEEN p a r e n t. n o d e l e f t AND p a r e n t. n o d e r i g h t GROUP BY node. node id, node. n o d e l e f t, node. node name Sous a r b r e de B 5 ; D ; 1 6 ; E ; 1 7 ; F ; 2 8 ; G ; 2 Une variante où on inclut la racine dans le résultat SELECT node. node id, node. node name, COUNT( p a r e n t. n o d e i d ) 1 AS node depth FROM node, (SELECT FROM node WHERE node. n o d e l e f t >= B. n o d e l e f t AND node. n o d e r i g h t <= B. n o d e r i g h t ) AS p a r e n t WHERE node. n o d e l e f t BETWEEN p a r e n t. n o d e l e f t AND p a r e n t. n o d e r i g h t GROUP BY node. node id, node. n o d e l e f t, node. node name Sous a r b r e de B 4 ; B ; 0 5 ; D ; 1 6 ; E ; 1 7 ; F ; 2 8 ; G ; 2 2.3.6 Trouver les fils directs d un noeud Le modèle du nested set n est pas adapté à ce genre de requète qui ne sont pas directe comme pour le Adjacency List Model. SELECT node. node id, node. node name, COUNT( p a r e n t. n o d e i d ) 1 AS node depth FROM node, (SELECT FROM node WHERE 6
node. n o d e l e f t >= B. n o d e l e f t AND node. n o d e r i g h t <= B. n o d e r i g h t ) AS p a r e n t WHERE node. n o d e l e f t BETWEEN p a r e n t. n o d e l e f t AND p a r e n t. n o d e r i g h t GROUP BY node. node id, node. n o d e l e f t, node. node name HAVING COUNT( p a r e n t. n o d e i d ) < 3 B e t f i l s d i r e c t s de B 4 ; B ; 0 5 ; D ; 1 6 ; E ; 1 7
3 Annexes Table des figures 2.1 Exemple d arbre dans le modèle classique (Adjacency List Model) et dans le modèle Nested set.. 3 2.2 Numérotation des noeuds dans la méthode du nested set........................ 4 2.3 Modification du type node........................................ 4 2.4 Insertion du modèle et de quelques données test dans une base de données suportant le SQL..... 4 8