La conception des bases de données relationnelles
I. Un Exemple pour l’échauffement
On a les données suivantes :
- Ensembles de clients avec un numéro, un nom et une ville.
- Pour chaque client, un ensemble de commandes avec un numéro de commande, un produit commandé (un CD) et une date commande.
Exemple de valeurs :
Clients Commandes
123, Ali, Rabat
<C01, Led Zeppelin, Dec-2015>,
<C02, Doors, Jan-2016>
124, Amina, Casa <C03, Santana, Nov-2015>,
<C04, Pink Floyd, Dec-2015>,
<C05, Led Zeppelin, Oct-2015>
Problème
Comment concevoir des relations ? Mettre ces valeurs dans des tables ? Quelles tables d’abord ?
Solution1
Table Client-Commande1
On met dans une table les attributs d’un client et les commandes. On considère une commande comme un attribut.
NumC NomC Ville Com1 Com2 Com3 Com4
123 Ali
Rabat
"C01, Led Zeppelin, Dec-2015"
"C02, Doors, Jan-
2016"
124
Amina Casa
"C03, Santana, Nov-2015"
"C04, Pink Floyd, Dec-
2015"
"C05, Led Zeppelin, Oct-2015"
Exemple de problèmes :
- On ne peut accéder aux noms des CD commandés ou aux dates commandes.
SELECT (PRODUIT)
FROM Client-Commande1
- On est obligé de supposer un nombre maximum de commande (4 ici)
Solution 1-bis :
Table Client-Commande1-bis
On décompose les champs de commandes pour en faire des attributs de la relation (on élargit la table).
NumC NomC Ville NumCom1 Produit1 Date1 NumCom2 Produit2 Date2 ...
123 Ali Rabat C01 Led Zeppelin Dec-2015 C02 Doors Jan-2016 ...
124 Amina Casa C03 Santana Nov-2015 C04 Pink Floyd Dec-2015 ...
... NumCom3 Produit3 Date3 ...
... - - - ...
... C05 Les Zeppelin Oct-2015
Client-Commande1-bis
... NumCo m4
Produit4 Date4
Exemple de problèmes :
- La Table peut paraître très large.
- On est encore obligé de supposer un nombre maximum de commandes (4 ici) - Beaucoup de valeurs indéfinies (Il n’y a pas toujours 4 commandes)
- Surtout, requête « Nom du Client qui a commandé Doors ?»
SELECT NomC
FROM Client-Commande1 WHERE Produit1= "Doors"
OR Produit2= "Doors"
OR Produit3= "Doors"
OR Produit4= "Doors"
Incommode !
- On ne peut pas, par exemple, calculer la somme ou la moyenne des prix des commandes du client ‘124’
(Imaginer qu’on a aussi le prix des produits commandés dans la table.) - Sauf à faire
SELECT (Prix1 + Prix2 + Prix3) / 3 FROM Client-Commande1-bis
WHERE NumC="124"
Incommode !
Solution 2 :
Table
Client-Commande2
NumCom Produit Date NumC NomC Ville
C01 Led Zeppelin Dec-2015 123 Ali Rabat
C02 Doors Jan-2016 123 Ali Rabat
C03 Santana Nov-2015 124 Amina Casa
C04 Pink Floyd Dec-2015 124 Amina Casa
C05 Led Zeppelin Oct-2015 124 Amina Casa
C06 Genesis Dec-2015 125 Aziza Tanger
On met les commandes d’un même client dans autant de lignes qu’il faut : 2 lignes pour ‘Ali’ et 3 lignes pour
‘Amina’, etc.
On constate que les problèmes précédents ont disparu :
- Pas de limites pour les commandes d’un client - Pas de valeurs indéfinies
- « Nom du Client qui a commandé Doors ?» La valeur ‘Doors’ apparaît dans LA colonne Produit SELECT NomC
FROM Client-Commande2 WHERE Produit= "Doors"
- On peut calculer le nombre de commandes pour un client donné (on ne pouvait pas avant) SELECT count (*)
FROM Client-Commande2 WHERE NumC="124"
- Ou la moyenne des prix. Plus simple cette fois-ci : colonne unique Prix SELECT Avg (Prix)
FROM Client-Commande2 WHERE NumC="124"
- Etc...
Néanmoins, cette table souffre encore de quelques anomalies :
- Redondances : mêmes informations client sur plusieurs lignes - Perte d’espace.
- Risque d’inconsistance. La requête suivante modifie la ville du client qui a fait la commande ‘C01’
UPDATE Client-Comande2 SET Ville = "Casa"
WHERE NumCom = "C01"
La base est dans un état inconsistant. Ali habite quelle ville Casa ou Rabat ?
- Plus encore, supposer qu’on supprime la seule commande faite par un client (par exemple Aziza) DELETE FROM Client-Commande2
WHERE NumCom="C06"
- On a perdu aussi les informations sur le client "Aziza"
- Inversement, on ne peut pas rajouter un nouveau client, qui n’a encore aucune commande.
NumCom Produit Date NumC NomC Ville
? ? ? 125 Aziz Fez
On ne peut avoir NumCom indéfini, car c’’est la clé primaire de la table.
- Etc...
Solution 3 :
Deux tables : une pour les clients
Client
et une pour les commandesCommande
Commande Client
NumCom Produit Date NumC NumC NomC Ville
C01 Led Zeppelin Dec-2015 123 123 Ali Rabat
C02 Doors Jan-2016 123 124 Amina Casa
C03 Santana Nov-2015 124 125 Aziza Tanger
C04 Pink Floyd Dec-2015 124
C05 Led Zeppelin Oct-2015 124
C06 Genesis Dec-2015 125
On constate que les problèmes précédents on disparu. (Vérifiez-le)
II. Récapitulation
“ Dans cette BD, on a deux types d’objets (ou entités). Des clients et des commandes.
On a mis dans une table séparée les informations qui se rapportent à un type d’entité
bien identifié ”
Règles simples :
1. Chaque type d’entité doit être représenté par une table.
2. La clé primaire d’une table est l’identifiant du type d’entité.
3. Les champs d’une table sont constitués des autres propriétés du type d’entité.
Mais les types d’entités ne sont pas indépendants. Il y a une « relation » c’est-à-dire une association (ang.
relationship) entre les clients et les commandes : un client fait des commandes. Dans cet exemple, la relation est de type 1-M (1-à-plusieurs) entre clients et commandes. Un client fait plusieurs (0, 1 ou n) commandes, et une commande est faite par un seul client. Autrement dit, la relation est une fonction entre l’ensemble des
commandes et l’ensemble des clients.
Commande Type d’association M-1
Client C01
C02 C03 C04 C05 ...
123 124 ...
Pour représenter cette association dans la base de données, l’identifiant de client (partie-1 de l’association) est à rajouter comme champs dans la table commande (partie-M de l’association)
4. Pour chaque association, l’identifiant du type d’entité partie-1 est à rajouter comme champs dans la table correspondant au type d’entité partie-M.
Commande
NumCom Produit Date NumC
Client
NumC NomC Ville
Autre exemple : cas de relation M-M
Considérons maintenant la base de donnée sur les livres de prêt les abonnés. Ici, le type d’association entre un abonné et un livre est de type plusieurs à plusieurs (M-M). Un livre peut être emprunté par plusieurs abonnés, et un abonné peut emprunter plusieurs livres.
Livre Type d’association M-M
Abonné L01
L02 L03 L04 L05 ...
A13 A24 A45 ...
Dans ce cas, les règle 1 à 3 sont les mêmes, on a une table par type d’entité, donc une table Livre et une table Abonné
Livre
NumInv Titre Auteur Qte
Abonne
NumAb Nom Prénom
Pour la relation de prêt entre un abonné et un livre, on crée une autre table avec comme champs : - les identifiants des types d’entités associés,
- tout autre champs qui dépends des deux entités, comme la date de prêt ici.
Pret
NumInv NumAb DatePret
D’où la règle 4’
4'. Pour chaque association M-M, rajouter une table avec les identifiants des types d’entité associés et tout autre attribut qui dépend de ces deux types d’entités pris ensemble. La clé primaire de cette table est la combinaison des deux identifiants.
III. Formalisation.
On va maintenant développer quelques propriétés formelles de ces tables bien conçues.
III.1. Notion de dépendance fonctionnelle.
Soit R une relation avec les attributs A, B et C.
R (A, B, C)
Définition : On dit qu’il y a une Dépendance Fonctionnelle entre les attributs A et B si la projection de R [A, B] est une fonction de A vers B, notée
A à B
On dit aussi que A détermine B, i.e. si on connaît la valeur de A dans R, on peut connaître aussi la valeur de B.
Exemple :
R
A B C a
a c g
e e b e
b c d f
Ici, A détermine B, A à B, mais ne détermine pas C (A -/-> C). On peut aussi constater que C à B et C à A.
Proposition : Dans une relation, la clé primaire détermine tous les autres attributs.
Cela découle du fait que la valeur de la clé identifie un tuple. Donc, les autres composants du tuple. Dans la relation Client (NumC, NomC, Ville), on a :
III.2. Ce qu’est une bonne relation
Définition : Une relation R est dite normalisée, ou en 3e Forme Normale, si toutes les dépendances fonctionnelles qu’elle porte, sont celles dues à la clé (d’après la proposition qui précède).
Les relations :
Client (NumC, NomC, Ville)
Commande (NumCom, Produit, Date, NumC)
Sont en 3e FN, car on a :
NumC à NomC, Ville
NumCom à Produit, Date, NumC Et il n’y a aucune autre DF.
III.3. Relation moins bonne
La relation
Client-Commande2 (NumCom, Produit, Date, NumC, NomC, Ville)
N’était pas en 3e FN, car il y a NumC àNomc, Ville dans cette relation, et NumC n’est pas clé de la relation.
On dit que cette relation Client-Commande2, est en 2e Forme Normale (2FN). Des attributs non clés (e.g. NumC et NomC) sont fonctionnellement dépendants.
Résultat : Une relation en 2FN, peut toujours être décomposée (projetée) en relations en 3FN.
Commande = Project ( Client-Commande2, NumCom, Produit, Date, NumC) Client = Project ( Client-Commande2 , NumC, NomC, Ville)
Remarquer les attributs de projection. On a mis dans une table à part, table Client, les attributs Dfs, NumC -->
Nomc, Ville, qui rendait la table Client-Commande2, non en 3FN. La clé de cette table est alors la partie droite (NumC) de la DF. Noter aussi qu’on a gardé ce même attribut NumC, dans la l’autre relation, pour pouvoir faire la jointure et retrouver les informations initiales :
Client-Commande2 = Join ( Client, Commande, Client.NumC = Commande.NumC)
Reste à vérifier que si on fait cette jointure, on retrouve bien la relation initiale. Ce qui est donné par le théorème suivant :
Théorème : Soit R (A, B, C) une relation, et R1 = R[A, B] , R2 = R[B, C] deux projections de R.
Soit S = Join (R1, R2, R1.B = R2.B)
Pour que S soit la même relation que R, il suffit que B à A ou B à C, c’est à dire que B soit clé dans l’une au moins des relations projections R1 et R2.
On dit alors que R est décomposable en R1 et R2.
On peut constater ce résultat dans l’exemple suivant.
R est décomposable en R1 [A, B] et R2 [B, C]
A B C a
c c
e e b
b b d Mais pas en R1 [A, B] et R2[A,C]