MIND : algorithme par niveaux de découverte des ... - Semantic Scholar

d'autres) d'un cadre théorique pour les algorithmes par niveaux défini dans .... 3 La figure 1 est un graphe représentant une partie des DI candidates dans notre.
99KB taille 13 téléchargements 163 vues
MIND : algorithme par niveaux de découverte des dépendances d'inclusion Fabien De Marchi1, Marlène Rivon2, Stéphane Lopes1, Jean-Marc Petit1 1

LIMOS, FRE CNRS 2239, Université Clermont-Ferrand II 24 avenue des Landais, 63 177 Aubière cedex, France

E-mail: {demarchi,slopes,jmpetit}@libd2.univ-bpclermont.fr

2

Quantix S.A. 67 bd Côte Blatin, 63 000 Clermont-Ferrand E-mail : [email protected]

Résumé Les dépendances d'inclusion, avec les dépendances fonctionnelles, sont les dépendances les plus utilisées en pratique. Elles généralisent respectivement les notions de clé étrangère et de clé. Leur utilité est importante chaque fois que la sémantique des données est nécessaire. Par exemple, ces connaissances sont utiles en conception, en maintenance, ou lors de la construction d'un entrepôt de données à partir des bases de production. Dans cet article, nous proposons un algorithme par niveaux pour la découverte des dépendances d'inclusion satisfaites dans une base de données. Nous utilisons un cadre de travail connu en y apportant les améliorations suivantes : un algorithme original de génération des DI candidates de niveau i+1 à partir des DI de niveau i, une méthode de génération cohérente des DI candidates de niveau 1, une implémentation des algorithmes proposés et des expérimentations sur une base de données opérationnelle. Malgré la complexité inhérente du problème abordé, les évaluations de performance montrent la faisabilité de notre approche.

Mots clés découverte de connaissances dans les bases de données, dépendances d'inclusion, réglage des bases de données, analyse de performances.

Abstract Inclusion dependencies together with functional dependencies form the most fundamental data dependencies used in practice. They are respectively the generalization of foreign keys and keys. Their utility is important for all applications in which data semantic is required: For example, during DB design or maintenance of existing databases, or to build a data warehouse from production databases. In this paper we propose a levelwise algorithm to discover inclusion dependencies (INDs) holding in a database. We use an existing framework, in which we have made the following contributions: an original algorithm to generate candidates IND at the level i+1 from satisfied INDs at level i, a coherent method to generate candidate INDs for level 1, an implementation of the proposed algorithm and experimental results on a real-life database. Despite the inherent complexity of this problem, performance evaluations show the feasibility of our proposal.

Keywords Knowledge discovery in databases , inclusion dependencies, database tuning, performance analysis.

1 Introduction Les dépendances d'inclusion (DI) constituent l'une des plus importantes sortes de contraintes d'intégrité dans les bases de données relationnelles [DATE81,CASA84,PICH90]. Elles représentent une part importante de la sémantique des bases de données, et sont reconnues comme un concept clé dans différentes applications. Parmi les plus importantes citons la conception de bases de données relationnelles [CASA84,MANN86a,CASA88,LEVE00], l'optimisation sémantique de requêtes [PAUL94,QIAN96,GRYZ98,CHEN99,POPA00], la rétroconception des bases de données [CASA83,MARK90,PETI96,COMY99], ou encore la maintenance des vues dans les entrepôts de données [QUAS96,LAUR99]. Alors que tout récemment des travaux ont été réalisés pour découvrir les dépendances fonctionnelles satisfaites dans une relation [HUHT99,LOPE00,NOVE01], la découverte des DI dans une base de données n'a pas (encore !) suscité beaucoup d'intérêts. Nous identifions deux principaux facteurs à cela : (1) Le problème est difficile de part le nombre potentiel de candidats qu'il est possible de former (cf. [CASA84,KANT92] pour des résultats de complexité) (2) Le manque de popularité des DI ; pour illustrer ce propos, il est intéressant de faire le parallèle avec les DF : les DF sont étudiées dès que l'on s'initie aux bases de données puisqu'elles permettent de définir des formes normales (e.g. FNBC ou 3FN) et de définir des clés, concepts très populaires en pratique. Il nous semble que ce qui est bon pour les DF l'est aussi pour les DI : en effet, la connaissance des DI permet de définir d'autres formes normales, comme la IDNF, qui sont justifiées ou définies dans [CASA84,MANN86b,LING92,MANN94,LEVE99,LEVE00]. Cette forme normale a les mêmes ambitions que celles issues des DF : éviter les anomalies de mise à jour afin d'assurer la cohérence et l'intégrité des données. De même, la définition des clés étrangères est aussi directement liée à la connaissance des DI, puisqu'une clé étrangère n'est rien d'autre que la partie gauche d'une DI dont la partie droite est une clé. En outre, dans de nombreuses bases de données existantes, les DI ne sont pas connues. En effet, les anciennes versions de nombreux SGBD (e.g. Oracle V6) ne supportaient pas la définition des clés étrangères. En conséquence, même si ces bases de données ont été migrées sur une version (e.g. Oracle V7 ou V8) qui supporte ce mécanisme, il y a très peu de chances que lors du changement de version, les analystes aient pris le temps de définir les clés étrangères. Il y a donc un intérêt pratique évident pour la découverte de ce type de connaissance. État de l'art Le problème de découverte des dépendances d'inclusion a été défini dans [KANT92]. La NP-complétude du problème y est démontré, tout en évoquant que des optimisations sont possibles grâce aux propriétés des DI. Une implémentation a été proposée dans [BELL95] mais uniquement pour la découverte des DI d'arité un. Certains accès aux données sont évités en utilisant des propriétés des DI. Une autre approche a été proposée dans [PETI99,LOPE01] afin de découvrir un sous-ensemble des DI satisfaites dans une base de données. L'idée est simple : il suffit de ne considérer comme attributs candidats pour former une DI que les attributs dupliqués, i.e. les attributs sur lesquels les ordres de jointure sont faits dans les programmes d'application. Le problème de la découverte des DI apparaît aussi comme une instance (parmi beaucoup d'autres) d'un cadre théorique pour les algorithmes par niveaux défini dans [MANN97]. Toutefois, aucun détail n'est donné sur une étape clé de ce type d'algorithme, à savoir la génération des DI candidates d'arité i+1 à partir des DI satisfaites d'arité i.

Notons que les algorithmes par niveaux ont été récemment utilisés avec succès pour résoudre différents problèmes comme celui de la découverte des "itemsets fréquents" pour les règles d'associations [AGRA94,BAST00] ou les séries chronologiques [SRIK96,MASS00], des transversaux minimaux d'un hypergraphe [GUNO97] ou encore des dépendances fonctionnelles [HUHT99,NOVE01]. Contribution Nous proposons dans cet article un algorithme par niveaux, appelé Mind (pour Mining IND), découvrant toutes les DI satisfaites par une base de données relationnelle. La principale contribution a été de proposer une génération des candidats d'arité i+1 à partir des DI satisfaites d'arité i. Nous avons également réalisé une implémentation de l'algorithme MIND, afin de pouvoir faire des expérimentations. Malgré la complexité inhérente du problème, l'évaluation des performances montre la faisabilité de notre proposition. Nous proposons ensuite des pistes d'optimisation pour cet algorithme : réduction du nombre d'accès aux données, amélioration de l'accès aux données et utilisation des DF pour inférer des DI satisfaites. Nous montrons en outre comment la même méthode peut être utilisée pour découvrir les DI approximatives, i.e. les DI presque vérifiées par la base de données. Organisation de l'article La section 2 effectue quelques rappels sur les bases de données. Dans la section 3, nous donnons une spécification du problème de la découverte des DI qui justifie une approche par niveaux, puis nous proposons un algorithme pour la résolution de ce problème. Nous présentons dans la section 4 l'implémentation réalisée ainsi que les résultats expérimentaux obtenus sur une base de données réelle. La section 5 évoque différentes techniques possibles d'optimisation de l'algorithme. Dans la section 6, nous mettons en évidence que notre méthode est applicable à la découverte des DI approximatives. Enfin, nous concluons et donnons quelques perspectives de recherche dans la section 7.

2 Préliminaires Voici une brève introduction à certains concepts fondamentaux des bases de données utilisés dans cet article (cf par exemple [MANN94,LEVE99] pour plus de détails). Soit R un ensemble fini d'attributs. Pour chaque attribut A ∈ R, l'ensemble de toutes ses valeurs possibles est appelé domaine de A et noté Dom(A). Un tuple sur R est une application t: R → ×A ∈ RDom(A), où t(A) ∈ Dom(A), ∀A ∈ R. Une relation est un ensemble de tuples. La cardinalité d'un ensemble X est notée |X|. On dit que r est une relation sur R et R est le schéma de relation de r. Si X ⊆ R est un ensemble d'attributs1, et t est un tuple, on note t[X] la restriction de t à X. La projection d'une relation r sur X, notée πX(r), est définie par πX(r) = {t[X] | t ∈ r}. Un schéma de base de données R est un ensemble fini de schémas de relations Ri. Une instance de base de données relationnelle d (ou base de données) sur R correspond à un ensemble de relations ri sur chaque Ri de R. Étant donnée une base de données d sur R, l'ensemble des domaines distincts (int, string, ...) est noté DOM(d). Une séquence d'attributs (par exemple X = { A,B,C } ou simplement ABC) est un ensemble ordonné d'attributs distincts. Étant donnée une séquence X, X[i] représente le ième élément de la séquence. Deux attributs A et B sont dits compatibles si Dom(A) = Dom(B). Deux séquences d'attributs X et Y sont compatibles si |X| = |Y| = m et si pour j=[1,m], Dom(X[j]) = Dom(Y[j]). 1

Les lettres du début de l'alphabet représentent des attributs simples tandis que celles de la fin de l'alphabet dénotent des ensembles d'attributs.

Les dépendances d'inclusion et la notion de satisfaction d'une dépendance d'inclusion dans une base de données sont définies ci-dessous. Une dépendance d'inclusion sur un schéma de base de données R est une expression de la forme Ri[X] ⊆ Rj[Y], où Ri, Rj ∈ R, X ⊆ Ri, Y ⊆ Rj, X et Y compatibles, et ∀A,B ∈ X, A ≠ B. Une DI est dite triviale si elle est de la forme R[X] ⊆ R[X]. L'arité (ou taille) d'une DI est le nombre d'attributs à droite ou à gauche. Soit d une base de données sur un schéma de base de données R, où ri, rj ∈ d sont des relations sur Ri, Rj ∈ R respectivement. Une DI Ri[X] ⊆ Rj[Y] est satisfaite dans d, notée d Ri[X] ⊆ Rj[Y], ssi ∀u ∈ ri, ∃v ∈ rj tel que u[X] = v[Y] (ou de manière équivalente πX(ri) ⊆ πY(rj)). On note dep(d) l’ensemble de toutes les DI satisfaites dans d. Notons qu'une DI est une propriété d'un schéma de base de données, et non d'une base de données. La tâche à laquelle nous nous intéressons ici est la découverte des DI satisfaites par une base de données particulière. Une axiomatisation juste et complète pour les DI a été proposée dans [CASA84]. Elle se compose de trois règles d'inférence : 1. (réflexivité) R[A1,...,An] ⊆ R[A1,...,An]. 2. (projection et permutation) si R[A1,...,An] ⊆ S[B1,...,Bn] alors R[Aσ1,...,Aσm] ⊆ S[Bσ1,...,Bσm] pour chaque séquence σ1,..., σm d'entiers distincts dans {1,...,n}. 3. (transitivité) si R[A1,...,An] ⊆ S[B1,...,Bn] et S[B1,...,Bn] ⊆ T[C1,...,Cn] alors R[A1,...,An] ⊆ T[C1,...,Cn]. Ces trois règles fournissent les propriétés de base sur lequel notre algorithme est conçu. Soit I1 et I2 deux ensembles de DI. On note par I1 I2 le fait que toute base de données vérifiant chaque DI de I1 vérifie également chaque DI de I2. On note I+ l'ensemble défini par : I+={R[X] ⊆ S[Y] | I R[X] ⊆ S[Y]}. I1 est une couverture de I2 si I1+ = I2+.

3 Spécification du problème Le problème qui nous intéresse peut être formulé comme suit : Etant donnée une base de données d sur un schéma de base de données R, trouver une petite couverture des DI Ri[X] ⊆ Rj[Y], Ri, Rj ∈ R, telles que d Ri[X] ⊆ Rj[Y]". Nous proposons dans cette section un cadre de travail basé sur les propriétés des DI en justifiant une approche par niveaux pour réduire l'espace de recherche. Nous donnons ensuite un algorithme basé sur ces considérations. Exemple 1 Une base de données d composée de trois relations (cf. Table 1) nous servira d'exemple tout au long de l'article.

R

S A 1 1 2 1

B X X Y X

C 3 3 4 3

D 11.0 12.0 11.0 13.0

T E 1 2 4 7

F X Y Z W

G 3 4 6 9

H 11.0 12.0 14.0 14.0

I 11.0 12.0 11.0 11.0 13.0

J 11.0 12.0 14.0 9.0 13.0

K 1 2 4 7 9

L X Y Z W R

Table 1 : Exemple Une couverture minimale de dep(d), l'ensemble de toutes les DI satisfaites dans d, est : I = { R[ABC] ⊆ S[EFG], S[EF] ⊆ T[KL],T[I] ⊆ R[D], R[D] ⊆ T[I], T[I] ⊆ T[J], S[H] ⊆ T[J]}.

3.1. Cadre de travail L'espace de recherche Initialement, l'ensemble des DI candidates se compose de toutes les expressions de la forme Ri[X] ⊆ Rj[Y] que l'on peut construire à partir du schéma de la base de données considérée. Toutefois, étant donné un ensemble d'attributs, il est inutile de considérer toutes les combinaisons pour construire les parties gauches, grâce à la deuxième règle d'inférence présentée dans la section 2. Exemple 2 Supposons que l'on connaisse toutes les DI satisfaites ayant pour partie gauche AB, soit sur l'exemple 1 : R[AB] ⊆ S[EF],R[AB] ⊆ T[KL]. On connaîtra alors grâce à la deuxième règle d'inférence des DI (propriété de permutation) toutes les DI satisfaites ayant pour partie gauche BA, par simple permutation des parties droites. Nous sommes alors confrontés au problème du choix d'un ordre pour organiser les attributs des parties gauches. Naturellement, nous avons choisi de garder ces attributs dans l'ordre lexicographique, ce qui a pour principal avantage de pouvoir utiliser une adaptation de la fonction AprioriGen [AGRA94] pour générer les parties gauches et les parties droites. Utilisation des propriétés des DI pour réduire l'espace de recherche Etant donnée une base de données d, soit C notre espace de recherche défini comme suit : C est l'ensemble contenant toutes les DI candidates avec une partie gauche respectant l'ordre lexicographique. Dans cette ensemble, on peut définir une relation α, comme suit [MANN97] : Soient I1 : Ri[X] ⊆ Rj[Y] et I2 : Ri′[X′] ⊆ Rj′[Y′] deux DI candidates. On a I1 α I2 si et seulement si : -

Ri = Ri′ et Rj = Rj′ et

-

X′= < A1,...,Ak > , Y′= < B1,...,Bk > , et il existe un ensemble d'indices i1 < ... < ih ∈ {1,...,k} avec h ≤ k tels que X= < Ai1,...,Aih > , Y= < Bi1,...,Bih >2.

Par exemple, on a (Ri[AC] ⊆ Rj[EG]) α (Ri[ABC] ⊆ Rj[EFG]), alors que (Ri[AC] ⊆ Rj[GE]) ← (Ri[ABC] ⊆ Rj[EFG]). On notera I1  I2 si I1 α I2 et I2 ← I1. A partir du deuxième axiome des DI, on peut alors déduire les propriétés suivantes :

2

Cette définition diffère légèrement de celle donnée dans [MANN97] en imposant un ordre aux indices i1,...,ih ; en effet comme on l'a souligné plus haut, on peut fixer (sans perdre aucune information) l’ordre des attributs à gauche.

Propriété 1 Soient I1 et I2 deux DI candidates telles que I1 α I2 . -

Si d

I2 alors d

I1 et

-

Si d

I1 alors d

I2.

Cette représentation du problème justifie une approche par niveaux pour la découverte des DI. En effet, les DI non satisfaites à un niveau donné vont nous permettre de supprimer de nombreuses DI candidates au niveau suivant. En fait, les DI vérifiées à un niveau sont utilisées pour construire les candidats de niveau suivant. Ainsi, l'espace de recherche va être considérablement réduit pour les niveaux supérieurs à 1. Exemple 3 La figure 1 est un graphe représentant une partie des DI candidates dans notre exemple courant, ordonnées par . ABCD ⊆ EFGH

ABC ⊆ EFG

AB ⊆ EF

ABD ⊆ EFH

ACD⊆ EGH

BCD ⊆ FGH

AC ⊆ EG

AD ⊆ EH

BC ⊆ FG

BD ⊆ FH

A⊆E

B⊆F

C⊆G

D⊆H

CD ⊆ GH

True ∅

False Not to be tested

Figure 1 : Quelques DI candidates ordonnées par  Parmi cet ensemble de 15 candidats, seulement 8 d'entre eux doivent être testés. Nous allons maintenant voir comment supprimer des candidats au niveau 1. Si l'on considère deux attributs Ri[A] et Rj[B], il faut tester à chaque niveau si Ri[A] ⊆ Rj[B] et si Rj[B] ⊆ Ri[A]. En fait, seulement l'une de ces deux dépendances doit être testée, grâce à la propriété suivante : Propriété 2 Soit Ri[X] et Rj[Y] deux séquences d'attributs dans une base de données d. d ⊆ Rj[Y] seulement si |πX(ri)| ≤ |πY(rj)|

Ri[X]

Cette propriété peut être utilisée pour diviser par deux le nombre de candidats de niveau 1, même si en cas d'égalité deux candidats seront générés. Ajoutons enfin qu'il est inutile de tester une DI entre deux attributs de domaines différents. Ainsi, d'autres candidats de niveau 1 pourront être évités.

3.2. Découverte des DI Dans la suite, les notations données dans la table 2 seront utilisées. Ci

Ensemble des DI candidates de taille i.

Ii

Ensemble des DI satisfaites de taille i.

c.lhs Séquence formant la partie gauche de la DI c c.rhs Séquence formant la partie droite de la DI c X.rel Schéma de relation contenant les attributs de la séquence X Table 2 : notations L'algorithme Mind trouve toutes les DI satisfaites dans une base de données prise en entrée3. Suivant le principe général des algorithmes par niveaux [MANN97], celui-ci effectue plusieurs parcours des données. Le premier consiste à tester les DI candidates de taille 1 dans la base. Ensuite, à partir de celles qui sont satisfaites, des DI candidates de taille 2 sont générées, et testées alors par un deuxième parcours de la base. Les DI candidates de niveau 3 sont alors générées. Le processus se poursuit ainsi tant qu'il est encore possible de générer de nouveaux candidats. Algorithme 1 Mind : découverte des DI Entrée : Une base de données d. Sortie : Les DI satisfaites dans d. 1: C1 : = GenCandidateLevel1(d); 2: i : = 1; 3: while Ci ≠ ∅ do 4: Ii : = GenIND(d,Ci); 5: Ci+1 : = GenNext(Ii); 6: i: = i+1; 7: end while ; 8: return ∪j < i Ij ;

Le coût d'un tel algorithme a été étudié de manière approfondie dans [MANN97]. D'une manière générale, il est égal au coût d'un test sur la base (ici le test d'une DI) multiplié par la somme du nombre de DI satisfaites et du nombre des "plus petites DI non satisfaites", relativement à la relation α. Exemple 4 Si l'on considère la figure 1, 8 tests sont nécessaires pour découvrir les 7 DI satisfaites. La DI D ⊆ H a du être testée car toutes les DI qui la précèdent dans le graphe (ici, ∅, considérée comme triviale) sont satisfaites.

En fait, l'algorithme tel qu'il est présenté ne découvre pas les DI de la forme R[AB] ⊆ R[AC] qui ne sont pourtant pas triviales. Cette restriction n'est faite que dans le but d'alléger les notations; pour les prendre en considération, il suffit "d'insérer" les DI triviales (e.g. R[A] ⊆ R[A]), nécessaires à la génération de tels candidats, dans l'algorithme. Bien sûr, les DI triviales ne seraient pas testées sur la base, et supprimées à la fin de l'algorithme.

3

3.2.1. Génération des candidats de niveau 1 Puisqu'il est inutile de tester des DI entre des attributs de domaines différents, une phase d'initialisation groupe les attributs suivant leur domaine. Ainsi, les DI candidates ne sont construites qu'à partir d'attributs de même domaine. Il faut noter que ceci n'est vrai que lors de l'initialisation : on peut tout à fait former une DI de la forme R[AB] ⊆ S[CD] avec dom(A) = dom(C) ≠ dom(B) = dom(D). L'algorithme 2 génère l'ensemble des DI candidates de niveau 1. Algorithme 2 GenCandidateLevel1 : Génération des candidats de niveau 1 Entrée : Une base de données d sur un schéma R. Sortie : C1, ensemble de candidats de niveau 1. 1: C1 : = ∅; 2: for all t ∈ DOM(d) do 3: let Ut = {R.A | R ∈ R, A ∈ R, Dom(A) = t} ; 4: Trier Ut suivant les cardinalités des attributs; 5: for (i := 1 ; i < |Ut| ; i++) do 6: for (j = i + 1 ; j ≤ |Ut| ; j++) do 7: C1:=C1 ∪{Ut[i] ⊆ Ut[j]}; 8: if cardinalité de Ut[i] = cardinalité de Ut[j] then 9: C1:=C1 ∪{Ut[j] ⊆ Ut[i]}; 10: end if 11: end for 12: end for 13: end for 14: return C1

La ligne 2 forme les candidats en prenant leur partie droite et leur partie gauche dans le même domaine. La ligne 4 privilégie un sens suivant la propriété 2. Les lignes 8 et 9 s'assurent que l'on n’oublie pas de candidats dans le cas d'attributs de cardinalité égale. Exemple 5 Dans notre exemple, on distingue trois domaines : int,string,real. on a alors : Uint = {R.A, R.C, S.E, S.G, T.K} qui, une fois trié, est égal à : Uint = < R.A, R.C, S.E, S.G, T.K >. De même, on a : Ustring = < R.B, S.F, T.L > et Ufloat = < R.D, T.I, S.H, T.J >. C1 = { (R.A ⊆ R.C), (R.A ⊆ S.E), (R.A ⊆ S.G), (R.A ⊆ T.K), (R.C ⊆ S.E), (R.C ⊆ S.G), (R.C ⊆ T.K), (S.E ⊆ S.G), (S.E ⊆ T.K), (S.G ⊆ T.K ), (R.B ⊆ S.F), (R.B ⊆ T.L), (S.F ⊆ T.L), (R.D ⊆ T.I), (R.D ⊆ S.H), (R.D ⊆ T.J), (T.I ⊆ S.H), (T.I ⊆ T.J), (S.H ⊆ T.J)}. 3.2.2. Génération du niveau supérieur La génération des DI candidates de niveau i+1 à partir des DI satisfaites au niveau i est une des contributions importantes de ce papier. Elle étend le principe classique de la génération des candidats des algorithmes par niveaux dont l'archétype est AprioriGen [AGRA94] pour la génération des motifs fréquents lors de la découverte des règles d'associations. L'algorithme 3 réalise cette tâche ; il se compose de deux phases principales : une phase de génération et une phase d'élagage, toutes les deux basées sur la propriété 1.

La phase de génération (lignes 1 à 8), fournit toutes les DI candidates générées de la façon suivante : soient I1 = (Ri[XA] ⊆ Rj[YC]) et I2 = Ri[XB] ⊆ Rj[YD] avec |X| = |Y| = i−1 et A < B (l'ordre lexicographique entre les attributs C et D n'a pas d'importance). On aura un candidat de la forme : Ri[XAB] ⊆ Rj[YCD]. Algorithme 3 GenNext : Génération des DI candidates de taille i+1 Entrée : Ii, DI de taille i. Sortie : Ci+1, ensemble des DI candidates de taille i+1. 1: insert into Ci+1 2: select p.lhs.rel"["p.lhs[1], p.lhs[2], ..., p.lhs[i], q.lhs[i]"]" " ⊆ " p.rhs.rel"["p.rhs[1], p.rhs[2], ..., p.rhs[i], q.rhs[i]"]" 3: from Ii p, Ii q 4: where p.lhs.rel = q.lhs.rel and p.rhs.rel = q.rhs.rel 5: and p.lhs[1]=q.lhs[1] and p.rhs[1]=q.rhs[1] 6: and … 7: and p.lhs[i−1]=q.lhs[i−1] and p.rhs[i−1]=q.rhs[i−1] 8: and p.lhs[i] < q.lhs[i] and p.rhs[i] ≠ q.rhs[i] 9: for all c ∈ Ci+1 do 10: for all δ  c et δ de taille i do 11: if δ ∉ Ii then 12: Ci+1=Ci+1 \ {c} 13: end if 14: end for 15: end for

Exemple 6 Pour illustrer la phase de génération (lignes 1 à 8), la table 3 présente les DI satisfaites au niveau 1 classées suivant les relations concernées (cf ligne 4) pour mieux illustrer le déroulement de l'algorithme. Pour chaque ensemble de DI de niveau 1, se trouve à droite l'ensemble de candidats générés pour le niveau 2.

R vers S

R vers T

S vers T T vers S T vers T

I1 R[A] ⊆ S[E] R[B] ⊆ S[F] R[C] ⊆ S[G] R[D] ⊆ S[H]

C2 R[AB] ⊆ S[EF] R[AC] ⊆ S[EG] R[AD] ⊆ S[EH] R[BC] ⊆ S[FG] R[BD] ⊆ S[FH] R[CD] ⊆ S[GH] R[A] ⊆ T[K] R[AB] ⊆ T[KL] R[B] ⊆ T[L] R[AD] ⊆ T[KI] R[D] ⊆ T[I] R[AD] ⊆ T[KJ] R[D] ⊆ T[J] R[BD] ⊆ T[LI] R[BD] ⊆ T[LJ] S[E] ⊆ T[K] S[EF] ⊆ T[KL] S[F] ⊆ T[L] S[EH] ⊆ T[KJ] S[H] ⊆ T[J] S[FH] ⊆ T[LJ] T[I] ⊆ S[H] T[I] ⊆ T[J]

Table 3 : Génération des candidats de niveau 2 à partir des DI satisfaites de niveau 1.

La phase d'élagage (lignes 9 à 14), est nécessaire pour ne garder parmi les DI ainsi formées que celles qui sont effectivement en accord avec la propriété 1. Exemple 7 Pour illustrer la phase d'élagage, supposons que les DI R[AB] ⊆ S[EF] et R[AC] ⊆ S[EG] soient satisfaites au niveau 2. Pour le niveau 3, la première partie de l'algorithme va former la DI candidate suivante : R[ABC] ⊆ S[EFG]. Il s'agira alors de vérifier que R[BC] ⊆ S[FG] est bien une DI satisfaite de niveau 2, et de supprimer la candidate formée si ce n'est pas le cas. 3.2.3. Test de validité des DI candidates A chaque niveau, les candidats doivent être testés sur la base. On peut utiliser des requêtes SQL basées sur la propriété bien connue suivante : soit d une base de données sur un schéma R, où ri, rj ∈ d sont des relations sur Ri, Rj ∈ R respectivement. On a : d Ri[X] ⊆ Rj[Y] ssi |πX(ri)| = |πX(ri) υ (X = Y) πY(rj)|. Sa mise en oeuvre est commode et facile à réaliser sur toutes les bases par le biais par exemple d'ODBC. Cette technique de test est celle utilisée dans les expérimentations de la section 4. L'algorithme 4 détermine toutes les DI satisfaites dans une base de données parmi un ensemble de candidats pris en entrée. Algorithme 4GenIND : Evaluation des DI candidates Entrée : Ci, un ensemble de DI candidates de taille i et d, la base de données. Sortie : Ii, ensemble des DI satisfaites de taille i. 1: for all c ∈ Ci do 2: if d c then 3: Ii:= Ii ∪ {c}; 4: end if 5: end for

4 Expérimentations sur une base de données opérationnelle Grâce à une collaboration en cours avec le Laboratoire d'Oncologie Moléculaire (LOM) de l'Université d'Auvergne (EA 2145, Centre Jean Perrin, Clermont-Ferrand) sur l'application de techniques de fouille de données à la thérapie génétique, nous avons pu effectuer des tests de notre algorithme sur une base de données opérationnelle du LOM. Description du contexte Le LOM est spécialisé dans la fabrication et l'analyse des biopuces. Les biopuces permettent d'analyser l'expression des gènes afin d'identifier ceux qui s'expriment dans un tissu cellulaire particulier, et de comparer les niveaux d'expression de ces gènes dans différentes conditions expérimentales. L'objectif in fine est d'adapter les traitements thérapeutiques en fonction de la génétique des patients. Description de la base de données En amont de la partie fouille de données, une base de données relationnelle a été construite afin de consigner toutes les manipulations permettant de construire les biopuces. Cette base de

données sert à la traçabilité des manipulations effectuées sur des biopuces, depuis la réception des gènes jusqu'à leur hybridation sur des tissus humains. Dans la version actuelle, cette base de données est composée de 16 schémas de relations, en moyenne chaque schéma ayant entre 4 et 5 attributs. La plus grande relation a 10 000 tuples et la plus petite quelques dizaines. Le nombre de types sur cette base de données est de trois : date avec 3 attributs, décimal avec 33 attributs et chaîne de caractères avec 35 attributs. Conditions d'expérimentation L'algorithme est implanté en C++, avec utilisation de la STL (Standard Template Library). Nous avons utilisé Oracle 8, et les accès à la base sont réalisés via ODBC. Nous avons réalisé plusieurs tests sur un Intel Pentium II 350 Mhz, avec 256 MB de mémoire principale, tournant sous Windows NT 4. Résultats d'expérimentation Sans aucun pré-traitement, nous avons exécuté notre algorithme sur cette base de données. Le temps de réponse a été de 6mn dont seulement 7s dû à l'algorithme, le reste du temps étant consacré aux accès aux données. Cela confirme la prédominance des coûts d'entrées/sorties dans ce type d'algorithmes. Les résultats sont décrits dans la table 4. Ces tests ont été réalisés en modifiant le test de validité d'une DI afin de prendre en compte les valeurs nulles. Les résultats sont conformes à ce que l'on pouvait attendre : seulement deux DI d'arité 3 sont valides dans la base, à comparer aux 167 DI valides d'arité 1. Arité 1 2 3

Nombre de candidats Nombre de DI valides 1166 167 200 9 2 2

Table 4 : Résultats expérimentaux quantitatifs Bilan des expérimentations Bien que cette base de données puisse être qualifiée de petite tant par rapport aux nombres de relations, que par rapport à la taille moyenne des relations, il n'en demeure pas moins que ces premiers résultats sont encourageants. Les temps de réponse sont convenables d'autant que la version utilisée pour réaliser les tests n'est sans doute pas optimale (cf. section suivante). De plus, via ODBC, ce que nous avons proposé peut se mettre en œuvre sur n'importe quelle base de données opérationnelle. Ces expérimentations nous ont aussi montré la nécessité de prendre en compte les valeurs NULL4. Nous sommes actuellement en train de réaliser d'autres tests sur des bases de données synthétiques afin d'étudier les cas limites de notre algorithme (par rapport aux nombres d'attributs et aux nombres de tuples).

4

Lors de la première expérimentation où aucune attention n'avait été portée aux valeurs NULL, nous avions obtenu 435 DI d'arité 1, 824 d'arité 2, 802 d'arité 3 et 389 d'arité 4 !

5 Optimisations 5.1. Optimisations avec les cardinalités des projections Dans l'algorithme 1, la cardinalité des projections n'était utilisée que pour l'élagage des candidats de niveau 1, via la propriété 2. Nous allons voir que la connaissance des cardinalités des ensembles d'attributs en général peut améliorer notre algorithme de différentes manières. Premièrement, grâce à cette propriété 2, on peut supprimer une DI candidate R[X] ⊆ S[Y] si |πX(r)| > |πY(s)|. De telles DI candidates d'arité supérieure ou égal à 2 peuvent en effet avoir été générées avec l'algorithme 3. On peut ensuite exploiter le troisième axiome des DI, la transitivité, grâce à la connaissance des cardinalités. En effet, pour ce faire les DI doivent être considérées dans le bon ordre : si d R[X] ⊆ S[Y] et d S[Y] ⊆ T[Z] alors |πX(r)| ≤ |πY(s)| ≤ |πZ(t)|. Par conséquent, si on a des séquences R.X, S.Y, T.Z, elles doivent être triées suivant les valeurs de leur cardinalité pour former les DI candidates. Ainsi, à chaque niveau, on peut considérer un graphe orienté défini comme suit. Les sommets sont les séquences d'attributs qui sont des parties gauches ou des parties droites de DI candidates à ce niveau. Il y a un arc de R[X] vers S[Y] ssi (1) R[X] ⊆ S[Y] est une DI candidate à ce niveau et (2) |πX(r)| ≤ |πY(s)|. Exemple 8 Considérons l'ensemble C2 de DI candidates issu de l'exemple 6. On représente alors cet ensemble de candidats à l'aide du graphe suivant (les cardinalités sont données entre parenthèses).

Figure 2 : Ensemble C2 de l’exemple 6 représenté sous la forme d’un graphe. Chaque arc du graphe ainsi construit représente un candidat pour le niveau courant. Ainsi, l'élagage autorisé par la propriété 2 est effectué. On peut ensuite éviter de tester tous les arcs transitifs en parcourant le graphe en profondeur. En outre, considérons le test de validité des DI que nous avons défini précédemment comparant la cardinalité de la partie gauche d'une DI avec la cardinalité de la jointure entre la partie gauche et la partie droite. Ici, on connaît déjà la cardinalité de la partie gauche de chaque DI. Seule la cardinalité de la jointure reste à être déterminée sur la base.

Remarques : 1. On peut également utiliser la propriété évidente suivante : si Ri[X] ⊆ Rj[Y] est satisfaite et si |πX(ri)| = |πY(rj)|, alors Rj[Y] ⊆ Ri[X] est également satisfaite. 2. Le calcul des cardinalités impliquant des accès à la base, il doit être parfois préférable d'appliquer l'algorithme 1, en particulier lorsque peu de DI transitives sont satisfaites.

5.2. Optimisation avec les dépendances fonctionnelles La connaissance des dépendances fonctionnelles (DF) satisfaites dans la base de données ainsi que des DI de niveau i, peut permettre l'inférence de certaines DI de niveau i+1 sans même accéder à la base, grâce à la règle suivante [MITC83] : Soient les dépendances suivantes satisfaites dans une base de données d : R[XY] ⊆ S[UV], R[XZ] ⊆ S[UW] et U → V. Alors la DI R[XYZ] ⊆ S[UVW] est satisfaite dans d. On voit que cette règle peut aisément s'inscrire dans notre algorithme par niveaux. Néanmoins, on ne peut pas supposer que les DF sont disponibles sur toutes les relations de la base de données, ce qui limite l'intérêt pratique de cette optimisation. Exemple 9 Supposons que l'on connaisse les DI satisfaites de niveau 2 de notre base de données exemple, et en particulier R[AB] ⊆ S[EF], R[AC] ⊆ S[EG] et R[BC] ⊆ S[FG]. La DI candidate R[ABC] ⊆ S[EFG] sera alors générée. Si l'on sait que sur la relation S la DF E → F est satisfaite (ce qui est le cas sur l'exemple), alors ce candidat peut directement être rajouté parmi les DI satisfaites de niveau 3 sans aucun accès à la base.

5.3. Optimisation des accès à la base Les requêtes SQL sont simples à mettre en œuvre mais il ne s'agit probablement pas de la méthode la plus efficace en terme de temps d'exécution, car les jointures sont effectuées dans leur intégralité même dans le cas de DI non satisfaites. Nous montrons deux optimisations possibles pour la phase de test des DI. Par des programmes (e.g. PL/SQL) Afin de tester la validité des DI sur la base, nous avons présenté une méthode basée sur le calcul des cardinalités des projections. Nous avons souligné le principal intérêt de cette méthode, à savoir qu'elle peut se mettre en œuvre au travers de requêtes SQL. Toutefois, dans le cas des DI non satisfaites, l'ensemble de la jointure entre la partie gauche et la partie droite est tout de même réalisée afin d'en calculer la cardinalité. En effectuant le test à l'aide par exemple de programmes PL/SQL, on peut envisager de l'interrompre dès lors qu'une valeur de la partie gauche contredit la DI. Le coût moyen du test des DI devrait ainsi être diminué. Par une approche data-mining Une autre approche pouvant se révéler intéressante serait de précéder la découverte des DI d'une phase de préparation des données, de manière à les représenter sous une forme plus adéquate au traitement de ce problème. L'idée est de ne garder que l'information minimum nécessaire, sous la forme la mieux adaptée. On pourrait éventuellement s'inspirer de méthodes utilisées dans le cadre de l'inférence des DF comme la construction de partitions [HUHT99]. Nous travaillons actuellement sur l'utilisation et la mise en œuvre de ces différentes techniques d'optimisation d'accès à la base.

6 Découverte des DI approximatives La connaissance des DI approximatives vérifiées dans une base de données peut s'avérer utile, par exemple pour détecter d'éventuelles erreurs parmi les tuples existants. Le problème de la découverte des DI approximatives peut être formulé ainsi : Etant donnée une base de données d sur un schéma R, trouver toutes les DI non triviales Ri[X] ⊆ Rj[Y], Ri,Rj ∈ R, telles que Ri[X] ⊆ Rj[Y] est "presque satisfaite dans d". Il s'agit dans un premier temps de formaliser la notion de "presque satisfaite". Une mesure d'erreur intéressante est donnée par la fonction g′3, définie par : g′3(Ri[X] ⊆ Rj[Y],d) = 1 − |πX(ri) υ (X = Y)πY(rj)| / |πX(ri)|. Exemple 10 Dans l'exemple de la table 1, on a : g′3(R[C] ⊆ S[E])=1 − 1 / 2 = 0.5. De manière informelle, g′3 est la proportion de valeurs dans X qu'il faudrait supprimer (indépendamment de leur nombre d'occurrences) pour obtenir une base de données d′ telle que d′ Ri[X] ⊆ Rj[Y]. On dit que Ri[X] ⊆ Rj[Y] est une DI approximative satisfaite dans d, et on note d ~ Ri[X] ⊆ Rj[Y], ssi g′3(Ri[X] ⊆ Rj[Y],d) < ε, ε défini par l'utilisateur. La propriété suivante nous permet de traiter le problème des DI approximatives à l'aide d'une approche par niveaux. Propriété 3 Soient I1 et I2 deux DI candidates sur une base de données d, telles que I1 α I2 -

Si d

~ I1,

-

Si d



alors d

I2, alors d

~ I2



et

I1.

Preuve Ce résultat découle du fait que, étant données I1 et I2 deux DI candidates, on a : I1α I2 Þ g′3(I1) ≤ g′3(I2). Cela est évident si l'on considère les définitions de g′3 et de l'ordre α. [¯]

Ainsi, l'algorithme 1 peut être appliqué. Simplement, la fonction GenIND doit être remplacée par la fonction GenAIND donnée dans l'algorithme 5 ci-après. Algorithme 5GenAIND : Evaluation des DI approximatives candidates Entrée : Ci, un ensemble de DI approximatives candidates de taille i et d, la base de données. Sortie : Ii, ensemble des DI approximatives satisfaites de taille i. 1: for all c ∈ Ci do 2: if d ~ c then 3: Ii:= Ii ∪ {c}; 4: end if 5: end for

Remarques : 1. On ne donne pas d'algorithme pour générer les candidats de niveau 1, même si celui-ci est légèrement différent de l'algorithme 2. En effet, la propriété 2 est fausse pour les DI approximatives, i.e. étant donnés deux attributs Ri[X] et Rj[Y], même si |πX(ri)| ≠ |πY(rj)|, les deux DI approximatives Ri[X] ⊆ Rj[Y] et Rj[Y] ⊆ Ri[X] peuvent être satisfaites dans d.

2. Les améliorations basées sur les cardinalités des projections et l'utilisation des DF proposées dans la section 5 ne sont pas applicables pour la découverte des DI approximatives car celles-ci ne vérifient pas les propriétés mises en jeu.

7 Conclusion La découverte des dépendances d'inclusion dans les bases de données relationnelles est un problème relativement peu étudié. Il est intéressant dans des applications telles que la conception et la maintenance des bases de données ou l'optimisation sémantique des requêtes. Dans cette article, nous proposons un algorithme par niveaux pour la découverte des DI dans une base de données relationnelle. Ce travail est le premier qui s'intéresse de manière compréhensive et globale à ce problème, en proposant des résultats expérimentaux. Nous avons focalisé notre attention sur la réduction du nombre de DI devant être testées sur la base, en créant des algorithmes originaux de génération de candidats basés sur les propriétés des DI. Puis, les accès à la base ont été réalisés avec des requêtes SQL, qui ont l'avantage d'être utilisables de manière simple dans pratiquement tous les SGBD. Nous avons ensuite mis en évidence que notre algorithme par niveaux pouvait être étendu à la découverte des DI approximatives, c'est à dire les DI qui sont presque satisfaites dans une base de données. Nous avons pour cela introduit une nouvelle mesure d'erreur, appelée g′3. Étant donnée la complexité inhérente du problème de la découverte de toutes les DI d'une base de données, un certain nombre de tests sur des données synthétiques sont actuellement en cours d'élaboration. Il s'agit d'étudier les limites de notre algorithme en fonction du nombre de tuples et du nombre d'attributs dans les relations. Nous pourrons ainsi déterminer les cas où cette méthode est applicable, et les cas où l'on devra faire des compromis et éventuellement ne découvrir qu'un sous ensemble des DI satisfaites dans une base de données. De nombreux travaux restent à effectuer, comme par exemple la phase d'accès aux données, comme nous l'avons évoqué dans la section 5, avec l'utilisation de programmes PL/SQL ou la mise en œuvre d'une phase de préparation des données. Ce travail s'inscrit dans un cadre de recherche portant sur l'analyse des bases de données relationnelles. Nous nous intéressons en particulier à la découverte des dépendances fonctionnelles et des dépendances d'inclusion au sein d'une base existante, ou encore à la construction de relations et de bases de données d'Armstrong informatives [DEMA01].

Références [AGRA94]

R. Agrawal and R. Srikant. Fast Algorithms for Mining Association Rules in Large Databases. In VLDB'94, Santiago, Chile, 1994.

[BAST00]

Y. Bastide, R. Taouil, N. Pasquier, G. Stumme, and L. Lakhal. Mining frequent patterns with counting inference. SIGKDD Exploration, 2(2):71-80, December 2000.

[BELL95]

S. Bell and P. Brockhausen. Discovery of Data Dependencies in Relational Databases. LS-8 Report 04, University of Dortmund, 1995.

[CASA83]

M.A. Casanova and J.E.A. de Sá. Designing Entity-Relationship Schemes for Conventional Information Systems. In ER'83, Anaheim, California, 1983.

[CASA84]

M. Casanova, R. Fagin, and C. Papadimitriou. Inclusion dependencies and their interaction with functional dependencies. Journal of Computer and System Sciences, 28(1):29-59, February 1984.

[CASA88]

M.A. Casanova, L. Tucherman, and A-L. Furtado. Enforcing Inclusion Dependencies and Referential Integrity. In VLDB'88, Los Angeles, USA, 1988.

[CHEN99]

Q. Cheng, J. Gryz, F. Koo, C. Leung, L. Liu, X. Qian, and B. Schiefer. Implementation of two semantic query optimization techniques in DB2 universal database. In VLDB'99, Edinburgh, Scotland, UK, 1999.

[COMY99]

I. Comyn-Wattiau and J.Akoka. Relational database reverse engineering. Network and Information Systems, 2(3):345-, 1999.

[DATE81]

C. J. Date. Referential integrity. In VLDB'81, Cannes, France, 1981.

[DEMA01]

F. De Marchi, S. Lopes, J-M. Petit. Informative Armstrong Relations: Application to Database Analysis. Rapport de recherche, laboratoire LIMOS, Clermont-Fd, France, 2001.

[GRYZ98]

J. Gryz. Query Folding with Inclusion Dependencies. In ICDE'98, Orlando, Florida, 1998.

[GUNO97]

D. Gunopulos, R. Khardon, H. Mannila, and H. Toivonen. Data mining, hypergraph transversals, and machine learning. In PODS'97, Tucson, Arizona, U.S.A., 1997.

[HUHT99]

Y. Huhtala, J. Karkkainen, P. Porkka, and H. Toivonen. TANE: An efficient algorithm for discovering functional and approximate dependencies. COMPJ: The Computer Journal, 42(2):100-111, 1999.

[KANT92]

M. Kantola, H. Mannila, K. J. Räihä, and H. Siirtola. Discovering functional and inclusion dependencies in relational databases. International J. Of Intelligent Systems, 7:591-607, 1992.

[LAUR99]

D. Laurent, J. Lechtenbörger, N. Spyratos, and G. Vossen. Complements for data warehouses. In ICDE'99, Sydney, Austrialia, 1999.

[LEVE99]

M. Levene and G. Loizou. A Guided Tour of Relational Databases and Beyond. SPRINGER, 1999.

[LEVE00]

M. Levene and M. W. Vincent. Justification for inclusion dependency normal form. Transactions on Knowledge and Data Engineering, 12(2):281-291, 2000.

[LING92]

T. Wang Ling and C. Hian Goh. Logical database design with inclusion dependencies. In ICDE'92, Tempe, Arizona, 1992.

[LOPE00]

S. Lopes, J.-M. Petit, and L. Lakhal. Efficient discovery of functional dependencies and armstrong relations. In EDBT'00, Konstanz, Germany, 2000.

[LOPE01]

S. Lopes, J-M. Petit, and F. Toumani. Discovering interesting inclusion dependencies: Application to logical database tuning. à paraître dans Information Systems 2001.

[MANN86a] H. Mannila and K.-J. Räihä. Design by example: An application of armstrong relations. Journal of Computer and System Sciences, 33(2):126-141, October 1986. [MANN86b] H. Mannila and K.-J. Räihä. Inclusion dependencies in database design. In ICDE'86, Los Angeles, California, USA, 1986. [MANN94]

H. Mannila and K. J. Räihä. The Design of Relational Databases. AddisonWesley,second edition, 1994.

[MANN97]

H. Mannila and H. Toivonen. Levelwise Search and Borders of Theories in Knowledge Discovery. Data Mining and Knowledge Discovery, 1(3):241-258, 1997.

[MARK90]

V.M. Markowitz and J.A. Makowsky. Identifying Extended Entity-Relationship Object Structures in Relational Schemas. Transactions on Software Engineering, 16(8):777-790, August 1990.

[MASS00]

F. Masseglia, P. Poncelet, and M. Teisseire. Incremental mining of sequential patterns in large databases. In BDA'00, Blois, france, October 2000.

[MITC83]

John C. Mitchell. The implication problem for functional and inclusion dependencies. Information and Control, 56(3):154-173, March 1983.

[NOVE01]

N. Novelli and R. Cicchetti. Fun: an efficient algorithm for mining functional and embedded dependencies. In ICDT'01, England, April 2001.

[PAUL94]

G. N. Paulley and P. Larson. Exploiting uniqueness in query optimization. In ICDE'94, Houston, Texas, USA, 1994.

[PETI96]

J-M. Petit, F. Toumani, J-F. Boulicaut, and J. Kouloumdjian. Towards the Reverse Engineering of Denormalized Relational Databases. In ICDE'96. New Orleans, USA, 1996.

[PETI99]

J-M. Petit and F. Toumani. Discovery of inclusion and approximate dependencies in databases. In BDA'99, Bordeaux, France, October 1999.

[PICH90]

E. Pichat and R. Bodin. Ingénierie des données. Masson, 1990.

[POPA00]

L. Popa, A. Deutsch, A. Sahuguet, and V. Tannen. A chase too far? In SIGMOD'00, New York, NY 10036, USA, 2000.

[QIAN96]

X. Qian. Query folding. In ICDE'96. New Orleans, USA, 1996.

[QUAS96]

D. Quass, A. Gupta, I. S. Mumick, and J. Widom. Making views selfmaintainable for data warehousing. In PDIS'96, Miami Beach, Florida, USA, 1996.

[SRIK96]

R. Srikant and R. Agrawal. Mining sequential patterns: Generalizations and performance improvements. In EDBT'96, Avignon, France, 1996.