LEGOND AUBRY Fabrice 04/04/2001 Fiche de lecture Titre du document : « STORED : Semi-structured TO RElational Data» Type du document : Article Auteurs : Alien Deutsch, Mary Fernandez, Dan Suciu Cadre de la publication : ? Date de la publication : 2000 Nombre de page de la publication : 12 pages Plan du rapport Introduction....................................................................................................................................................2 L’architecture générale de STORED .............................................................................................................2 Génération des filtres de conversions XML vers SQL ..................................................................................3 CREATION DES TABLES « NOYAUX » .....................................................................................................4 Etape 1 : Détermination de préfixes de chemin importants .......................................................4 Etape 2 – Déterminations des liens entre chemins .....................................................................4 Etape 3 : Agrégations des préfixes de chemin ............................................................................5 Etape 4 : Sélection des attributs obligatoires .............................................................................5 Etape 5 : Génération des requêtes en langage STORED ...........................................................5 Le résultat ...................................................................................................................................5 CREATIONS DES TABLES DE SURCHARGE ...............................................................................................6 Etape 1 : Indexation des attributs ...............................................................................................6 Etape 2 : Génération des requêtes de surcharge ........................................................................6 Le résultat ...................................................................................................................................7 Requête de M.A.J. et d’extraction .................................................................................................................7 Etape 1 : Construction des règles d’inversion............................................................................7 Etapes 2-3 : Décomposition en sous-requêtes et optimisation algébrique .................................8 Etapes 4 : Construction et exécution des sous-requêtes .............................................................8 Les mises à jour (« query updates ») ..........................................................................................8 Conclusion .....................................................................................................................................................8 Page 1 sur 9 LEGOND AUBRY Fabrice 04/04/2001 Introduction Comme il a déjà été dit, les données semi-structurées sont partout. Depuis le développement de l’XML, la présence de ce type de données c'est encore accentué et démocratisé. Le XML est cependant un langage complexe, verbeux et descriptif. Il n'est en aucun cas prescriptif. Cela lui offre une grande puissance syntaxique, mais le rend souvent irrégulier (dans le sens où les données ne sont pas forcées de suivrent strictement le schéma défini) et donc difficile à stocker et manipuler. Le XML est souvent vu comme un graphe orienté potentiellement cyclique. Différentes approches ont été étudiées pour traiter ces données. Elles ont donné lieu au développement de différents programmes comme Lorel, Tsimmis ou Strudel. Cependant, ils ont tous une architecture propriétaire qui leur donne certes de nombreux avantages en terme de performance et de flexibilité mais qui a une contrepartie : Ces "approches" sont souvent coûteuses en espace et elles n'utilisent pas les SGBDR classiques - et ne peuvent donc pas tirer profit de l’expérience que les programmeurs ont acquis dans ce domaine. Dans mon exposé, je me suis surtout attaché à décrire, de façon sommaire mais claire, les étapes et procédés mis en place par les auteurs pour aboutir à la solution proposée. Dans ce document, je m’attacherai plutôt à la partie algorithmique de la solution. L’architecture générale de STORED Le principal but de STORED est donc de gérer la transcription XML / SQL. Cette conversion doit être optimiser de manière à minimiser l’espace disque occupé par la base relationnelle tout en conservant la totalité des données. Il a été démontré que les données semi-structurées peuvent être stockées comme des relations ternaires et unaire : Les tuples ternaire [origine, attribut, destination] sont mis dans une table g.edges(x,l,y) Les tuples unaires [oid des objets racines] sont mis dans une table g.roots(x). STORED utilise un algorithme puissant pour générer les tables relationnelles à partir des sources XML proposés par l’utilisateur. Cette conversion ce fait en deux phases bien distinctes : la première génère le noyau des éléments réguliers. Par régulier, les auteurs signifient que l’élément suit les règles respectées par la majorité d’entre eux. La seconde phase, elle, permet d’ajouter les éléments exclus -hors normes- lors de la première phase, dans des tables spécifiques appelées tables de surcharges (overflow). A la fin de la conversion, les algorithmes de conversions : fourniront les filtres de conversion XML vers SQL créeront des tables relationnelles permettant de stocker les valeurs des attributs créeront des tables relationnelles permettant de stockés les liens (arcs) et par conséquent la structure des données. Page 2 sur 9 LEGOND AUBRY Fabrice 04/04/2001 Tables principales Tables des arcs Source XML Tables de surcharges Tables des objets racines En résumé, les contributions que se propose d’apporter STORED sont : 1. Un langage déclaratif permettant de décrire les différents types de requêtes : création des tables principales, créations des tables de surcharges, extraction et manipulation de données 2. Un algorithme de génération des tables noyaux 3. Un algorithme de génération des tables de surcharges 4. Un algorithme pour les M.A.J. et les interrogations de données Ceci représente donc une solution complète pour la gestion des données semi-structurées avec des outils de base de données existant, connu et stables. Les objectifs sont : de maintenir des performances optimales, l’utilisation de STORED doit être sans perte d’information, l’utilisation doit être la plus aisée possible, minimiser l’occupation disque, minimiser la fragmentation de la base de données et surtout respecter les contraintes imposées par le modèle relationnel. Cependant, ces objectifs limitent aussi les possibilités de la solution. Par exemple, STORED ne permet pas d’utiliser les « regular-path » (car cela implique la prise en compte de la possibilité de récursivité infinie difficile à gérer avec une SGBDR), le langage est moins puissant que les autres (limitations sur les jointures) Génération des filtres de conversions XML vers SQL La génération des tables est basée sur un problème d’optimisation. On cherche à minimiser une fonction de coût o(M). M étant un noyau généré à partir d’une source de données D. On a o(M) telle que o( M ) c ( M ) d ( M ) avec k d ( M ) f i d (QiM ) i 1 Page 3 sur 9 LEGOND AUBRY Fabrice 04/04/2001 c(M) est le coût en terme d’espace de la solution trouvé et d(M) le coût de terme de temps d’exécution des requêtes pré-définies (Qi) auxquelles on a attribué un poids de pondération (fi). On tient compte ainsi au maximum des conditions initiales du système et de son cadre d’utilisation. Pour compléter tout cela, les auteurs ont spécifié des paramètres de contraintes stricts sur le noyau : i. K Le nombre maximum de tables ii. A Le nombre maximum d’attribut par table iii. S La taille disque maximum iv. C Paramètre de seuil pour différencier grands et petits ensembles v. Supp Limite basse pour le nombre d’objets qui permet à l’algorithme de déterminer un chemin comme important ou non. Voir les paragraphes suivants. Comme ce problème est NP-complet, les auteurs ont préféré utiliser la théorie heuristique pour le simplifier et l’alléger. Création des tables « noyaux » L’algorithme est le suivant : On suppose une source D de données structurées en XML. Soit o1,o2, …,on l’ensemble des objets atteignable par le chemin de préfixe F. On définit le support comme le nombre d’objets ok (défini précédemment) qui contiennent l’information B. La détermination du « meilleur » cœur se fait en cinq étapes. Etape 1 : Détermination de préfixes de chemin importants Elle consiste à relever tous les préfixes F tels que le support (avec B quelconque -*-) est supérieur au paramètre Supp. Cette liste de préfixes intéressants seront des objets racines. Chaque entrée de cette liste est développée récursivement en arbre -dont il est racine-. La condition d’arrêt sera comme pour la racine que le support du sous-arbre (sous-préfixe) soit inférieur à Supp. Ex : avec Supp = 2000 TaxPayer (Support=5000) Taxpayer.sexe (4000) … Taxpayer.address (3000) Taxpayer.address.zip (3000) … Taxpayer.address.gate_entry_code (20) arrêt Taxpayer.pet (200) arrêt Etape 2 – Déterminations des liens entre chemins C’est l’étape du « Data-Mining » basé sur une modification d’une solution proposée par Wang et Li. On utilise les données et les requêtes d’interrogations prédéfinies. On définit les liens entre les arbres et entre les sous-arbres. Page 4 sur 9 LEGOND AUBRY Fabrice 04/04/2001 Etape 3 : Agrégations des préfixes de chemin Dans cette étape, on crée les liens du noyau de manière à minimiser les recouvrements et les arbres doublons. En cas de conflit entre deux préfixes de chemin, on prend celui de plus grand support. Cette étape est arrêter lorsque l’on ne peut plus faire d’agrégation. Etape 4 : Sélection des attributs obligatoires Pour chaque arbre, on détermine les attributs requis en fonction des paramètres K et A.On créer les tables relationnelles à la fin de cette étape. Etape 5 : Génération des requêtes en langage STORED On génère alors les requête en langage STORED pour répartir les données provenant d’une XML dans les différentes tables XML créées. Le résultat En résumé, on a : ALGORITHM: Automatic Storage Generation INPUT: K, A, S, C, Supp, and query mix Q OUTPUT: Set of relational STORED mappings METHOD: Step 1: Find all minimal prefixes with data support >= Supp Step 2: - Run the WL data mining algorithm with the changes in the text. - Let K' = number of maximally contained patterns found Step 3: Select K0 (<= K) patterns out of the K' Step 4: For each of the K0 patterns, select the set of ``required'' attributes Step 5: For each of the K0 patterns with required attributes, generate one or more STORED relational queries. Les sur-définitions sont possibles et même courante car les conditions ne sont pas toujours exclusives. Ainsi une donnée peut parfois répondre à deux tables dans ce cas, il sera stocké dans la table choisie par l’algorithme. Ex : M4a = FROM Audit.taxpayer : $X { name : $N, addr : $P, OPT{audited : $A}, OPT{taxamount : $T} } WHERE typeOf($P, "string") STORE Taxpr4a($X, $N, $P, $A, $T) Les requêtes de stockage contiennent souvent des closes OPT qui désignent des paramètres optionnels (qui peuvent être nuls). STORE désigne la table relationnelle dans laquelle les données seront stockées. Lorsqu’il existe des attributs multiples dans une source XML, on a 2 cas : Petits ensembles (de cardinalité < C) : création de T attributs dans la table si possible (paramètre A) Grands ensembles (de cardinalité C) : création d’une table relationnelle séparée. Page 5 sur 9 LEGOND AUBRY Fabrice 04/04/2001 Créations des tables de surcharge Etape 1 : Indexation des attributs On indexe tous les attributs. Pour chaque attribut, on utilise la fonction high(attribut) qui est le nombre maximum d’occurrences dans un tuple XML. Ex : S1 = Audit[1] : { taxpayer[0,*] : { address[1,2] … } } Si sur l’ensemble de la source XML, on trouve au maximum deux adresses par « taxpayer », high(address)=2. A partir de tous les attributs contenus dans la source D, on crée les arbres canoniques des attributs (couvrant l’ensemble des possibilités de la source). Par exemple : S1=Audit[1] : { taxpayer[0,*] : { name[1], address[1,2], taxreturn[0,*]: { year[1], amount[1], extension[0,1] } } } Etape 2 : Génération des requêtes de surcharge On détermine si le noyau est capable ou non de stocker les données produites par la source (à partir des arbres canoniques). Si ce n’est pas le cas, on génère une requête de surcharge permettant de compléter le noyau pour y stocker les données « hors-normes ». Ce qui donne dans l’exemple précédent : O1 = FROM Audit.taxpayer:$X { name:$N, address:$A, $L:_} WHERE $L = address OVERFLOW G1($L) O2 = FROM Audit.taxpayer:$X { name:$N, address:$A, taxreturn:$T, taxreturn: { year:$Y, amount:$A, $L:_ }} WHERE $L = extension OVERFLOW G2($L) Page 6 sur 9 LEGOND AUBRY Fabrice 04/04/2001 Le résultat Encore une fois : ALGORITHM Automatic Overflow Generation INPUT Relational mapping M, schema S OUTPUT Overflow mapping O METHOD Step 1: for each attribute a in S construct set of databases Da Step 2: for each DDa compute M on D if a is not STORED by M then generate overflow mapping Requête de M.A.J. et d’extraction On suppose pour cette partie que la création est terminée. On peut alors modifier, interroger ou faire des calculs sur les données. Les jointures ne sont possibles que dans la close WHERE. Etape 1 : Construction des règles d’inversion A partir des règles de conversions XML / SQL, on engendre les règles « d’inversion ». Ces fonctions sont masquées à l’utilisateur. A partir des attributs passés dans la requête, le moteur détermine quelles tables SQL sont touchées et, par conséquent, utilisées plus tard – à l’étape 2. On construit, à ce moment, une base canonique en fusionnant tous les objets symboliques. Chaque close CONSTRUCT fournit un arbre –dans notre exemple c’est S_audit – dont les branches (nodes) sont générées par des fonctions de Skolem. Ces fonctions (S_name_1, S_addr_1, S_taxpayer, S_taxamount_1, S_street_1, S_city_1) sont elles-mêmes liées aux attributs. Page 7 sur 9 LEGOND AUBRY Fabrice 04/04/2001 Règles d’inversions produites Règles définies Ia0 = FROM Taxpayer($X, $FN, $LN, $S, $C, $T) CONSTRUCT Audit : S_Audit() { taxpayer: S_taxpayer($X) { name : S_name_1($X) {firstname : S_firstname_1($X), $FN, lastname : S_lastname_1($X) $LN}, addr : S_addr_1($X) {street : S_street_1($X) $S, city : S_city_1($X) $C} } } Ma = FROM Audit.taxpayer: $X { name[1] : {firstname[1] : $FN, lastname[1] : $LN}, addr[1] : {street[1] : $S, city[1] : $C}, OPT{taxamount[1] : $T} } STORE Taxpayer($X, $FN, $LN, $S, $C, $T) Mb = FROM Audit.taxpayer: $X { addr[1] : {street[1] : $S, city[1] : $C, $L : _}} OVERFLOW G1($L) Ia1 = FROM Taxpayer($X, $FN, $LN, $S, $C, $T) WHERE $T != null CONSTRUCT Audit : S_Audit() { taxpayer: S_taxpayer($X) { taxamount : S_taxamount_1($X) $T } Mc = FROM Audit.taxpayer: $X { name[1] : $N, OPT{taxamount[1] : $T}, $L : _ } OVERFLOW G2($L) Q = SELECT $N FROM Audit.taxpayer:$X { name : $N, taxamount:$T, w4form.income:$I, address.*:$A} WHERE $T < 0.1 * $I, $A = "Philadelphia" Ib = FROM G1.roots($X), G1.edges($X,$L,$Y) CONSTRUCT Audit : S_Audit() { taxpayer: S_taxpayer($X) {addr : S_addr_1($X) {$L : $Y}} } Ic = FROM G2.roots($X), G2.edges($X, $K, $Z) WHERE $K != taxamount CONSTRUCT Audit : S_Audit() { taxpayer: S_taxpayer($X) {$K : $Z} } Etapes 2-3 : Décomposition en sous-requêtes et optimisation algébrique Dans cette étape, on compose l’ensemble des combinaisons possibles de nodes (des branches) atteintes par la requête. Pour chaque tuple, on cherche, dans les règles d’inversion, la couverture minimale permettant de répondre à la requête. Etapes 4 : Construction et exécution des sous-requêtes On génère les requêtes SQL standard qui seront alors exécuter et on transmettra le résultat à l’utilisateur. Les mises à jour (« query updates ») On transforme la requête avec les étapes 1 à 3 précédentes. On se retrouve alors avec un ensemble (c’est souvent un singleton) de sous-requête SQL qui peuvent, chacune, mettre à jour la base de façon cohérente. Pour éviter les doublons, on n’en exécute qu’une seule. On choisit alors celle qui implique le moins de modifications possible de la base de données. Conclusion L’article manque singulièrement de précision sur les étapes de chaque type de requêtes. Il reste trop souvent généraliste. Il faudrait, à mon avis, un complément d’information et quelques tests supplémentaires pour valider l’utilisation de cette solution pour des grosses applications. Page 8 sur 9 LEGOND AUBRY Fabrice 04/04/2001 L’aspect performance est un peu oublié. Les évaluations de coût dans l’article sont un peu légère et parfois mais bizarre (on part d’une source XML de 95Mo pour générer une base de 1Mo). Il faudrait mettre la main sur un article plus complet pour obtenir des informations plus viables. Je n’ai donc pas aborder ce points des ce petit rapport. Cependant, ce que je peux dire, c’est que l’exemple pris dans l’article me semble plutôt petit par rapport aux tailles des bases de données actuelles (souvent quelques Go). De plus, je ne crois pas personnellement que cette solution soit très efficace en terme de vitesse pure. En effet, elle oblige à la création, suppression, modification de –nombreuses- tables et non de tuples. En générale, les créateurs de moteurs de BD relationnelles optimisent la manipulation des tuples et pas celle des tables qui sont sensées être effectuées seulement au moment de la création de la base. Or STORED oblige à de fréquentes réorganisations des tables. Il m’est impossible de savoir si cela implique un surcoût important ou non mais je pense qu’il doit l’être. Page 9 sur 9