• Aucun résultat trouvé

[PDF] Les Bases de données pas à pas guide de formation avance | Cours informatique

N/A
N/A
Protected

Academic year: 2021

Partager "[PDF] Les Bases de données pas à pas guide de formation avance | Cours informatique"

Copied!
170
0
0

Texte intégral

(1)

Bases de Données I

Université de Mons Jef Wijsen 2017–2018

(2)

Préface

Merci de signaler toute erreur, de toute sorte (orthographe, grammaire, typographie, contenu. . .), à [email protected]. Des suggestions pour améliorer les explications seront également appréciées.

(3)

Table des matières

I Le Modèle Relationnel 5

1 Préliminaires 6

2 La Structure du Modèle Relationnel 7

2.1 Relations . . . 7 2.2 Bases de données . . . 8 2.3 Clé primaire et clé étrangère . . . 9 2.4 La contrainte UNIQUE . . . 10 2.5 Le bouche-trou NULL . . . 10 2.6 La perspective “Unnamed” . . . 11 3 L’Algèbre Relationnelle 12 3.1 Syntaxe . . . 12 3.2 Sémantique . . . 13 3.3 Exemples . . . 13 3.4 Inclusion et équivalence . . . 14

3.5 Non-redondance des opérateurs . . . 15

3.6 Fermeture transitive . . . 16 3.7 La perspective “Unnamed” . . . 16 3.7.1 Syntaxe . . . 16 3.7.2 Sémantique . . . 17 3.7.3 Exemple . . . 17 4 Le Calcul Relationnel 18 4.1 Syntaxe . . . 18 4.2 Sémantique . . . 19 4.3 Indépendance du domaine . . . 20

4.4 Des requêtes dites safe . . . 22

4.5 Discussions approfondies . . . 23 4.6 Le calcul relationnel TRC . . . 24 4.6.1 TRC par l’exemple . . . 24 4.6.2 Syntaxe . . . 25 4.6.3 Sémantique . . . 26 4.6.4 Du TRC au SQL . . . 27 5 SQL 28 5.1 La base de données . . . 28

5.2 Création de domaines et de tables . . . 28

(4)

5.4 Mises à jour . . . 33

5.5 Intégration de SQL à des langages de programmation . . . 34

5.6 Vues . . . 35

5.6.1 Définition des Vues . . . 35

5.6.2 Interrogation au travers de vues . . . 35

5.6.3 Mise à jour au travers de vues . . . 35

6 Les Dépendances Fonctionnelles 36 6.1 Introduction . . . 36

6.2 Syntaxe et sémantique . . . 36

6.3 Fermeture d’un ensemble d’attributs . . . 37

6.4 Autres dépendances . . . 38

6.4.1 Dépendances de jointure et dépendances multivaluées . . . 38

6.4.2 Dépendances d’inclusion . . . 39

7 Les Formes Normales 41 7.1 La redondance . . . 41

7.2 BCNF . . . 41

7.3 Décompositions . . . 42

7.4 Décomposition en BCNF . . . 43

7.5 3NF . . . 44

7.6 Dépendances fonctionnelles singulières . . . 45

7.7 Décomposition en 3NF . . . 45 7.8 1NF, 2NF, 4NF, 5NF . . . 46 7.8.1 1NF et 2NF . . . 46 7.8.2 4NF . . . 47 7.8.3 5NF . . . 47 8 Le Modèle Entité-Association 49 8.1 Énoncé . . . 49 8.2 Le diagramme entité-association . . . 50

8.3 Traduction vers le modèle relationnel . . . 50

II Gestion des Transactions 52 9 Two-Phase Locking (2PL) 53 9.1 Cadre théorique . . . 53

9.2 Les exécutions sérielles . . . 54

9.3 Les exécutions sérialisables . . . 54

9.4 L’écriture aveugle . . . 55

9.5 Spécification du protocole 2PL . . . 55

9.5.1 Le comportement d’une transaction . . . 56

9.5.2 L’exécution globale . . . 56

9.6 Implémentation du protocole 2PL . . . 57

9.7 Le verrou mortel . . . 59

9.8 Strict 2PL . . . 60

10 Résistance aux Pannes et Reprise 62 10.1 Le buffer . . . 62

(5)

10.2 Undo/Redo . . . 63 10.3 Le journal . . . 64 10.4 Procédure de Reprise . . . 64 10.5 Exemple . . . 64 10.6 Checkpointing . . . 65 10.7 Undo/No-Redo et Redo/No-Undo . . . 66 III Exercices 67 A Les Grandes Découvertes en Bases de Données 118 A.1 Introduction . . . 118

A.2 Les BD Hiérarchiques . . . 118

A.3 Les BD de Type Réseau . . . 119

A.4 Les BD Relationnelles . . . 122

A.5 Le Web, une BD ? . . . 124

A.5.1 Un Manque de Structure . . . 124

(6)

Première partie

(7)

Chapitre 1

Préliminaires

L’ensemble vide est dénoté par ∅ ou {}.

Soient A et B deux ensembles. On écrit A ( B si A ⊆ B et A 6= B. On dénote par |A| le nombre d’éléments dans A.

Le produit cartésien de A et B, dénoté par A × B, est l’ensemble

A× B := {(a, b) | a ∈ A, b ∈ B}.

Une relation binaire sur A est un sous-ensemble de A × A.

Soit R une relation binaire sur A. On dit que R est transitive si pour tout a, b, c ∈ A, si (a, b) ∈ R et (b, c) ∈ R, alors (a, c) ∈ R. La fermeture transitive de R est la plus petite (par rapport à ⊆) relation binaire qui contient R et qui est transitive.

Soit n un entier non-négatif. L’ensemble An est défini comme suit :

An:= {ha1, . . . , ani | a1, . . . , an∈ A}.

Une fonction totale f de A vers B, dénotée f : A → B, est un sous-ensemble de A × B tel que pour tout a ∈ A, il existe exactement un élément b ∈ B tel que (a, b) ∈ f ; cet unique élément b est alors dénoté par f(a). On appelle A le domaine de f.

Soit f : A → B une fonction totale et A0 ⊆ A. La restriction de f à l’ensemble A0, dénoté par

f[A0], est la fonction totale f0 : A0→ B telle que pour chaque a ∈ A0, f0(a) = f(a).

Un cas particulier est la restriction de f à l’ensemble vide : f[∅] = {}.

Exemple 1. Soient A = {a, b, c} et B = {1, 2, 3, 4}. Soit f = {(a, 1), (b, 2), (c, 2)}. Alors f est

une fonction totale de A vers B.

(8)

Chapitre 2

La Structure du Modèle

Relationnel

Future users of large data banks must be protected from having to know how the data is organized in the machine (the internal representation).

J.F. Codd, 1970 [5, page 377]

Le modèle relationnel a été introduit en 1970 par E.F. Codd [5]. Un premier prototype de système de base de données relationnelle, appelé “System R”, a été développé à partir de 1974 [3]. C’était le début d’une technologie révolutionnaire qui est maintenant omniprésente : le SGBDR, Système de Gestion de Base de Données Relationnelle.

Les ouvrages suivants présentent, de façon rigoureuse, les fondements théoriques des bases de données relationnelles :

— “The Theory of Relational Databases” par D. Maier [11] ;

— “Principles of Database and Knowledge-Base Systems” par J.D. Ullman [12, 13] ; — “Foundations of Databases” par S. Abiteboul, R. Hull et V. Vianu [1].

Les livres [1] et [11] sont gratuitement disponibles en ligne.

2.1 Relations

Supposons

— un ensemble infini dom dont les éléments sont appelés des valeurs (ou des constantes) ; — un nombre d’ensembles non vides, appelés domaines. Chaque domaine est un sous-ensemble

de dom ;

— un nombre infini d’attributs A, B, C, A1, B1, C1, . . . ; et

— une fonction Dom qui fait correspondre, à chaque attribut, un domaine.

Un schéma-de-relation (ou simplement schéma si aucune confusion n’est possible) est alors un ensemble fini A d’attributs.

(9)

Pr´enom Genre Jean ♂ Anne ♀

Figure 2.1 – Une relation présentée sous forme de table.

Un tuple sur ce schéma-de-relation est une fonction totale t : A → dom telle que pour tout attribut A ∈ A, t(A) ∈ Dom(A). Une relation sur ce schéma-de-relation est un ensemble fini de tuples sur ce schéma.

Exemple 2. Soit N l’ensemble des prénoms autorisés en Belgique. Soient Pr´enom et Genre

deux attributs avec Dom(Pr´enom) = N et Dom(Genre) = {♂, ♀}. Alors {Pr´enom, Genre} est un schéma-de-relation. Deux tuples sur ce schéma-de-relation sont {(Pr´enom, Jean), (Genre, ♂)} et {(Pr´enom, Anne), (Genre, ♀)}. L’ensemble qui contient ces deux tuples est une relation.

Les relations seront souvent présentées sous forme de table. La table de la figure 2.1 présente la relation de l’exemple 2. Ensuite, il est habituel de parler de “la première rangée” pour dénoter le tuple {(Pr´enom, Jean), (Genre, ♂)}, ou de “la première colonne”. Noter cependant que des relations et des schémas-de-relation sont des ensembles non-ordonnés.

Dans la théorie, on va souvent négliger les domaines, en supposant que pour chaque attribut A, Dom(A) = dom.

Si A1, A2, . . . , A` sont des attributs, on écrira souvent A1A2· · · A` pour dénoter l’ensemble

{A1, A2, . . . , A`}. Si X et Y sont des ensembles d’attributs, on écrira souvent XY pour dénoter

l’union X ∪ Y .

Par exemple, si A et B sont des attributs, et X est un ensemble d’attributs, alors X ∪ {A, B} peut être abrévié comme XAB.

2.2 Bases de données

Supposons un nombre infini de noms de relation R, S, T, R1, S1, T1, . . ., et une fonction sorte qui

fait correspondre, à chaque nom de relation, un schéma-de-relation. La notation R[A1, . . . , An]

est utilisée pour dénoter que R est un nom de relation avec sorte(R) = {A1, . . . , An}.

Un schéma-de-base-de-données (ou simplement schéma si aucune confusion n’est possible) est alors un ensemble fini R de noms de relation. Une base de données (ou instance de base de données) sur ce schéma-de-base-de-données est une fonction totale avec domaine R qui fait correspondre, à chaque nom de relation R dans R, une relation sur sorte(R). Le symbole I sera

souvent utilisé pour dénoter une base de données ; pour R ∈ R, on dénote par RI la relation qui

correspond à R.

Il est habituel de présenter une base de données comme un ensemble de tables, comme illustré dans la figure 2.2. Le schéma de cette base de données est {VINS, ABUS} avec sorte(VINS) = {Cru,

(10)

VINS Cru Mill´esime Qualit´e Volnay 1983 A Volnay 1979 B Chablis 1983 A Julienas 1986 C

ABUS Buveur Cru Mill´esime Jean Volnay 1983 Jean Volnay 1979 Pierre Volnay 1979 Pierre Julienas 1986

Figure 2.2 – Une base de données présentée sous forme de tables. Exemple issu de [8].

2.3 Clé primaire et clé étrangère

On fait correspondre, à chaque nom de relation R, une clé primaire, en utilisant la syntaxe suivante :

R PRIMARY KEY(A1, A2, . . . , Ak), (2.1)

avec A1, A2, . . . , Ak des attributs distincts appartenant à sorte(R). Soit I une base de données

dont le schéma contient R. On dit que I satisfait (ou respecte) la clé primaire de R si pour tout

t1, t2 ∈ RI, si t1[A1A2· · · Ak] = t2[A1A2· · · Ak], alors t1 = t2. C’est-à-dire, la base de données I

respecte la clé primaire si pour chaque tuple t ∈ RI, il n’existe pas d’autre tuple dans RI avec

la même valeur pour (les attributs de) la clé primaire ; chaque tuple t ∈ RI est donc identifié

de façon unique par sa valeur pour la clé primaire. Il est habituel de souligner les attributs qui constituent la clé primaire.

La clé primaire de R peut être utilisée ailleurs pour faire référence aux tuples d’une relation RI.

La syntaxe est comme suit :

S FOREIGN KEY(B1, B2, . . . , Bk) REFERENCES R, (2.2)

avec S un nom de relation et B1, B2, . . . , Bk des attributs appartenant à sorte(S). Soit I une

base de données dont le schéma contient R et S. On dit que I satisfait (ou respecte) la clé

étrangère (2.2) si pour tout tuple s ∈ SI, il existe un tuple (unique) t ∈ RI tel que pour

chaque i ∈ {1, . . . , k}, s(Bi) = t(Ai), où les attributs A1, . . . Ak constituent la clé primaire (2.1).

C’est-à-dire, chaque tuple de SI fait référence à un tuple unique de RI en copiant sa valeur

pour la clé primaire. Noter que la longueur k de la clé étrangère est identique à la longueur de

la clé primaire de R. Il est cependant possible que Bi6= Ai (pour un ou plusieurs i ∈ {1, . . . , k}).

Il est aussi possible que S = R.

Les clés primaires et étrangères constituent un mécanisme élégant pour relier des tuples de différentes relations, tout en évitant des références “artificielles” telles que les pointeurs ou les auto-incréments. Les clés primaires et étrangères sont des contraintes que l’on ajoute à un schéma-de-bases-de-données pour restreindre les bases de données qui sont admissibles.

Exemple 3. Pour la base de données de la figure 2.2, on peut raisonnablement imposer les clés

primaires et la clé étrangère suivantes :

VINS PRIMARY KEY(Cru, Mill´esime)

ABUS PRIMARY KEY(Buveur, Cru, Mill´esime)

ABUS FOREIGN KEY(Cru, Mill´esime) REFERENCES VINS

La clé primaire de VINS exprime qu’aucun cru ne peut avoir deux qualités différentes pour une même année.

(11)

VOITURES Plaque Chˆassis Type Ann´ee CGD.123 13459ABC Renault 19 1992 SAP.346 CBA54321 Peugeot 404 1994 ACCESSOIRES Plaque Accessoire

CGD.123 radio

CGD.123 système antivol

Figure 2.3 – Base de données. Chaque voiture a une plaque et un numéro de châssis qui lui sont propres.

Exemple 4. Cet exemple artificiel montre l’importance de l’ordre des attributs dans la

spécifi-cation des clés primaires et étrangères.

R[A, B]

R PRIMARY KEY(A, B)

R FOREIGN KEY(B, A) REFERENCES R

Une base de données I (dont le schéma contient R) respecte ces contraintes si et seulement

si pour tout t1 ∈ RI, il existe t2 ∈ RI tel que t2(B) = t1(A) et t2(A) = t1(B). Noter que la

clé primaire dans cet exemple sera toujours respectée, car une relation est un ensemble (sans doublons).

2.4 La contrainte UNIQUE

La syntaxe de la contrainte UNIQUE est comme suit :

R UNIQUE(A1, A2, . . . , Ak),

avec R un nom de relation et A1, A2, . . . , Ak des attributs distincts appartenant à sorte(R).

Cette contrainte est satisfaite par une bases de données I (dont le schéma contient R) si pour

tout t1, t2∈ RI, si t1[A1A2· · · Ak] = t2[A1A2· · · Ak], alors t1 = t2.

Exemple 5. La base de données de la figure 2.3 enregistre les accessoires présents dans différentes

voitures. La contrainte UNIQUE exprime que chaque voiture a un numéro de châssis qui lui est unique.

VOITURES [Plaque, Chˆassis, Type, Ann´ee]

VOITURES PRIMARY KEY(Plaque)

VOITURES UNIQUE(Chˆassis)

ACCESSOIRES [Plaque, Accessoire]

ACCESSOIRES PRIMARY KEY(Plaque, Accessoire)

ACCESSOIRES FOREIGN KEY(Plaque) REFERENCESS VOITURES

2.5 Le bouche-trou NULL

(12)

CITOYENS NN Pr´enom Nom NPermisConduire 94.04.01-001.31 Alex Astaire 123456789 15.09.11-001.47 Bart Bretelle NULL 91.06.22-001.31 Cloé Camp NULL

Figure 2.4 – Base de données avec des NULLs.

généralement de remplacer la valeur absente par le symbole NULL. Dans la base de données de la figure 2.4, NN dénote le numéro national, et NPermisConduire le numéro de permis de conduire. Le numéro national de Bart Bretelle indique qu’il est né à la date du 11 septembre 2015 ; il est trop jeune pour avoir un permis de conduire. La situation est moins claire pour Cloé Camp : soit elle n’a pas de permis de conduire, soit elle a un permis de conduire dont le numéro est manquant dans la base de données actuelle.

Le bouche-trou NULL n’étant pas une valeur (i.e., NULL 6∈ dom), il est nécessaire d’étendre les définitions des sections 2.1–2.4 pour tenir compte des NULLs. Par exemple, est-ce-que la relation

VOITURESde la figure 2.3 pourrait contenir deux tuples distincts t1, t2tels que t1(Chˆassis) = NULL

et t2(Chˆassis) = NULL, tout en respectant la contrainte VOITURES UNIQUE(Chˆassis) ?

Cependant, cette extension avec NULL est hors de portée du présent syllabus.

2.6 La perspective “Unnamed”

Le formalisme expliqué précédemment utilise des attributs pour dénoter une valeur dans un tuple ; on parle de la perspective “Named”, dans le sens où les attributs portent un nom. Dans la perspective “Unnamed”, les attributs sont remplacés par des indices 1, 2, 3, . . .

Soit n un entier non-négatif. Une relation d’arité n est un sous-ensemble fini de domn.

On définit la fonction arit´e qui fait correspondre, à chaque nom de relation R, un entier non-négatif tel que arit´e(R) = |sorte(R)|.

Soit R un schéma-de-base-de-données. Une base de données sur R est une fonction totale avec domaine R qui fait correspondre, à chaque nom de relation R dans R, une relation d’arité arit´e(R).

Les définitions de clé primaire, clé étrangère et la contrainte UNIQUE peuvent facilement être adaptées à la perspective “Unnamed”.

Dès que l’on ajoute un ordre aux attributs dans la perspective “Named”, une correspondance évidente émerge entre les perspectives “Named” et “Unnamed”. Cet ordre est généralement

l’ordre dans lequel on liste les attributs dans la notation R[A1, . . . , An]. Alors, un tuple “Named”

(13)

Chapitre 3

L’Algèbre Relationnelle

Soit R un schéma-de-base-de-données (i.e., un ensemble fini de noms de relation). On peut concevoir une requête comme un programme informatique qui prend en entrée une base de données I sur R et qui donne en sortie une relation. Le “langage de programmation” introduit dans ce chapitre est l’algèbre relationnelle. Ce langage est moins puissant que les langages Java ou Python, mais est beaucoup plus simple et se prête mieux aux analyses théoriques.

Dans un premier temps, on introduira l’algèbre relationnelle dans la perspective “Named”. Cette algèbre est dénotée par le sigle SPJRUD, qui contient la première lettre de chaque opérateur de l’algèbre.

3.1 Syntaxe

Soit R un schéma-de-bases-de-données.

Noms de relation Chaque nom de relation R dans R est une expression algébrique

(ato-mique).

Sélection “attribut égal constante” Si E est une expression algébrique, A ∈ sorte(E),

et a ∈ dom, alors σA=“a”(E) est une expression algébrique avec sorte(σA=“a”(E)) =

sorte(E).

Sélection “attribut égal attribut” Si E est une expression algébrique et A, B ∈ sorte(E),

alors σA=B(E) est une expression algébrique avec sorte(σA=B(E)) = sorte(E).

Projection Si E est une expression algébrique et X ⊆ sorte(E), alors πX(E) est une

expression algébrique avec sorte(πX(E)) = X.

Jointure Si E1 et E2 sont des expressions algébriques, alors E1 1 E2 est une expression

algébrique avec sorte(E11 E2) = sorte(E1) ∪ sorte(E2).

Renommage Si E est une expression algébrique, A ∈ sorte(E), et B est un attribut tel

que B 6∈ sorte(E), alors ρA7→B(E) est une expression algébrique avec sorte(ρA7→B(E)) =

(sorte(E) \ {A}) ∪ {B}.

Union Si E1 et E2 sont des expressions algébriques avec sorte(E1) = sorte(E2), alors E1∪·E2

est une expression algébrique avec sorte(E1∪· E2) = sorte(E1). Noter que le symbole ∪·

est utilisé ici pour marquer la différence avec l’union ensembliste ∪. Si aucune confusion

(14)

Différence Si E1 et E2 sont des expressions algébriques avec sorte(E1) = sorte(E2), alors

E1− E2 est une expression algébrique avec sorte(E1− E2) = sorte(E1).

Des parenthèses sont utilisées pour préciser l’ordre d’évaluation. En absence de parenthèses, la

jointure est prioritaire sur l’union et la différence. Par exemple, l’expression πA(R) 1 S ∪· T doit

être évaluée comme (πA(R) 1 S) ∪· T.

3.2 Sémantique

Soit I une base de données sur R.

Si E est une expression algébrique, on dénote parJE K

I la relation qui est le résultat de l’évaluation

de E sur I. La définition deJE K

I est comme suit :

— Si R est un nom de relation, alorsJRK

I := RI. Donc, le résultat de l’expression R est

la relation dans la base de données qui correspond à R. Noter que pour deux bases de

données différentes, I et J , il est possible que JRK

I 6= JRK J.JσA=“a”(E)K I := {t ∈ JE K I | t(A) = a}.JσA=B(E)K I := {t ∈ JE K I | t(A) = t(B)}.JπX(E)K I := {t[X] | t ∈ JE K I}.

— Soit X = sorte(E1) et Y = sorte(E2).

Alors JE1 1 E2K I := {t | t[X] ∈ JE1K I et t[Y ] ∈ JE2K I}. — Soit X = sorte(E) \ {A}.

Alors JρA7→B(E)K

I := {t | il existe s ∈

JE K

I tel que s[X] = t[X] et s[A] = t[B]}.

JE1∪· E2K

I :=

JE1K

I

JE2K

I, avec ∪ l’union ensembliste.

JE1− E2K

I :=

JE1K

I\

JE2K

I, avec \ la différence ensembliste.

Une expression algébrique E est aussi appelée une requête, et JE K

I est la réponse à la requête E

sur la base de données I.

3.3 Exemples

Les buveurs exigeants Disons qu’un buveur est exigeant s’il ne boit que des vins de qualité A.

Pour la base de données de la figure 2.2, on souhaite encoder la requête “Quels buveurs sont exigeants ?”. Soit

E1 := π{Buveur,Qualit´e}(ABUS 1 VINS).

Un tuple {(Buveur, b), (Qualit´e, q)} dans l’évaluation de E1 signifie que b est un buveur qui a

déjà bu un vin de qualité q. L’expression suivante rend alors les buveurs qui ont déjà bu un vin qui n’est pas de qualité A :

E2 := π{Buveur}(E1− σQualit´e=“A”(E1)).

Si on substitue dans cette expression la définition de E1, on obtient :

(15)

Cependant, cette substitution nuit à la lisibilité.

L’expression demandée E3 doit rendre tout buveur qui n’est pas dans l’évaluation de E2.

Donc,

E3:= πBuveur(ABUS) − E2.

L’expression E2 peut être simplifiée si on introduit l’abréviation suivante. Si A ∈ sorte(R), alors

σA6=“a”(R) est une abréviation pour R − σA=“a”(R). Avec cette abréviation, E2 peut s’écrire comme

E2 := π{Buveur}Qualit´e6=“A”(E1)).

La table sans colonnes La définition de πX(E) permet X = {}. Quelle requête est encodée

par E4 := π{}(E3) ?

S’il existe au moins un buveur exigeant, alors l’évaluation de E4 rend la relation {{}}, i.e., la

relation qui contient le tuple vide. S’il n’existe pas de buveur exigeant, alors l’évaluation de E4rend

la relation vide {}. Il est habituel d’interpréter {{}} et {} respectivement comme true et false.

L’expression E4 encode alors la requête booléenne “Existe-t-il des buveurs exigeants ?”.

Les buveurs ayant bu plusieurs crus Pour la base de données de la figure 2.2, on souhaite

encoder la requête “Quels buveurs ont déjà bu deux ou plusieurs crus différents ?”. Soit E1 := π{Buveur,Cru}(ABUS) 1 ρCru7→Vin(π{Buveur,Cru}(ABUS)).

La requête finale E2 est comme suit :

E2 := π{Buveur}(E1− σCru=Vin(E1)).

3.4 Inclusion et équivalence

Dans les définitions suivantes, un schéma-de-bases-de-données R est sous-entendu.

Soient E1 et E2 deux expressions algébriques. On dira que l’expression E1 est inclue dans E2,

dénoté par E1 v E2, si pour toute base de données I,JE1K

I

JE2K

I.

On dira que les expressions E1 et E2 sont équivalentes, dénoté par E1 ≡ E2, si E1 v E2 et

E2 v E1.

Exemple 6. Soit R et S deux noms de relation avec sorte(R) = sorte(S). Soit X ⊆ sorte(R).

On peut facilement prouver que πX(R ∪· S) ≡ πX(R) ∪· πX(S).

Il a été prouvé [1, Corollary 6.3.2] que l’équivalence des expressions algébriques est indécidable. C’est-à-dire, il n’existe pas d’algorithme qui prend en entrée deux expressions algébriques, et détermine si, oui ou non, ces deux expressions sont équivalentes.

(16)

R A B

a 1

R A B

a 1

a 2

Figure 3.1 – Bases de données I (à gauche) et J (à droite).

3.5 Non-redondance des opérateurs

Un exercice intéressant est de démontrer qu’aucun des six opérateurs de l’algèbre SPJRUD n’est redondant. Démontrons ici que la différence est un opérateur non-redondant. Dénotons par SPJRU l’algèbre relationnelle qui ne contient pas la différence.

La démonstration fera appel aux bases de données I et J de la figure 3.1, et l’expression algébrique

E0 := πA(σB=“1”(R)) − πA(σB=“2”(R)).

On a JE0K

I = {{(A, a)}} et

JE0K

J = {}. Remarquons que J ajoute un tuple à I, mais que

JE0K

J (

JE0K

I. On appelle cette requête non-monotone : l’insertion de tuples dans la base

de données peut avoir comme effet la suppression de tuples de la réponse. Intuitivement, la différence est redondante car c’est le seul opérateur permettant de ressortir cet effet non-monotone.

De façon plus formelle, démontrons qu’aucune expression algébrique de l’algèbre SPJRU (i.e.,

l’algèbre sans la différence) n’est équivalente à E0. Dans le paragraphe suivant, on prouve que

pour toute expression algébrique E de l’algèbre SPJRU,JE K

I ⊆JE K J. À partir de JE K I ⊆JE K J et JE0K J ( JE0K

I, il est correct de conclure que soit

JE K I 6= JE0K I, soit JE K J 6= JE0K J (soit les deux), et donc E 6≡ E0.

On prouve maintenant, par induction, que pour toute expression algébrique E de l’algèbre

SPJRU,JE K

I JE K

J. La base de l’induction est E = R, où R est un nom de relation. Par notre

choix de I et J (voir figure 3.1), on a bien queJRK

I = RI est un sous-ensemble de

JRK

J = RJ. Les autres possibilités pour E sont comme suit :

— E est une sélection σC=“c”(E1). Noter que même si sorte(R) = {A, B}, il est possible

que C ∈ sorte(E1), car E1 peut contenir un renommage. L’hypothèse d’induction est

JE1K

I

JE1K

J, c’est-à-dire, l’évaluation de E

1 sur I est un sous-ensemble de l’évaluation

de E1sur J . Il est alors évident que l’évaluation de σC=“c”(E1) sur I est un sous-ensemble

de l’évaluation de σC=“c”(E1) sur J , i.e., JσC=“c”(E1)K

I

JσC=“c”(E1)K J.

— E est une sélection σC=D(E1). Raisonnement similaire au premier point.

— E est une projection πX(E1). Raisonnement similaire au premier point.

— E est un renommage ρC7→D(E1). Raisonnement similaire au premier point.

— E est une jointure E1 1 E2. L’hypothèse d’induction estJE1K

I JE1K J et JE2K I JE2K J.

Il est alors évident que JE1 1 E2K

I

JE1 1 E2K

J.

— E est une union E1∪· E2. Raisonnement similaire au point précédent.

Le paragraphe précédent démontre en fait que l’algèbre SPJRU ne permet pas d’encoder des requêtes non-monotones. La notion de monotonicité est définie, de façon générale, comme suit.

(17)

Soit E une expression algébrique relative à un schéma-de-base-de-données R. On dit que E est monotone si la propriété suivante est vérifiée pour toutes bases de données I et J sur R : si

RI ⊆ RJ pour tout R ∈ R, alors

JE K I

JE K

J. Une expression algébrique est non-monotone si

elle n’est pas monotone.

Proposition 2. Chaque requête de l’algèbre SPJRU (i.e., l’algèbre sans la différence) est

monotone.

La Proposition 2 explique pourquoi la requête “Quels buveurs sont exigeants ?” de la section 3.3 a besoin de la différence. Supposons un buveur b qui est exigeant selon la base de données actuelle. Insérons ensuite dans la relation ABUS un tuple qui associe à b un vin de qualité C. Dans la nouvelle base de données, le buveur b ne sera plus exigeant. Ce scénario montre que la requête “Quels buveurs sont exigeants ?” est non-monotone, et donc pas exprimable en SPJRU.

3.6 Fermeture transitive

Voir chapitre 1 pour la définition de fermeture transitive. Il est connu [1, page 436] qu’il n’existe pas de requête en SPJRUD qui calcule la fermeture transitive d’une relation binaire. Cependant, l’algèbre permet de tester si une relation binaire est transitive. Soit R un nom de relation avec sorte(R) = {A, B}. Soit

E1 := πAB(ρB7→C(R) 1 ρA7→C(R)).

L’expression E1 rend un tuple {(A, a), (B, b)} dès que la base de données contient deux tuples

comme suit : R A B a c c b ... ... . L’expression E2 := π{}(E1− R)

teste si E1 contient un tuple qui n’est pas dans R. Si c’est le cas, la relation R n’est pas transitive.

Si E2 retourne la relation vide, la relation R est transitive. Noter que selon l’encodage de true

et false expliqué dans la section 3.3, la requête E2 demande en fait “Est-ce que la relation R

n’est pas transitive ?”.

3.7 La perspective “Unnamed”

Dans cette section, on définit l’algèbre relationnelle dans la perspective “Unnamed”. Un exercice intéressant est de démontrer que cette algèbre a exactement la même expressivité que l’algèbre SPJRUD.

3.7.1 Syntaxe

(18)

Noms de relation Chaque nom de relation R dans R est une expression algébrique d’arité

arit´e(R).

Sélection “attribut égal constante” Si E est une expression algébrique d’arité n, 1 ≤

i≤ n, et a une constante, alors σi=“a”(E) est une expression algébrique d’arité n.

Sélection “attribut égal attribut” Si E est une expression algébrique d’arité n et 1 ≤

i, j≤ n, alors σi=j(E) est une expression algébrique d’arité n.

Projection Si E est une expression algébrique d’arité n et 1 ≤ i1, i2, . . . , ik ≤ n, alors

πi1,i2,...,ik(E) est une expression algébrique d’arité k.

Produit cartésien Si E et F sont des expressions algébriques d’arités m en n,

respective-ment, alors E × F est une expression algébrique d’arité m + n.

Union Si E et F sont deux expressions algébriques de même arité n, alors E ∪· F est une

expression algébrique d’arité n.

Différence Si E et F sont deux expressions algébriques de même arité n, alors E − F est

une expression algébrique d’arité n.

3.7.2 Sémantique

Soit I une base de données sur R. La définition deJE K

I est comme suit :

— Si R est un nom de relation, alorsJRK

I = RI.Jσi=“a”(E)K I = {ha 1, a2, . . . , ani ∈JE K I | ai= a}.Jσi=j(E)K I = {ha 1, a2, . . . , ani ∈JE K I | a i= aj}. — Jπi1,i2,...,ik(E)K I = {ha i1, ai2, . . . , aiki | ha1, a2, . . . , ani ∈JE K I}.JE × F K I = {ha 1, a2, . . . , am, b1, b2, . . . , bni | ha1, . . . , ami ∈JE K I,hb 1, . . . , bni ∈JF K I}.JE ∪· FK I = JE K I JF K

I, où ∪ est l’union ensembliste.

JE − F K

I = JE K

I

\JF K

I, où \ est la différence ensembliste.

3.7.3 Exemple

La requête E3 retourne les buveurs exigeants :

E1 := π1,6(σ2=43=5(ABUS 1 VINS)))

E2 := π1(E1\ σ2=“A”(E1))

E3 := π1(ABUS) − E2

Noter que la projection permet de permuter et de dupliquer des colonnes. Par exemple,

R 1 2 a b c d π2,1,1(R) 1 2 3 b a a d c c

(19)

Chapitre 4

Le Calcul Relationnel

Le calcul relationnel sera introduit dans la perspective “Unnamed”. L’idée est d’utiliser la logique du premier ordre pour interroger une base de données. Prenons la requête “Quels buveurs sont exigeants ?” introduite dans la section 3.3. En calcul relationnel, cette requête peut être encodée comme suit :

{b | ∀c∀m (ABUS(b, c, m) → VINS(c, m, “A”)) partie gauche

∧ ∃c0∃m0ABUS(b, c0, m0)

partie droite

}.

La partie droite de la conjonction vérifie que b est bien un buveur (et pas, par exemple, une cafetière). La partie gauche de la conjonction vérifie que chaque vin bu par b est bien de qualité A.

Notez dés le début l’importance de la partie droite. Substituons b par la valeur “Senseo”.1

Comme Senseo n’est pas un buveur, la prémisse ABUS(“Senseo”, c, m) de l’implication sera

fausse pour tout c et m. Mais alors la partie gauche de la conjonction est vraie !2 La partie droite

de la conjonction joue le rôle de garde-fou : puisque ∃c0∃m0ABUS(“Senseo”, c0, m0) est fausse, la

conjonction sera finalement fausse.

4.1 Syntaxe

Supposons un nombre infini de variables x, y, z, x1, y1, z1. . .3 Aucune variable n’appartient à

dom. Soit R un schéma-de-base-de-données.

— Chaque variable x est un terme.

— Chaque constante c ∈ dom est un terme.

— Si e1 et e2 sont des termes, alors e1 = e2 est une formule (atomique).

— Si R est un nom de relation d’arité k, et e1, . . . , ek son des termes, alors R(e1, . . . , ek) est

une formule (atomique).

— Si ϕ1 et ϕ2 sont des formules, alors ϕ1∧ ϕ2, ϕ1∨ ϕ2 et ¬ϕ1 sont des formules.

1. Senseo est une marque de cafetière.

2. Rappelez-vous : si la prémisse d’une implication est fausse, l’implication est vraie, quel que soit le conséquent ! 3. Pour des raisons de lisibilité, on utilise parfois des variables b, c, m pour dénoter, respectivement, des buveurs,

(20)

— Si ϕ est une formule et x une variable, alors ∃xϕ et ∀xϕ sont des formules.

L’expression ϕ → ψ est une abréviation pour ¬ϕ ∨ ψ. L’expression ϕ ↔ ψ est une abréviation pour (ϕ → ψ) ∧ (ψ → ϕ).

L’ensemble des variables libres d’une formule ϕ, dénoté par free(ϕ), est défini comme suit :

— free(e1 = e2) = {e1, e2} \ dom ;

— free(R(e1, . . . , ek)) = {e1, . . . , ek} \ dom ;

— free(ϕ1∧ ϕ2) = free(ϕ1∨ ϕ2) = free(ϕ1) ∪ free(ϕ2) ;

— free(¬ϕ1) = free(ϕ1) ;

— free(∃xϕ) = free(∀xϕ) = free(ϕ) \ {x}.

Si free(ϕ) = {x1, . . . , xk}, on écrira ϕ(x1, . . . , xk).

4.2 Sémantique

La définition mathématique de la sémantique peut sembler plutôt rébarbative. Pourtant, rien n’est plus logique que la logique elle-même ,. Soit I une base de données sur R. Intuitivement,

une formule R(a1, . . . , ak) est vraie si ha1, . . . , aki ∈ RI; a = a est vraie et a = b est fausse ;

ϕ1∧ ϕ2 est vraie si ϕ1 est vraie et ϕ2 est vraie ; ϕ1∨ ϕ2 est vraie si ϕ1 est vraie ou ϕ2 est vraie ;

¬ϕ1 est vraie si ϕ1 n’est pas vraie ; ∃xϕ(x) est vraie s’il existe une valeur pour x qui rend ϕ

vraie ; ∀xϕ(x) est vraie si ϕ est vraie pour toute valeur de x.

De façon plus formelle, le domaine actif d’une base de données I, dénoté par adom(I), est l’ensemble de toutes les constantes qui apparaissent dans I.

Soit I une base de données sur le schéma-de-base-de-données R. Fixons un domaine d’interpré-tation d tel que

adom(I) ⊆ d ⊆ dom. (4.1)

On définit, pour chaque formule ϕ(x1, . . . , xk) et ha1, . . . , aki ∈ dk, la notion de

I, d |= ϕ(a1, . . . , ak),

qui exprime que ϕ(a1, . . . , ak) est vraie dans I, relatif au domaine d’interprétation d. On écrira

~xet ~a pour respectivement hx1, . . . , xki et ha1, . . . , aki.

Le tuple ~a donne lieu à une valuation ν : d∪{x1, . . . , xn} → d telle que pour chaque i ∈ {1, . . . , n},

ν(xi) = ai et pour chaque c ∈ d, ν(c) = c. Intuitivement, la valeur de xi est ai, et la valeur d’une

constante est la constante elle-même.

— I, d |= t1 = t2 si ν(t1) = ν(t2) ;

— I, d |= R(e1, . . . , ek) si hν(e1), . . . , ν(ek)i ∈ RI;

— si ϕ(~x) ≡ ϕ1(~x) ∧ ϕ2(~x), alors I, d |= ϕ(~a) si I, d |= ϕ1(~a) et I, d |= ϕ2(~a) ;4

— si ϕ(~x) ≡ ϕ1(~x) ∨ ϕ2(~x), alors I, d |= ϕ(~a) si I, d |= ϕ1(~a) ou I, d |= ϕ2(~a) ;

— si ϕ(~x) ≡ ¬ϕ1(~x), alors I, d |= ϕ(~a) si I 6|= ϕ1(~a) ;

4. On suppose ici que free(ϕ1) = free(ϕ2). Noter que l’on peut toujours “introduire” une nouvelle variable libre z dans une formule ϕ en remplaçant ϕ par (z = z) ∧ ϕ.

(21)

— si ϕ(~x) ≡ ∃yψ(y, ~x), alors I, d |= ϕ(~a) s’il existe c ∈ d tel que I, d |= ψ(c,~a) ; — si ϕ(~x) ≡ ∀yψ(y, ~x), alors I, d |= ϕ(~a) si I, d |= ψ(c,~a) pour tout c ∈ d. Une requête en calcul relationnel est une formule

{x1, . . . , xk| ϕ(x1, . . . , xk)}.

La réponse à cette requête contient tout tuple ha1, . . . , aki tel que I, d |= ϕ(a1, . . . , ak).

Une légère extension consiste à permettre que la même variable apparaisse plusieurs fois à gauche de la bar verticale. Par exemple (voir aussi section 3.7.3),

{x1, x2, x2 | R(x2, x1)}.

Noter que le domaine d’interprétation d intervient à trois endroits dans le calcul de la réponse à une requête :

1. les tuples de la réponse sont choisis dans dk;

2. dans le teste I, d |= ∃yψ(y,~a), on cherche la valeur de y dans d ; et

3. dans le teste I, d |= ∀yψ(y,~a), on prend, comme valeur pour y, toute valeur de d. La question qui vient à l’esprit est : “Est-ce que la réponse à une requête peut varier selon le choix de d ?”.

4.3 Indépendance du domaine

Malheureusement, le calcul relationnel défini précédemment a ses défauts. Prenons la re-quête :

{b | ∀c∀m (ABUS(b, c, m) → VINS(c, m, “A”))}. /1

Comme expliqué dans l’introduction de ce chapitre, la formule à droite de la bar verticale est vraie si l’on remplace b par les valeurs “Senseo” ou “Chablis”, qui appartiennent donc à la

réponse, à moins que “Senseo” et “Chablis” soient des valeurs dans d.5 Cette requête dépend

donc du choix du domaine d’interprétation d. En plus, si d est un ensemble infini, la réponse à cette requête sera infinie (parce que chaque base de données est finie).

Prenons une autre requête :

{c | ∀mVINS(c, m, “A”)}. /2

Intuitivement, on cherche les crus qui ont toujours été de qualité A. La réponse est certainement finie, car c doit apparaître dans la table VINS. Cependant, pour chaque cru c, on peut toujours trouver une valeur pour m dans d telle que VINS(c, m, “A”) est faux dans la base de données : il suffit de choisir une valeur qui n’est pas un millésime. Donc, la réponse à cette requête sera toujours vide. Une solution pourrait consister à restreindre le domaine de la variable m a un ensemble fini de millésimes. De nouveau, la réponse dépendrait du domaine choisi, qui ne correspond peut-être pas au domaine envisagé par l’utilisateur qui soumet la requête. En plus, la qualité d’un cru peut manquer pour certaines années. Vu que la base de données de la figure 2.2 n’enregistre pas la qualité du Chablis en 1979, est-il correct de dire que le Chablis a toujours été de qualité A ? Les requêtes suivantes ne posent pas ces défauts, car elles contrôlent elles-même le

(22)

domaine de m. La requête suivante exige que c a été de qualité A dans tout millésime m pour lequel la qualité de c a été enregistré :

{c | ∃m0∃q0VINS(c, m0, q0) ∧ ∀m∀q (VINS(c, m, q) → q = “A”)}.

La requête suivante est plus sévère ; elle exige que c a été de qualité A dans tout millésime m qui apparaît dans la colonne Mill´esime :

{c | ∃m0∃q0VINS(c, m0, q0) ∧ ∀c0∀m∀q VINS(c0, m, q) → VINS(c, m, “A”)}.

Comme déjà illustré par la requête /1, contrairement à ce que l’on pouvait penser, une in-terprétation relative au domaine actif n’est pas toujours naturelle. Soit I la base de données suivante :

R Mod`ele Couleur

Clio bleu

Laguna bleu Laguna rouge

.

Considérons la requête “Quels modèles sont disponibles en chaque couleur ?”. La réponse attendue est {hLagunai}. Prenons la requête :

{m | ∃c0R(m, c0) ∧ ∀cR(m, c)}. /3

Une interprétation relative au domaine actif ne donne pas la bonne réponse : puisque hLaguna, Clioi n’est pas un tuple de R et “Clio” appartient au domaine actif, la sous-formule ∀cR(“Laguna”, c) n’est pas vraie. La bonne requête est :

{m | ∃c0R(m, c0) ∧ ∀m0∀c R(m0, c) → R(m, c)},

ce qui est équivalent à :

{m | ∃c0R(m, c0) ∧ ¬∃m0∃c R(m0, c) ∧ ¬R(m, c)}.

On dira qu’une requête {~x | ϕ(~x)} est indépendante du domaine [d’interprétation] (en anglais : domain independent) si la réponse à la requête ne dépend pas du choix de d que l’on fait dans (4.1). De façon précise, une requête {~x | ϕ(~x)} est indépendante du domaine si pour toute base de

données I, pour tout d1,d2 tels que adom(I) ⊆ d1,d2 ⊆ dom, la réponse relative à d1 est

identique à la réponse relative à d2. En conséquence, la réponse à une requête qui est indépendante

du domaine peut être calculée en prenant adom(I) comme domaine d’interprétation.

Suite aux explications précédentes, on peut conclure que les requêtes /1, /2 et /3 ne sont pas indépendantes du domaine. Voici d’autres exemples de requêtes qui ne sont pas indépendantes du domaine.

Exemple avec disjonction

{x | R(a) ∨ R(b) ∨ R(x)} /4

Soit I1 la base de données suivante :

R A a c

.

On a adom(I1) = {a, c}. L’interprétation relative à {a, c} donne la réponse {hai, hci}. Soit d une

constante telle que d 6∈ {a, c}. L’interprétation relative à {a, c, d} donne la réponse {hai, hci, hdi}. La requête /4 n’est donc pas indépendante du domaine.

(23)

Exemple avec négation

{x | ¬R(x)} /5

Soit I2 la base de donnée suivante :

R A

a .

On a adom(I2) = {a}. L’interprétation relative à {a} donne la réponse vide. L’interprétation

relative à {a, d}, d 6= a, donne la réponse {hdi}.

Exemple avec quantification universelle

{x | ∀yR(x, y)} /6

Soit I3 la base de donnée suivante :

R A B

a a

a b

.

On a adom(I3) = {a, b}. L’interprétation relative à {a, b} donne la réponse {hai}. L’interprétation

relative à {a, b, d} donne la réponse vide, parce que ha, di 6∈ RI3.

4.4 Des requêtes dites safe

La section 4.3 a amplement illustré les défauts des requêtes qui ne sont pas indépendantes du domaine. Désormais, une requête qui n’est pas indépendante du domaine sera considérée comme erronée. Malheureusement, il est connu [1, Corollary 6.3.2] qu’il n’existe pas d’algorithme qui prend en entrée une requête en calcul relationnel et qui détermine si, oui ou non, cette requête est indépendante du domaine (voir section 4.5).

La solution consistera à imposer des restrictions syntaxiques qui garantissent l’indépendance du domaine. Ces restrictions peuvent prendre différentes formes. On introduit ici des restrictions qui sont directement inspirées sur l’algèbre relationnelle.

La notion de variable libre reste inchangée et n’est pas répétée ci-après.

Nom de relation Si R est un nom de relation d’arité n, et x1, . . . , xn sont des variables

dis-tinctes, alors R(x1, . . . , xn) est une formule safe (atomique). La restriction que x1, . . . , xn

soient distinctes fait que chaque variable correspond à exactement un attribut de sorte(R).

Sélection Si ϕ est une formule safe, a est une constante, et x, y ∈ free(ϕ), alors ϕ∧(x = “a”)

et ϕ ∧ (x = y) sont des formules safe.

Projection Si ϕ est une formule safe et x ∈ free(ϕ), alors ∃xϕ est une formule safe. Jointure Si ϕ1 et ϕ2 sont des formules safe, alors ϕ1∧ ϕ2 est une formule safe.

Union Si ϕ1 et ϕ2 sont des formules safe avec free(ϕ1) = free(ϕ2), alors ϕ1∨ ϕ2 est une

formule safe. La restriction que ϕ1 et ϕ2 aient exactement les mêmes variables libres

provient de la restriction que l’union E1∪·E2 est seulement définie si sorte(E1) = sorte(E2).

Noter que la formule dans /4 n’est donc pas safe.

Différence Si ϕ1 et ϕ2 sont des formules safe avec free(ϕ1) = free(ϕ2), alors ϕ1∧ ¬ϕ2 est

une formule safe. La restriction que ϕ1 et ϕ2 aient exactement les mêmes variables libres

provient de la restriction que la différence E1− E2 est seulement définie si sorte(E1) =

(24)

Une requête {~x | ϕ(~x)} est safe si la formule ϕ(~x) est safe. Dénotons par SRC (Safe Relational Calculus) la restriction du calcul relationnel aux formules et requêtes safe.

Un exercice intéressant est de démontrer les résultats suivants (voir aussi les transparents) : — Chaque requête en SPJRUD est équivalente à une requête en SRC.

— Chaque requête en SRC est équivalente à une requête en SPJRUD.

— Chaque requête en SRC est indépendante du domaine (une conséquence des deux assertions qui précèdent).

SRC impose une syntaxe très restrictive aux formules. Malgré ces restrictions, l’assertion suivante est vraie :

— Chaque requête qui est indépendante du domaine est équivalente à une requête en SRC (voir section 4.5).

Bien que les restrictions syntaxiques ne diminuent donc pas pas l’expressivité, elles rendent le langage SRC rébarbatif à utiliser. Par exemple, la requête {x | R(x, x)} doit s’écrire comme {x | ∃y (R(x, y) ∧ x = y)} en SRC. Dans [1, Section 5.4], on trouve des restrictions moins sévères du calcul relationnel qui garantissent aussi l’indépendance du domaine.

4.5 Discussions approfondies

Sur la base de la Proposition 1, on peut facilement prouver qu’il est indécidable de déterminer si, oui ou non, une formule en calcul relationnel est indépendante du domaine. Considérer une requête de la forme :

{~x | ψ(~x) ∧ ¬ (ϕ1 ↔ ϕ2)}, (4.2)

avec ϕ1 et ϕ2 des formules booléennes (i.e., sans variables libres) en SRC, et ψ une formule

en calcul relationnel telle que {~x | ψ(~x)} n’est pas indépendante du domaine. Deux cas sont possibles :

1. Si ϕ1 ≡ ϕ2, alors ¬ (ϕ1↔ ϕ2) est faux, et la requête (4.2) retourne la réponse vide sur

toute base de données, quel que soit le domaine d’interprétation. Dans ce cas, la requête est donc indépendante du domaine.

2. Si ϕ1 6≡ ϕ2, alors ¬ (ϕ1 ↔ ϕ2) est vrai, et la requête (4.2) est équivalente à {~x | ψ(~x)},

une requête qui n’est pas indépendante du domaine.

En conclusion, la requête (4.2) est indépendante du domaine si et seulement si ϕ1 ≡ ϕ2. Mais

on sait, par la Proposition 1, que l’équivalence de ϕ1 et ϕ2 est indécidable. Noter ici que la

Proposition 1 peut être appliquée au langage SRC, car on sait qu’il est possible de “traduire” des requêtes entre SRC et SPJRUD. Il est alors correct de conclure qu’il est indécidable de déterminer si, oui ou non, une formule en calcul relationnel est indépendante du domaine. On explique maintenant pourquoi chaque requête qui est indépendante du domaine est équivalente à une requête en SRC. Noter d’abord qu’il existe une requête {x | α(x)} en SRC qui prend en entrée une base de données et qui retourne son domaine actif. Par exemple, supposons que le schéma-de-base-de-données consiste en deux noms de relations, R et S, chacun d’arité 2. Alors

α(x) est la formule suivante :

α(x) := (∃yR(x, y) ∨ ∃yR(y, x)) ∨ (∃yS(x, y) ∨ ∃yS(y, x)) .

Soit {~x | ψ(~x)} une requête en calcul relationnel qui est indépendante du domaine. La requête en SRC équivalente peut être construite comme suit.

(25)

— Assurer que toute formule atomique respecte les contraintes syntaxiques imposées par SRC. Par exemple, remplacer R(x, “a”) par R(x, y) ∧ (y = “a”) ; remplacer R(x, x) par

R(x, y) ∧ (y = x) ;

— remplacer chaque sous-formule x = “a” de ψ par α(x) ∧ (x = “a”) ; — remplacer chaque sous-formule x = y de ψ par (α(x) ∧ α(y)) ∧ (x = y) ;

— remplacer chaque négation ¬ϕ(x1, . . . , xn) par (α(x1) ∧ · · · ∧ α(xn)) ∧ ¬ϕ(x1, . . . , xn) ;

— assurer que les parties gauche et droite d’une disjonction aient les mêmes variables libres.

Par exemple, remplacer ϕ1(x, y) ∨ ϕ2(y, z) par (ϕ1(x, y) ∧ α(z)) ∨ (ϕ2(y, z) ∧ α(x)).

On peut vérifier que ces étapes aboutissent à une requête en SRC qui donne les mêmes réponses que {~x | ψ(~x)} avec, comme domaine d’interprétation, le domaine actif. Comme {~x | ψ(~x)} est indépendante du domaine, une interprétation relative au domaine actif retourne, par définition, la réponse correcte.

4.6 Le calcul relationnel TRC

Dans le calcul introduit précédemment, les variables représentent des valeurs de dom. On introduit maintenant brièvement une variante du calcul relationnel dans lequel les variables représentent des tuples. Dans la littérature, on utilise souvent les dénotations DRC et TRC pour distinguer ces deux approches :

Domain Relational Calculus (DRC) : Les variables représentent des valeurs. Tuple Relational Calculus (TRC) : Les variables représentent des tuples.

4.6.1 TRC par l’exemple

Prenons le suivant schéma-de-bases-de-données, pris du livre [7] : S[S], Sname, Status, City]

P[P], Pname, Color, Weight, City] SP[S], P], Qty]

Les tables S et P enregistrent respectivement des fournisseurs et des produits. La table SP enregistre quel fournisseur sait fournir quel produit, et en quelle quantité. Chaque quantité est en nombre entier strictement positif.

Requête 7.7.4

Trouver tout couple de villes tel qu’un fournisseur habitant la première ville sait fournir un produit stocké dans la deuxième ville.

La requête en SQL :

SELECT s.City, p.City

FROM S AS s, SP AS r, P AS p WHERE s.S]= r.S] AND r.P]= p.P] ; La requête en SRC : {s.4, p.5 | S(s) ∧ P(p) ∧ ∃r (SP(r) ∧ s.1 = r.1 ∧ r.2 = p.1)}

(26)

Pour améliorer encore la lisibilité, on remplace les indices par les attributs : {s.City, p.City | S(s) ∧ P(p) ∧ ∃r (SP(r) ∧ s.S] = r.S] ∧ r.P] = p.P])}

{s.City, p.City | ∃r (S(s) ∧ P(p) ∧ SP(r) ∧ s.S] = r.S] ∧ r.P] = p.P])} Remarquer que cette dernière requête en TRC est très proche de la requête en SQL.

Requête 7.7.15

Trouver les noms de fournisseurs qui savent fournir tout produit rouge. En SQL :

SELECT s.Sname FROM S AS s

WHERE NOT EXISTS ( SELECT * FROM P AS p

WHERE p.Color = “red”

AND NOT EXISTS ( SELECT * FROM SP AS r WHERE r.S]= s.S] AND r.P]= p.P] ) ) ; En SRC : {s.2 | S(s) ∧ ∀p ∈ P (p.3 = “red” → ∃r ∈ SP (r.1 = s.1 ∧ r.2 = p.1))}{s.2 | S(s) ∧ ¬∃p ∈ P (p.3 = “red” ∧ ¬∃r ∈ SP (r.1 = s.1 ∧ r.2 = p.1))} Avec les attributs :

{s.Sname | S(s) ∧ ∀p ∈ P (p.Color = “red” → ∃r ∈ SP (r.S] = s.S] ∧ r.P] = p.P]))}

{s.Sname | S(s) ∧ ¬∃p ∈ P (p.Color = “red” ∧ ¬∃r ∈ SP (r.S] = s.S] ∧ r.P] = p.P]))}

4.6.2 Syntaxe

Formules On suppose des variables r, s, t, . . . , et une fonction qui fait correspondre, à chaque

variable, une arité dans {0, 1, 2, . . .}.

— Chaque constante c ∈ dom est un terme.

— Si t est une variable d’arité n et i ∈ {1, 2, . . . , n}, alors t.i est un terme.

— Si e1 et e2 sont des termes, alors e1 = e2 est une formule (atomique).

— Si R est un nom de relation et r une variable de même arité que R, alors R(r) est une formule (atomique).

— Si ϕ1 et ϕ2 sont des formules, alors ϕ1∧ ϕ2, ϕ1∨ ϕ2 et ¬ϕ1 sont des formules.

(27)

Requêtes Une requête est une expression de la forme

{L | ϕ} avec L une liste de termes et ϕ une formule telles que

— pour chaque terme r.i dans L, la variable r est une variable libre de ϕ ; et — chaque variable libre de ϕ apparaît dans un terme de L.

Abréviations On introduit un nombre d’abréviations :

— ϕ1→ ϕ2 est une abréviation de ¬ϕ1∨ ϕ2;

— ∃r ∈ R (ϕ) est une abréviation de ∃r (R(r) ∧ ϕ) ; — ∀r ∈ R (ϕ) est une abréviation de ∀r (R(r) → ϕ) ;

— u1 6= u2 est une abréviation de ¬ (u1 = u2).

Noter que ces abréviations sont cohérentes :

∀r ∈ R (ϕ) ≡ ¬¬∀r ∈ R (ϕ) (logique : ¬¬p ≡ p) ≡ ¬¬∀r (R(r) → ϕ) (abréviation) ≡ ¬∃r¬ (¬R(r) ∨ ϕ) (logique : ¬∀rψ ≡ ∃r¬ψ et p → q ≡ ¬p ∨ q) ≡ ¬∃r (R(r) ∧ ¬ϕ) (De Morgan) ≡ ¬∃r ∈ R (¬ϕ) (abréviation) 4.6.3 Sémantique

La sémantique du TRC peut être définie de façon rigoureuse, comme on l’a fait pour le DRC dans la section 4.2. Ici, on se contente de donner, de façon informelle, les différences avec le calcul TRC.

Soit I une base de données et d un domaine d’interprétation.

— Une variable d’arité n prend ses valeurs dans dn (et non dans d).

— R(r) est vrai si le tuple r appartient à la relation RI.

— ∃rϕ est vrai s’il existe un tuple r ∈ dn qui rend ϕ vrai, avec n l’arité de r.

— ∀rϕ est vrai si pour tout tuple r ∈ dn, ϕ est vrai, avec n l’arité de r.

Dans le calcul TRC, comme dans le calcul DRC, certaines requêtes ne sont pas indépendantes du domaine :

{r.1 | R(r) ∨ ∃s (S(s))}; /

{r.1 | ¬R(r)}. /

SQL est un mixe de l’algèbre relationnelle et le calcul TRC. Par exemple, pour un schéma-de-bases-de-données qui contient R[A] et S[B], la requête TRC {r.1 | R(r) ∨ S(r)} donne lieu à une union en SQL. Noter aussi qu’il serait illogique de vouloir remplacer, dans cette requête TRC, l’indice 1 par un attribut (A ou B).

(28)

4.6.4 Du TRC au SQL

Prenons la requête :

Donner des couples (n1, n2) de noms de fournisseurs tels que les produits fournis

par n1 sont un sous-ensemble des produits fournis par n2.

Il est difficile d’encoder cette requête directement en SQL. En TRC : {s1.2, s2.2 | S(s1) ∧ S(s2) ∧ ∀r1 ∈ SP (r1.1 = s1.1 → ∃r2∈ SP (r2.1 = s2.1 ∧ r2.2 = r1.2))} ≡ {s1.2, s2.2 | S(s1) ∧ S(s2) ∧ ¬∃r1∈ SP (r1.1 = s1.1 ∧ ¬∃r2 ∈ SP (r2.1 = s2.1 ∧ r2.2 = r1.2))}

Avec les attributs :

{s1.Sname, s2.Sname| S(s1) ∧ S(s2) ∧ ∀r1∈ SP (r1.S]= s1.S]→ ∃r2 ∈ SP (r2.S]= s2.S]∧ r2.P]= r1.P]))} ≡ {s1.Sname, s2.Sname| S(s1) ∧ S(s2) ∧ ¬∃r1∈ SP (r1.S]= s1.S]∧ ¬∃r2∈ SP (r2.S]= s2.S]∧ r2.P]= r1.P]))} La traduction en SQL :

SELECT s1.Sname, s2.Sname FROM S AS s1, S AS s2

WHERE NOT EXISTS ( SELECT *

FROM SP AS r1 WHERE r1.S] = s1.S]

AND NOT EXISTS ( SELECT *

FROM SP AS r2 WHERE r2.S] = s2.S]

(29)

Chapitre 5

SQL

Le langage SQL fera l’objet des Travaux Pratiques. Ce chapitre n’est qu’une brève introduction. La bases de données et les requêtes sont reprises de [7].

5.1 La base de données

S S# SNAME STATUS CITY S1 Smith 20 London S2 Jones 10 Paris S3 Blake 30 Paris S4 Clark 20 London S5 Adams 30 Athens

P P# PNAME COLOR WEIGHT CITY P1 Nut Red 12 London P2 Bolt Green 17 Paris P3 Screw Blue 17 Rome P4 Screw Red 14 London P5 Cam Blue 12 Paris P6 Cog Red 19 London SP S# P# QTY S1 P1 300 S1 P2 200 S1 P3 400 S1 P4 200 S1 P5 100 S1 P6 100 S2 P1 300 S2 P2 400 S3 P2 200 S4 P2 200 S4 P4 300 S4 P5 400

5.2 Création de domaines et de tables

CREATE DOMAIN COLOR CHAR(6) DEFAULT ‘???’ CONSTRAINT VALID_COLORS

CHECK ( VALUE IN

( ‘Red’, ‘Yellow’, ‘Blue’, ‘Green’, ‘???’ ) ) ;

(30)

CREATE DOMAIN QTY NUMERIC(9) ; CREATE TABLE S ( S# S#, SNAME NAME, STATUS STATUS, CITY CITY, PRIMARY KEY ( S# ) ) ; CREATE TABLE P ( P# P#, PNAME NAME, COLOR COLOR, WEIGHT WEIGHT, CITY CITY, PRIMARY KEY ( P# ) ) ; CREATE TABLE SP

( S# S# NOT NULL, P# P# NOT NULL, QTY QTY NOT NULL, PRIMARY KEY ( S#, P# ),

FOREIGN KEY ( S# ) REFERENCES S ON DELETE CASCADE ON UPDATE CASCADE, FOREIGN KEY ( P# ) REFERENCES P

ON DELETE CASCADE ON UPDATE CASCADE, CHECK ( QTY > 0 AND QTY < 5001 ) ) ;

5.3 Retrouver des informations

Get color and city for “nonParis” parts with weight greater than 10.

SELECT P.COLOR, P.CITY

FROM P

WHERE P.CITY <> ‘Paris’

AND P.WEIGHT > 10 ;

SELECT DISTINCT P.COLOR, P.CITY

FROM P

WHERE P.CITY <> ‘Paris’

AND P.WEIGHT > 10 ;

SELECT DISTINCT P.COLOR, P.CITY

FROM P

WHERE P.CITY <> ‘Paris’

AND P.WEIGHT > 10

(31)

For all parts, get the part number and the weight of that part in grams. Supposons

que le poids est donné en livre (=454 g). SELECT P.P#, P.WEIGHT * 454 AS GMWT

FROM P ;

Get full details of all suppliers.

SELECT *

FROM S ;

SELECT S.*

FROM S ;

Get all combinations of supplier number and part number such that the supplier and part in question are colocated.

SELECT S.S#, P.P#

FROM S, P

WHERE S.CITY = P.CITY ;

Sémantique. Premièrement, “FROM S, P” donne le produit cartésien de S et P.

S.S# S.SNAME S.STATUS S.CITY P.P# P.PNAME P.COLOR P.WEIGHT P.CITY

S1 Smith 20 London P1 Nut Red 12 London

S1 Smith 20 London P2 Bolt Green 17 Paris

S1 Smith 20 London P3 Screw Blue 17 Rome

S1 Smith 20 London P4 Screw Red 14 London

S1 Smith 20 London P5 Cam Blue 12 Paris

S1 Smith 20 London P6 Cog Red 19 London

S2 Jones 10 Paris P1 Nut Red 12 London

S2 Jones 10 Paris P2 Bolt Green 17 Paris

S2 Jones 10 Paris P3 Screw Blue 17 Rome

S2 Jones 10 Paris P4 Screw Red 14 London

S2 Jones 10 Paris P5 Cam Blue 12 Paris

S2 Jones 10 Paris P6 Cog Red 19 London

. . .

S5 Adams 30 Athens P6 Cog Red 19 London

Deuxièmement, “WHERE S.CITY = P.CITY” sélectionne les tuples satisfaisant la condition. S.S# S.SNAME S.STATUS S.CITY P.P# P.PNAME P.COLOR P.WEIGHT P.CITY

S1 Smith 20 London P1 Nut Red 12 London

S1 Smith 20 London P4 Screw Red 14 London

S1 Smith 20 London P6 Cog Red 19 London

S2 Jones 10 Paris P2 Bolt Green 17 Paris

S2 Jones 10 Paris P5 Cam Blue 12 Paris

. . .

Finalement, “SELECT S.S#, P.P#” sélectionne (ou plutôt : projette) les colonnes mention-nées. S# P# S1 P1 S1 P4 S1 P6 S2 P2 S2 P5 . . .

(32)

Get all pairs of city names such that a supplier located in the first city supplies a part stored in the second city.

SELECT S.CITY, P.CITY

FROM S, SP, P

WHERE S.S# = SP.S#

AND SP.P# = P.P# ;

Get the total number of suppliers.

SELECT COUNT(*) AS N

FROM S ;

Get the maximum and the minimum quantity for part P2.

SELECT MAX ( SP.QTY ) AS MAXQ, MIN ( SP.QTY ) AS MINQ

FROM SP

WHERE SP.P# = ‘P2’ ;

For each part supplied, get the part number and the total shipment quantity.

SELECT SP.P#, SUM ( SP.QTY ) AS TOTQTY

FROM SP

GROUP BY SP.P# ;

Sémantique. Premièrement, imaginons que “FROM SP GROUP BY SP.P#” donne la “table”

sui-vante. {S#} P# {QTY} {S1, S2} P1 {300, 300} {S1, S2, S3, S4} P2 {200, 400, 200, 200} {S1} P3 {400} {S1, S4} P4 {200, 300} {S1, S4} P5 {100, 400} {S1} P6 {100}

Finalement, “SELECT SP.P#, SUM ( SP.QTY ) AS TOTQTY” donne : P# TOTQTY P1 600 P2 1000 P3 400 P4 500 P5 500 P6 100

SELECT P.P#, ( SELECT SUM ( SP.QTY )

FROM SP

WHERE SP.P# = P.P# ) AS TOTQTY

(33)

Get part number for all parts supplied by more than one supplier.

SELECT SP.P#

FROM SP

GROUP BY SP.P#

HAVING COUNT ( SP.S# ) > 1 ;

Get supplier names for suppliers who supply part P2.

SELECT DISTINCT S.SNAME

FROM S

WHERE S# IN

( SELECT SP.S#

FROM SP

WHERE SP.P# = ‘P2’ ) ; SELECT DISTINCT S.SNAME

FROM S WHERE EXISTS ( SELECT * FROM SP WHERE SP.P# = ‘P2’ AND SP.S# = S.S# ) ;

SELECT DISTINCT S.SNAME

FROM S, SP

WHERE S.S# = SP.S#

AND SP.P# = ‘P2’ ;

Get supplier numbers for suppliers with status less than the current maximum status in the S table.

SELECT S.S#

FROM S

WHERE S.STATUS <

( SELECT MAX ( S.STATUS )

(34)

Get supplier names for suppliers who do not supply part P2.

SELECT DISTINCT S.SNAME

FROM S

WHERE S# NOT IN ( SELECT SP.S#

FROM SP

WHERE SP.P# = ‘P2’) ; SELECT DISTINCT S.SNAME

FROM S

WHERE NOT EXISTS ( SELECT *

FROM SP

WHERE SP.P# = ‘P2’

AND SP.S# = S.S# ) ;

Get supplier names for suppliers who supply all red parts.

SELECT S.SNAME

FROM S

WHERE NOT EXISTS ( SELECT *

FROM P

WHERE P.COLOR = ‘Red’

AND NOT EXISTS

( SELECT *

FROM SP

WHERE SP.S# = S.S#

AND SP.P# = P.P# ) ) ;

Get part numbers for parts that either weigh more than 16 pounds or are supplied by supplier S2, or both. SELECT P.P# FROM P WHERE P.WEIGHT > 16 UNION SELECT SP.P# FROM SP WHERE SP.S# = ‘S2’ ;

5.4 Mises à jour

Single-row INSERT. INSERT

INTO P ( P#, PNAME, COLOR, WEIGHT, CITY )

(35)

Multi-row INSERT.

INSERT

INTO TEMP ( S#, CITY )

SELECT S.S#, S.CITY

FROM S

WHERE S.STATUS > 15 ;

Multi-row UPDATE.

UPDATE P

SET COLOR = ‘Yellow’,

WEIGHT = P.WEIGHT + 5 WHERE P.CITY = ‘Paris’ ;

Multi-row UPDATE.

UPDATE P

SET CITY = ( SELECT S.CITY

FROM S

WHERE S.S# = ‘S5’ ) WHERE P.COLOR = ‘Red’ ;

Multi-row DELETE. DELETE FROM SP WHERE ‘London’ = ( SELECT S.CITY FROM S WHERE S.S# = SP.S# ) ;

5.5 Intégration de SQL à des langages de programmation

EXEC SQL DECLARE X CURSOR FOR

SELECT S.S#, S.SNAME, S.STATUS

FROM S

WHERE S.CITY = :Y ;

EXEC SQL OPEN X ; /* execute the query */

EXEC SQL FETCH X INTO :V1, :V2, :V3 ; /* fetch the first row (if any) */

WHILE a row is fetched LOOP

... /* process the row */

EXEC SQL FETCH X INTO :V1, :V2, :V3 ; /* fetch the next row (if any) */ END-LOOP

(36)

5.6 Vues

5.6.1 Définition des Vues

Une vue est une table virtuelle dont le schéma et le contenu sont dérivés de la base réelle par un ensemble de requêtes.

CREATE VIEW REDPARTS ( P#, PNAME, WT, CITY ) AS SELECT P.P#, P.PNAME, P.WEIGHT, P.CITY

FROM P

WHERE P.COLOR = ‘Red’ ; CREATE VIEW PQ

AS SELECT SP.P#, SUM ( SP.QTY ) AS TOTQTY

FROM SP

GROUP BY SP.P# ;

5.6.2 Interrogation au travers de vues Get red parts that weigh more than 15 pounds.

SELECT P# FROM REDPARTS WHERE WT > 15 ; ⇔ SELECT P# FROM P WHERE WEIGHT > 15

AND COLOR = ‘Red’ ;

5.6.3 Mise à jour au travers de vues

UPDATE REDPARTS

SET WT = 454 * WT ;

UPDATE P

SET WEIGHT = 454 * WEIGHT

WHERE COLOR = ‘Red’ ; UPDATE PQ

SET TOTQTY = TOTQTY + 1 ;

UPDATE SP

(37)

Chapitre 6

Les Dépendances Fonctionnelles

6.1 Introduction

La table suivante enregistre l’horaire du premier quadrimeste. Le premier tuple, par exemple, indique qu’une séance du cours de Physique I aura lieu chaque lundi à 8H15 ; le titulaire de ce cours est le professeur Albert Einstein.

Prof Cours Heure

Albert Einstein Physique I lundi, 8H15

Albert Einstein Physique I mercredi, 10H15

Albert Einstein Méchanique quantique lundi, 10H15

Marie Curie Chimie II lundi, 8H15

Les deux contraintes suivantes doivent être respectées à chaque instant : — Chaque cours n’a qu’un seul titulaire.

— Aucun professeur ne peut enseigner deux cours distincts à une même plage horaire. Par exemple, on ne peut pas déplacer le cours de Physique I du “lundi, 8H15” au “lundi, 10H15”, car ce déplacement engendrait un conflit horaire pour Albert Einstein.

Ces contraintes seront appelées des dépendances fonctionnelles, et dénotées comme suit :

Cours→ Prof : À chaque cours ne peut correspondre qu’un seul professeur.

Prof, Heure→ Cours : À chaque combinaison d’un professeur et une plage horaire ne peut

correspondre qu’un seul cours.

Noter qu’en conséquence, à chaque combinaison d’un cours et plage horaire ne peut correspondre qu’un seul professeur : Cours, Heure → Prof.

6.2 Syntaxe et sémantique

Toutes les définitions dans la suite de ce chapitre sont relatives à un schéma-de-relation A.

Syntaxe Une dépendance fonctionnelle (DF) sur A est une expression X → Y avec X, Y ⊆

Références

Documents relatifs

La dernière occupation d’une maison d’époque ptolémaïque du village de Tebtynis (Fayoum).. Une céramique de

‌أ فورظلا بسح كلذ و ةعونتلما ةينفلا و ةيناسنلإا ميقلا نم ديدعلاب ثيدلحا يرئازلجا بدلأا رخزي ب كلذ و رامدتسلاا ءازإ ابه رم تيلا لحارلما و زاربإ نم

III. We first propose the use of CSI ratio between two antennas in the same WiFi card, analyze its properties and verify that it provides better signal measurement than the amplitude

C’est d’ailleurs Nicolas Barthélemy lui-même qui nous y pousse, dans un poème adressé au grand humaniste Érasme en 1532 : « Je suis maître d’un collège monastique, prieur

alcaldes et encomenderos se multiplient également au fur et à mesure que les réseaux de communication se mettent en place, où les autorités locales

Ces matériaux ont été développés suivant trois axes principaux : d’abord l’axe des mouvements, associés aux moyens de transport et aux centres névralgiques

Le texte dit littéraire remodèlerait ainsi, au moyen des merveilloses batailles, un personnage de grand laïc que l’énoncé ecclésiastique disqualifiait à travers,

On croit l’avoir montré, et en avoir trouvé la confirmation chez Hjelmslev : quoique non mis en forme par un terme, le concept de métalangage est au plus haut point présent dans