Académique Documents
Professionnel Documents
Culture Documents
Pour Les De: Bases Données
Pour Les De: Bases Données
2ee édition
Rattaché à l'équipe MACAO du laboratoire IRIT et au département Réseaux et Télécoms de l'IUT de Avec la collaboration de Frédéric Brouard
Blagnac, il intervient autour des bases de données et des technologies de l'information (XML et Web
services) en licence et mastère professionnels, ainsi que pour le compte de la société Orsys. Il est également
l'auteur des ouvrages SQL pour Oracle et Programmer avec MySQL, parus aux éditions Eyrolles.
UML 2
Frédéric Brouard est spécialiste du langage SQL et des bases de données relationnelles. Il dirige
Au sommaire
ISBN : 978-2-212-13413-1
Code article : G13413
Le niveau conceptuel. Analyse des besoins • Concepts majeurs • Identifiants • Associations binaires et n-aires • Classes-
782212 134131
C. Soutou
associations • Agrégations • Identification relative et artificielle • Héritage • Aspects temporels • Démarche à adopter •
Règles métier et contraintes • Règles de validation • Le niveau logique. Du conceptuel au relationnel • Typez vos
Avec 30
colonnes • Normalisation • Calculs de volumétrie • Le niveau physique. Le langage SQL • Passage du logique au exercices
physique • Programmation des contraintes • Dénormalisation • Le niveau externe. Vues relationnelles (SQL2) • Vues corrigés
9
matérialisées • Vues objet (SQL3) • Déclencheurs INSTEAD OF • Les outils du marché : de la théorie à la pratique.
29,90 €
soutou 15/02/12 11:31 Page 1
2ee édition
Rattaché à l'équipe MACAO du laboratoire IRIT et au département Réseaux et Télécoms de l'IUT de Avec la collaboration de Frédéric Brouard
Blagnac, il intervient autour des bases de données et des technologies de l'information (XML et Web
services) en licence et mastère professionnels, ainsi que pour le compte de la société Orsys. Il est également
l'auteur des ouvrages SQL pour Oracle et Programmer avec MySQL, parus aux éditions Eyrolles.
UML 2
Frédéric Brouard est spécialiste du langage SQL et des bases de données relationnelles. Il dirige
Au sommaire
ISBN : 978-2-212-13413-1
Code article : G13413
Le niveau conceptuel. Analyse des besoins • Concepts majeurs • Identifiants • Associations binaires et n-aires • Classes-
C. Soutou
associations • Agrégations • Identification relative et artificielle • Héritage • Aspects temporels • Démarche à adopter •
Règles métier et contraintes • Règles de validation • Le niveau logique. Du conceptuel au relationnel • Typez vos
Avec 30
colonnes • Normalisation • Calculs de volumétrie • Le niveau physique. Le langage SQL • Passage du logique au exercices
physique • Programmation des contraintes • Dénormalisation • Le niveau externe. Vues relationnelles (SQL2) • Vues corrigés
matérialisées • Vues objet (SQL3) • Déclencheurs INSTEAD OF • Les outils du marché : de la théorie à la pratique.
soutou titre 9/02/12 10:53 Page 2
UML 2
pour les
bases de données
2e édition
dU même AUTEUR
Autres ouvrages
H. Balzert. – UML 2.
N°11753, 2006, 88 pages.
H. Bersini. – La programmation orientée objet. Cours et exercices en UML 2 avec Java 6, C# 4, C++, Python, PHP 5 et LinQ.
N°12806, 2011, 644 pages.
Christian Soutou
UML 2
pour les
bases de données
2e édition
ÉDITIONS EYROLLES
61, bd Saint-Germain
75240 Paris Cedex 05
www.editions-eyrolles.com
En application de la loi du 11 mars 1957, il est interdit de reproduire intégralement ou partiellement le présent ouvrage,
sur quelque support que ce soit, sans l’autorisation de l’Éditeur ou du Centre Français d’exploitation du droit de copie,
20, rue des Grands Augustins, 75006 Paris.
© Groupe Eyrolles, 2007, 2012, ISBN : 978-2-212-13413-1
1 Le niveau conceptuel. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Analyse des besoins. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Premiers exemples. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Le jargon du terrain . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Ne confondez pas traitements et données. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Le dictionnaire des données . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
Les concepts majeurs. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Un peu d’histoire . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
© Éditions Eyrolles V
D’autres formalismes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Terminologie. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
Attribut ou information ?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
Classe ou entité ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Les identifiants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Qui dit libellé, dit identifiant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Concrets ou abstraits ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
Artificiels ou naturels ?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Plusieurs, c’est possible ?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Les associations binaires. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
Multiplicités versus cardinalités . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
Le maximum est prépondérant . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
Le minimum est-il illusoire ?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
Réflexivité. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
Les rôles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Mise en pratique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
Les associations plus complexes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
Les classes-associations. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
Premier exemple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
Formalismes entité-association. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
Rattacher une classe-association . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
Classe-association réflexive. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
Mise en pratique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Les associations n-aires. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Savoir les interpréter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
Le langage du formalisme. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
Quelques bêtises du Web . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
Quelques cas valides. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Comment se prémunir ?. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
Mise en pratique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
Les agrégations. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
L’identification relative . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
Notations avec Merise. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
Réification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
Exemples avec UML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
Alternatives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
Mise en pratique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
L’identification artificielle. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
Mise en pratique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
VI © Éditions Eyrolles
L’héritage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
Définition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 58
Identification. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
Instances. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
Héritage multiple . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
Mise en pratique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Aspects temporels. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Modélisation d’un moment. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
Modélisation de chronologie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
Modélisation de l’historisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
Mise en pratique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
La démarche à adopter. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
Décomposition en propositions élémentaires . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
Propositions incomplètes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
Chronologie des étapes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
Quelques conseils. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
Les erreurs classiques. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
Les concepts inutiles de UML . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
Un seul schéma valable ? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
Règles métier et contraintes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
Contraintes prédéfinies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
Contraintes personnalisées (langage OCL). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
Contraintes d’héritage . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
Mise en pratique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
Règles de validation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
Les dépendances fonctionnelles. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
Vérification. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
Première forme normale. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83
Deuxième forme normale. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
Troisième forme normale. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
Forme normale de Boyce-Codd. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
Forme normale domaine-clé . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
Quatrième et cinquième formes normales. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
Mise en pratique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
Bilan. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
Exercices. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 91
Dénormalisation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 180
Les règles de Brouard. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183
Mise en pratique . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185
Exercices. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186
© Éditions Eyrolles IX
Modelio. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 249
Identifiants. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250
Associations. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250
Génération du modèle relationnel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251
Génération des tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252
Objecteering. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 253
Identifiants. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254
Associations. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255
Génération du modèle relationnel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255
Génération des tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256
PowerAMC. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257
Identifiants. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257
Associations. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 258
Héritage. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
Génération du modèle relationnel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 259
Génération des tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
Rétroconception. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261
Rational Rose. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262
Identifiants. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263
Génération du modèle relationnel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264
Génération des tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265
Rétroconception. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265
Visual Paradigm. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265
Win’Design. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 266
Identifiants. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267
Associations. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268
Héritage. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268
Génération du modèle relationnel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268
Génération des tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270
Rétroconception. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270
Conclusion. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271
X © Éditions Eyrolles
© Éditions Eyrolles XI
B Ressources. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315
Webographie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 315
Bibliographie. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 316
Index. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 319
© Éditions Eyrolles 1
sûr ; Apollo 11 a été envoyé sur la lune en juillet 1969 avant qu’E. Codd publie ses écrits sur le
modèle relationnel. À l’époque, la conception des données se faisait avec bon sens, depuis, les
chercheurs ont amené des cadres plus formels. À vous de toujours conserver votre bon sens,
tout en utilisant ces cadres.
Le modèle hiérarchique
Les bases de données hiérarchiques ont introduit un modèle de données du même nom. Il s’agit
de déterminer une arborescence de données où l’accès à un enregistrement de niveau inférieur
n’est pas possible sans passer par le niveau supérieur. Promus par IBM et toujours utilisés dans
le domaine bancaire, les SGBD hiérarchiques souffrent toutefois de nombreux inconvénients.
La figure suivante illustre un modèle hiérarchique de données dans lequel des compagnies
aériennes peuvent embaucher plusieurs pilotes. Un pilote peut travailler pour le compte de
différentes compagnies.
2 © Éditions Eyrolles
Les inconvénients récurrents sont toujours la forte dépendance entre les données stockées et
les méthodes d’accès. Les chaînages internes impliquent forcément une programmation com-
plexe. Outre ces problèmes de programmation, ce modèle montre des lacunes lors de l’accès
à la base.
●● Extraire la liste des pilotes implique le parcours de toutes les compagnies.
●● L’insertion peut se révéler problématique : l’ajout d’un pilote sans compagnie n’est pas
pilotes aussi.
●● La modification est souvent problématique : les incohérences proviennent d’éventuelles
redondances (le nom ou l’adresse d’un pilote qui change doit se répercuter à tous les enre-
gistrements).
Bien qu’il existe de nombreuses hiérarchies autour de nous, le monde qui nous entoure n’est
pas un arbre !
Le modèle réseau
Quelques années plus tard, C. W. Bachman, pionnier dans le domaine de l’informatique, s’est
essayé aux bases de données en inventant un modèle brisant cette hiérarchie plutôt arbitraire.
Les bases de données réseau étaient nées avec le modèle CODASYL, première norme décidée
sans IBM.
© Éditions Eyrolles 3
Bien que résolvant quelques limitations du modèle hiérarchique et annonçant des perfor-
mances en lecture honorables, le modèle réseau n’est ni plus ni moins qu’une usine à gaz gavée
de pointeurs. Pour preuve, plus personne n’utilise de tels SGBD où la dépendance entre les
données stockées et les méthodes d’accès existe toujours, et l’évolution d’une base de données
est très coûteuse en termes de recompilation de pointeurs.
Soyons honnêtes, le monde ressemble bien à une telle usine à gaz ! Mais pas question de
stocker ainsi les données, ce serait bien trop compliqué de concevoir le bon graphe. Le modèle
de données se doit d’être plus simple.
Le modèle relationnel
En 1970, E. Codd publie l’article de référence posant les bases du modèle relationnel [COD
70]. D’un seul coup, toutes les limitations des précédents modèles sont résolues. Le but initial
de ce modèle était d’améliorer l’indépendance entre les données et les traitements. Cet aspect
des choses est réussi et avec ça d’autres fonctionnalités apparaissent :
●● Normalisation (dépendances fonctionnelles) et théorie des ensembles (algèbre relation-
nelle).
●● Cohérence des données (intégrité référentielle).
●● Langage SQL (déclaratif et normalisé).
●● Accès aux données optimisé (choix du chemin par le SGBD).
●● Indexation, etc.
Les liens entre les enregistrements de la base de données sont réalisés non pas à l’aide de poin-
teurs physiques, mais à l’aide des valeurs des clés étrangères et des clés primaires. Pour cette
raison, le modèle relationnel est dit « modèle à valeurs ».
4 © Éditions Eyrolles
La force de ce modèle de données réside dans le fait qu’il repose sur des principes simples et
permet de modéliser des données complexes. Le modèle relationnel est à l’origine du succès
que connaissent aujourd’hui les grands éditeurs de SGBD, à savoir Oracle, IBM, Microsoft et
Sybase dans différents domaines :
●● OLTP (OnLine Transaction Processing) où les mises à jour des données sont fréquentes,
les accès concurrents et les transactions nécessaires.
●● OLAP (Online Analytical Processing) où les données sont multidimensionnelles (cubes),
les analyses complexes et l’informatique décisionnelle.
●● Systèmes d’information géographiques (SIG) où la majorité des données sont exprimées en
2D ou 3D et suivent des variations temporelles.
Comment concevoir de telles relations ? C’est ce que nous allons voir tout au long de cet
ouvrage…
Cet ouvrage s’adresse à toutes les personnes qui s’intéressent à la modélisation et à la conception
des bases de données.
●● Les architectes, chefs de projet, analystes, développeurs et responsables méthode habitués
au modèle entité-association y trouveront les moyens de raisonner avec le diagramme de
classes UML.
●● Les novices découvriront une méthode de conception, des règles de normalisation et de
nombreux exercices mettant en jeu tous les niveaux du processus d’une base de données.
© Éditions Eyrolles 5
L’adoption généralisée de la notation UML dépasse le simple effet de mode. La majorité des
nouveaux projets industriels utilisent la notation UML. Tous les cursus universitaires, qu’ils
soient théoriques ou plus techniques, incluent l’étude d’UML. Cela ne signifie pas qu’UML
soit la panacée, mais que cette notation est devenue incontournable. La dernière version de
la spécification UML, sortie en mai 2010, est la 2.3 (http://www.omg.org/spec/UML/2.3/).
Ce succès s’explique aussi par l’adoption unanime des concepts objet, qui ont des avantages
indéniables (réutilisabilité de composants logiciels, facilité de maintenance, prototypage et
extension des applications, etc.).
Les diagrammes
Les versions 1.x de la notation UML définissent neuf diagrammes : cinq pour les aspects
statiques (classes, objets, cas d’utilisation, composants et déploiement) et quatre pour les
aspects dynamiques (séquence, collaboration, états-transitions, activités). Les spécifications
d’UML 2.x ajoutent le diagramme d’interaction, le diagramme de structure composite et le
diagramme temporel. Seul le diagramme de classes est intéressant à utiliser pour la modéli-
sation d’une base de données.
UML concerne en premier lieu le développement logiciel et n’a pas été initialement pensé
pour les bases de données. La notation UML permet toutefois d’offrir un formalisme aux
concepteurs d’objets métier et aux concepteurs de bases de données. D’autre part, les
concepts relatifs à la modélisation de données (entités, associations, attributs et identifiants)
peuvent être parfaitement intégrés aux diagrammes de classes. De plus, d’autres concepts
(notamment les classes-associations, agrégats et contraintes) permettent d’enrichir un
schéma conceptuel.
Les outils
De nombreux outils informatiques basés sur la notation UML existent depuis quelques
années. Les plus sophistiqués permettent de générer des modèles logiques ou des scripts
SQL. Alors que l’automatisation est quasiment assurée (sous réserve de la qualité de l’outil)
entre le modèle conceptuel et la base de données, il n’en est pas de même de l’élaboration du
diagramme initial qui va conditionner toute la suite. Ici l’humain est au centre de tout et il
n’est pas question de penser que cette tâche puisse être automatisée (c’est heureux pour les
concepteurs).
Par ailleurs, il est fort probable que les scripts SQL générés devront être modifiés manuelle-
ment par la suite, soit pour des raisons d’optimisation, soit parce que l’outil ne permet pas de
générer une caractéristique particulière du SGBD (index, vues, types de données...), soit tout
simplement parce que le concepteur préfère utiliser une autre possibilité d’implémentation
pour traduire telle ou telle autre association.
Il est donc préférable de maîtriser les concepts, de comprendre les mécanismes de trans-
formation de modèles et d’adopter une démarche afin d’utiliser l’outil de manière optimale.
6 © Éditions Eyrolles
Guide de lecture
Cet ouvrage s’organise en 5 chapitres qui suivent les étapes de modélisation illustrées dans la
figure suivante.
© Éditions Eyrolles 7
L’ouvrage commence par décrire la construction d’un diagramme de classes UML en respec-
tant des règles qui permettent de le valider et de le normaliser. Les mécanismes de dérivation
d’un modèle conceptuel dans un schéma de données relationnel sont clairement expliqués à
l’aide d’exemples concrets. Le modèle logique est ensuite optimisé avant l’écriture des scripts
SQL. Il s’agit ensuite d’implémenter les règles métier en programmant des contraintes ou des
déclencheurs SQL. La dernière étape consiste à préparer des vues qui composeront l’interface
de la base aux utilisateurs extérieurs.
8 © Éditions Eyrolles
Niveau conceptuel
Le chapitre 1 décrit la première étape du processus de conception d’une base de données,
à savoir la construction d’un schéma conceptuel. Le formalisme graphique préconisé est le
diagramme de classes de la notation UML qui permet des équivalences des modèles de type
entité-association.
Transformation et normalisation
Le chapitre 2 décrit les concepts du modèle relationnel, puis présente les règles qui permettent
de dériver un schéma logique à partir d’un modèle conceptuel. La dernière partie traite de la
normalisation et du calcul de volumétrie.
Annexes
Les annexes contiennent les corrigés détaillés des exercices, une webographie et une biblio-
graphie. L’index propose les termes utilisés dans la définition des concepts et de certaines
instructions SQL.
© Éditions Eyrolles 9
Les pictogrammes
10 © Éditions Eyrolles
Le niveau conceptuel
Ce chapitre détaille la première étape de conception d’une base de données : il s’agit d’élaborer
un schéma conceptuel. Bien que le formalisme graphique préconisé soit le diagramme de
classes de la notation UML, vous trouverez toutes les équivalences avec les modèles de type
entité-association.
La modélisation est un processus à la fois incontournable et crucial. Incontournable, car même
si vous maîtrisez le modèle relationnel et connaissez parfaitement l’environnement à auto-
matiser, vous ne pouvez pas raisonnablement créer directement les tables. Crucial, car cela
conditionne la structure de la base de données et donc influencera les performances à venir.
Ce travail d’abstraction concerne toute nouvelle conception et il est naturel d’y consacrer du
temps.
Le schéma conceptuel exprime une vue abstraite de la base de données qui, afin de préserver
l’indépendance données/traitements, ne comporte aucune indication relative aux structures de
stockage ou techniques d’accès aux données.
L’objectif d’un schéma conceptuel n’est pas de décrire complètement un système, mais de
modéliser dans un premier temps les données qui seront stockées. Par ailleurs, des règles
métier peuvent enrichir un schéma conceptuel afin de préparer au mieux la programmation
des applications.
© Éditions Eyrolles 11
Pour faire comprendre pourquoi il est fréquent de mal interpréter un modèle physique, je montre à mes
étudiants deux tables « voiture » et « personne » avec un lien 1:n de voiture vers personne et je leur
demande ce que ce modèle décrit. Il y a pratiquement autant de réponses que d’étudiants, mais jamais
la bonne !
Imaginez ce que cela peut donner en entreprise quand la base de données doit être utilisée par de nom-
breux informaticiens pour développer une même application, chacun ayant sa propre interprétation des
liens entre les tables…
Enfin, en ce qui concerne l’arrivée de tables obèses, elle est liée à la non-utilisation du modèle conceptuel.
Combien de fois ai-je entendu un développeur demander « J’ai une nouvelle information à stocker, je la
rattache à quelle table ? » avec à la fin des tables de 80 colonnes inexploitables et contre-performantes
lors de la montée en charge…
À lire : http://blog.developpez.com/sqlpro/p10070/langage-sql-norme/base-de-donnees-et-performances-
petites.
Premiers exemples
Une organisation
Considérons le club de plongée qui décide d’abandonner la gestion papier de toutes ses pres-
tations. L’analyse va consister à recenser ses biens matériels, comprendre le fonctionnement
de la gestion des clients et comptabiliser les sorties des bateaux, etc. La visite des sites et la
rencontre avec chaque intervenant seront très instructives (accueil, pilote du bateau, moniteurs
et directeur de plongée) ; elles permettront de bien appréhender le contexte. L’étude de docu-
ments papier permet souvent une investigation plus approfondie : le carnet de bord d’un bateau
pour se rendre compte du nombre de sorties par jour, des cartes pour recenser les sites, les
habitudes ou réglementations associées, etc.
12 © Éditions Eyrolles
Sans vous jeter à l’eau (elle était facile celle-là…), vous devez pousser chaque expert dans son
domaine à le faire.
Un texte de loi
Considérons le texte suivant où différentes informations sont présentes au sein d’un même
contenu. Supposons que les textes de loi soient numérisés et stockés sur un serveur ministériel.
Le contexte d’analyse est, par exemple, restreint à la recherche d’un texte en particulier.
Il apparaît un numéro d’article, un numéro de loi ou de décret (il s’agira donc de prendre en
compte un type de document), la date de la loi ou du décret. Par ailleurs, les termes « portant
droits » et « relatif » vous amèneront à prendre en compte une donnée modélisant les mots-clés
d’un article ou décret. Enfin, le verbe « abroger » implique d’affecter un statut à chaque article
ou loi (abrogé ou pas).
© Éditions Eyrolles 13
Le jargon du terrain
Lors de cette analyse, vous constaterez que le jargon du terrain n’est pas toujours clair. Chaque
domaine a ses experts et son vocabulaire. Par exemple, des simples notions comme une date,
une durée ou un prix ne seront probablement pas perçues de la même manière dans un contexte
financier ou des travaux publics.
Si vous devez concevoir une base de données, mieux vaut ne pas connaître le domaine ou
feindre de n’y rien comprendre afin que votre connaissance partielle ne vienne pas perturber
la réalité du système. À titre d’exemple, supposons que vous soyez copropriétaire et que vous
assistiez depuis de nombreuses années aux réunions houleuses organisées par votre cher (dans
les deux termes ?) syndic. Un jour, vous avez en charge d’informatiser un autre syndic (dom-
mage…). Vous constaterez sans doute que le fonctionnement de votre client est très différent
de celui que vous supposiez. Ainsi, il est probable que cela vous pénalise davantage que si vous
étiez novice dans ce domaine de l’immobilier.
Deux démarches sont à mener de front (oui, avec sa tête !) :
●● déductive : vous devrez décortiquer le discours en informations élémentaires ;
●● inductive : vous mettrez en évidence à partir des concepts du discours des informations.
14 © Éditions Eyrolles
Questionnez les experts du domaine en reformulant souvent vos interrogations. N’hésitez pas
à changer d’interlocuteur afin d’avoir des points de vue complémentaires. Investiguez jusqu’au
moment où vous obtiendrez une réponse unique et sans ambiguïté à chacune de vos questions.
Le tableau suivant présente quelques questions qui ne peuvent être résolues par l’étude seule
de documents initiaux (photos, fragments de texte et interface graphique) des trois exemples
précédents. Vous devrez obtenir une réponse précise à chacune de ces questions.
Lors de la phase d’analyse, il est souvent difficile de « faire cracher le morceau aux inter-
viewés ». En effet, ils sont tellement dans leur univers qu’ils n’envisagent même pas qu’un
tiers, spécialiste de l’information et qui est plongé dans leur univers, puisse ignorer à ce
point leur métier. Ils ont donc souvent des difficultés à faire comprendre ou à simplifier
les règles qui les régissent ou qu’ils ont eux-mêmes créées. Pour s’en convaincre, il n’y a
qu’à voir la réaction de non-informaticiens lorsqu’ils participent à une discussion entre
développeurs passionnés !
C’est pourquoi la maîtrise du vocabulaire client est essentielle et déterminante. Je com-
mence toujours par cette phase, et je note et apprends par cœur les définitions techniques…
Au cours de la phase d’analyse par interview, il est probable qu’il y ait toujours des zones
d’ombre, notamment sur les règles de gestion, même lorsque les explications viennent de
plusieurs sources. Dans ce cas, je fais mon simplet en revenant le soir ou le lendemain
avec une question-affirmation prenant l’exact contraire de ce que j’ai pu comprendre, par
exemple : « Si j’ai bien compris, l’allotement résiduel ne peut être induit que par un tiers
au contrat… ». À ce moment-là, à tous les coups, mon interlocuteur rétorque : « Mais,
non… j’ai dû mal m’expliquer… je vais prendre un autre exemple… »
En général, là vous avez gagné… car on progresse plus de ses erreurs que de ses réussites !
© Éditions Eyrolles 15
16 © Éditions Eyrolles
La majorité des outils de conception permettent de générer des rapports, plus ou moins
détaillés, listant les données du domaine associées à certaines caractéristiques importantes :
●● identificateur (nom de la donnée) ;
D’autres caractéristiques moins importantes peuvent préciser la nature des données (contrainte
de valeur, minimum, maximum, intervalle, valeur calculée…).
La figure suivante illustre un extrait d’un rapport généré à l’aide de l’outil PowerAMC.
© Éditions Eyrolles 17
de ces concepts, vous serez en mesure de concevoir votre base de données quel que soit le
domaine d’application.
Un peu d’histoire
Le modèle relationnel est né en 1970 des travaux de Edgar Frank Codd, mathématicien
britannique, ex-pilote de chasse de la RAF, devenu ingénieur chez IBM.
Pendant les années qui ont suivi, deux courants de recherches relatives à la conception des
tables se sont dégagés. Le premier visait à contrôler la qualité d’un schéma relationnel en pro-
posant des règles de normalisation (les formes normales seront étudiées en détail au chapitre
suivant). Le second visait à s’abstraire des structures de données stockées en introduisant un
niveau plus abstrait : le niveau conceptuel.
Le modèle entité-association, appelé entity-relationship (entité-relation) chez les Anglo-
Saxons, a été proposé des deux côtés de l’Atlantique. La paternité de ce modèle fut attribuée à
Peter Chen en 1976 avec son article « The Entity-Relationship Model-Toward a Unified View
of Data », mais il n’était sans doute pas le premier. Il est d’ailleurs amusant de lire le titre d’un
des articles d’Hubert Tardieu paru en 1979 « A Method, A Formalism and Tools for Database
Design (three years of Experimental Practice) ».
18 © Éditions Eyrolles
Comme tout ce qui a du succès, ces approches ont été reprises : en 1991 avec le modèle
conceptuel des données (MCD) de Merise, étendu avec Merise/2 en 1994.
En 1997, d’importants acteurs (HP, Microsoft, Oracle, Unisys) utilisent des travaux de
G. Booch, J. Rumbaugh et I. Jacobson pour donner naissance à la version 1.0 d’UML.
D’autres formalismes
Il existe toujours plusieurs autres formalismes graphiques. Citons le modèle binaire NIAM
(Natural Language Information Analysis Method), IDEF1X (Integration Definition for
Information Modeling), la notation de Barker, etc. Seul le modèle entité-association avait été
initialement reconnu par l’ISO.
Selon l’outil que vous utiliserez, vous serez peut-être amené à les rencontrer. Par ailleurs, les
outils permettent aisément de générer un diagramme dans un autre formalisme.
© Éditions Eyrolles 19
Terminologie
Chaque concept de base se divise en sous-concepts comme le présente le tableau suivant.
Tableau 1-3 : Les trois concepts de base
Dans l’état actuel de vos connaissances, et en vous supposant débutant, vous pourriez établir
le tableau suivant sans vous prononcer davantage sur la suite des événements.
Tableau 1-4 : Les trois concepts du cas des supermarchés
Le tableau suivant présente les termes équivalents de la notation UML et des formalismes
entité-association (Merise compris).
Tableau 1-5 : Terminologie
UML Entité-association
Classe Entité
Association Association (Relation)
Objet Occurrence
Multiplicité Cardinalité
Diagramme de classes Modèle conceptuel de données (Merise)
Attribut ou information ?
Lors de l’analyse de l’existant ou du domaine à modéliser, vous devrez faire la distinction entre
attribut et information.
20 © Éditions Eyrolles
●● Les attributs caractérisent les données que vous stockerez en base. Vous les découvrirez
plus ou moins directement. Vous devrez en créer de toutes pièces dans certains cas (les
identifiants en particulier).
●● Les informations incluent toutes les données de l’univers du discours. On y retrouve les
attributs et d’autres données qui n’auront pas à être stockées (informations déduites, calcu-
lées ou de traitements).
L’attribut est une donnée brute et l’information est généralement « calculée » ou composée à
partir d’autres données brutes (date et heure système, par exemple). Le tableau suivant présente
quelques exemples de « bons » ou de mauvais candidats à devenir attribut.
Au début vous tâtonnerez, mais ensuite vous irez rapidement à l’essentiel, en laissant de côté
les informations qui n’auront pas lieu d’être stockées, en amont du dictionnaire des données.
Par ailleurs, vous devrez veiller à ce que chaque attribut soit indécomposable en termes de
structure. Autrement dit, toute valeur d’un attribut doit être atomique. L’exemple le plus parlant
est celui d’une adresse qui ne doit pas être modélisée par un unique attribut adresse, mais
par autant d’attributs qui la composent (nom de la voie, numéro dans la voie, code postal,
cedex…).
Cet aspect des choses sera argumenté au niveau physique ; il est motivé principalement par
l’extraction et l’indexation future des données.
Classe ou entité ?
Deux appellations identiques pour le même concept, c’est ça l’informatique : on aime bien
donner des noms différents aux choses dès qu’on change d’environnement.
●● Entité est la terminologie qui fut proposée par les pionniers de la conception de base de
données.
●● Classe est la terminologie utilisée par les pionniers de la conception objet et reprise par
UML.
© Éditions Eyrolles 21
• Une entité (classe) est une description d’un ensemble homogène d’objets (concrets ou
abstraits), chacun caractérisé par différents attributs.
• Chaque entité (classe) doit disposer d’un identifiant.
• Les classes UML peuvent disposer de méthodes (mécanisme pas encore bien adapté aux
schémas relatifs aux bases de données).
Chaque outil a ses préférences graphiques par défaut qui diffèrent d’un autre ; la figure sui-
vante illustre quelques différences. En revanche, vous retrouverez les constantes suivantes :
●● un cadre représente une entité (classe), le nom de la classe dans le premier compartiment ;
Comme vous le constatez, le type des données peut apparaître (exemple de la seconde classe).
La visibilité des attributs aussi (private de la seconde classe). Ce mécanisme est issu de
l’approche objet et ne concerne pas les schémas relatifs aux bases de données.
Vous devrez affecter, à chacune de vos classes, un identifiant. Un identifiant est une propriété
naturelle ou artificielle d’une classe permettant de distinguer un objet de tous les autres (et
ce quel que soit l’objet considéré). Un identifiant peut être composé d’un ou de plusieurs
attributs.
Si l’outil que vous envisagez d’utiliser ne permet pas cette fonctionnalité, et bien changez-le
pour un autre… En effet, sans identifiant, vous ne pourrez générer aucun script SQL à partir
de votre schéma conceptuel.
22 © Éditions Eyrolles
Les identifiants
L’étape d’identification est fondamentale, elle va conditionner par la suite la composition des
index et des clés étrangères de vos tables. C’est aussi grâce aux identifiants que vous décou-
vrirez des nouvelles classes à définir.
constructeur, au sein du service des mines, sur les cartes grises, etc.
●● Les prénom et nom (prenom_client et nom_client) du passager d’un vol se trouveront
à coup sûr au niveau des cartes d’embarquement, dans les e-mailings publicitaires, les
programmes de fidélité, etc.
Afin d’éviter en amont des probables redondances d’informations au niveau de la base de
données, vous devrez, pour chaque attribut de la sorte, y associer un identifiant ayant un nom
explicite. Ainsi, id_produit devra identifier nom_produit, id_type_voiture identifiera
type_voiture, id_client identifiera nom_client et prenom_client, etc.
Dans l’exemple suivant, il apparaît au premier abord trois attributs. Le titre des thèmes tels
« L’entretien » et « Les pièces d’usure » (lib_theme), le titre des sujets (lib_sujet) et le
numéro des pages du catalogue (num_page).
© Éditions Eyrolles 23
Deux de ces attributs se trouvent être des libellés qui impliquent la définition des identifiants
associés (id_theme et id_sujet). Le schéma conceptuel sera donc composé d’au moins
deux classes, illustrées comme suit. L’outil PowerAMC permet de déclarer un identifiant pour
chaque classe (et permet de le repérer visuellement).
Pourquoi avoir disposé l’attribut num_page dans la classe Sujets ? Parce qu’il « dépend »
de cette classe. En effet, d’après l’analyse qui a été établie, chaque sujet est doté d’un libellé
et une seule page du catalogue le concerne. Nous reviendrons plus loin sur cette notion de
dépendance.
Concrets ou abstraits ?
Abstrait ou concret, tout objet se doit d’être identifiable.
●● Si une classe regroupe des objets concrets, l’identifiant est naturellement concret, mais
24 © Éditions Eyrolles
●● L’avion (ici, un A320) : du point de vue de la compagnie aérienne, chaque objet est concret,
doté d’une immatriculation, d’un numéro de série, d’une date d’acquisition, et associé à des
événements (vols et révisons) etc. L’immatriculation ou le numéro de série sont de bons
candidats pour devenir identifiants. Du point de vue d’une agence de voyages, cet objet est
abstrait ; il importe peu de savoir quel aéronef de la compagnie réalise le vol. Dans ce cas, le
type de l’avion (ici, A320) suffirait à l’identifier. Pour distinguer tout vol réel, l’objet concret
avion devient un composant de l’identifiant (il faudra utiliser l’identification relative).
●● La voiture (ici, une BMW 320Ci type E46) : du point de vue de la concession, chaque objet
est concret, doté d’un numéro de série et de bien d’autres options. Le numéro de série est
un bon candidat pour devenir identifiant de chaque véhicule. D’un point de vue du départe-
ment des ventes, habitué des statistiques, chaque objet devient abstrait et associé à un type
catalogue (ici, 320Ci E46). Ce type suffirait à identifier toute voiture perçue comme un
modèle. Dans le contexte des cartes grises ou des services de police, plusieurs identifiants
seront nécessaires, le numéro de série (qui ne varie jamais) et le numéro d’immatriculation.
●● Le livre (ici, SQL 3e édition) : du point de vue de l’éditeur, chaque objet peut être perçu de
manière abstraite, doté notamment d’un numéro ISBN unique (il existe en fait plusieurs
classifications ISBN). Du point de vue d’un libraire ou d’un bibliothécaire, chaque objet est
concret et sera vendu ou prêté. En conséquence, un numéro d’exemplaire artificiel devra
être ajouté afin d’identifier tout livre perçu ici comme un exemplaire.
●● Le plat (ici, un steak-frites) : dans le contexte d’un restaurant, chaque objet sera plutôt
perçu de manière abstraite (plusieurs steaks-frites correspondent au même plat qui est
vendu à la carte à un certain prix). Un code suffira donc à identifier ce plat. S’il advenait
qu’on doive tracer la provenance des viandes, il faudrait considérer l’objet comme concret
et associer à chaque steak un numéro unique afin de pouvoir relier ce dernier à l’exploita-
tion d’origine. Dans ce cas, les deux identifiants (celui du steak et celui de l’exploitation)
seraient utilisés conjointement.
J’appelle cela les notions « générique » et « spécifique ». Alors que Livre est une classe
générique (qui décrit une œuvre littéraire, par exemple Les misérables de Victor Hugo),
Livre peut être aussi spécifique (Les misérables, collection Folio, Gallimard). Enfin, Livre
peut être un exemplaire d’une bibliothèque. Cela rejoint les notions de classe et d’instance.
Artificiels ou naturels ?
Avant de parler de la nature d’un identifiant, évoquons les deux critères de qualité à respecter :
●● stabilité (un objet ne doit pas changer d’identifiant au cours du temps) ;
Lorsque l’attribut d’un objet remplit les deux critères fondamentaux, on parle « d’identification
naturelle » (l’identifiant a une sémantique métier ; on parle de « clé métier »).
© Éditions Eyrolles 25
Lorsqu’aucun attribut présent dans le dictionnaire des données ne remplit les deux critères
fondamentaux, il est nécessaire d’ajouter un attribut identifiant (le plus souvent un numérique
qui deviendra séquence ou auto-incrément). On parlera « d’identification artificielle ». Cette
technique, très utilisée, est simple et favorise le respect des critères de qualité au cours du
temps.
Si vous optez pour l’identification artificielle, vous devez, dans la majorité des cas, ajouter à la
classe un attribut naturel d’identification (clé métier). Cette identification secondaire permettra
par la suite de pouvoir rechercher un objet à l’aide d’une sémantique métier.
Plusieurs identifiants peuvent être déduits de la figure suivante (extrait du site Internet de la
banque LCL).
●● L’identifiant naturel de la banque LCL (id_banque) : il est aussi possible d’identifier une
banque par un numéro artificiel (c’est le cas du code attribué par la Banque de France :
30002 pour le Crédit Lyonnais).
●● L’identifiant naturel de l’agence (id_agence), indiqué en tant qu’indicatif du compte : c’est
et de lettres (chaque client connaît ses numéros ou est capable de les retrouver).
●● L’identifiant articiel du client (id_client) : le client ne le connaît pas, mais le banquier
26 © Éditions Eyrolles
Une clé naturelle peut ne pas être connue lors de la saisie primale… Que se passe-t-il si
le patient que vous avez modélisé avec comme identifiant son numéro de Sécurité sociale
arrive à l’hôpital sans ses papiers et dans le coma ?
Une clé naturelle peut évoluer dans le temps… Que se passe-t-il si ayant modélisé vos
adhérents par leurs nom et prénom, Marie DUPONT se marie avec Albert DUVAL ? Quid
des données des nombreuses tables filles ?
Une clé naturelle est souvent longue… Un numéro de Sécurité sociale (13 caractères),
comme le couple nom et prénom (en moyenne, 15 caractères), c’est 3 à 4 fois plus long
qu’un entier et permet environ 6 fois moins de combinaisons (en pratique, on ne peut uti-
liser qu’une quarantaine de caractères sur les 25 possibles). C’est donc facilement 24 fois
moins performant !
Préférez une clé arbitraire la plus courte possible. Par exemple, un entier auto-incrémenté
(SEQUENCE , IDENTITY en SQL). L’utilisation des GUID (Globally Unique IDentifier)
ou UUID (Universally Unique Identifier) posant d’autres problèmes en plus de ne pas
garantir l’unicité absolue…
Il est possible de définir dans une classe plusieurs identifiants à la condition qu’un seul soit
principal.
© Éditions Eyrolles 27
Les autres identifiants potentiels (appelés secondaires ou alternatifs) n’apparaîtront pas for-
cément visuellement sur vos schémas conceptuels (cela dépend de l’outil que vous utiliserez).
Ces identifiants secondaires se rendront plus utiles au niveau logique en jouant le rôle de clé
candidate pouvant se substituer à la clé primaire de la table. Des références supplémentaires
pourront être mises en place sans nécessairement utiliser la clé primaire de la table.
La figure suivante présente la classe UML (incomplète) que l’on peut déduire de cet exemple.
L’ensemble des données qu’il faudrait recenser n’est pas pris en compte (nom de l’auteur,
traducteur…). En revanche, les attributs identifiants potentiels sont tous répertoriés. Seul
l’identifiant principal est aisément repérable visuellement.
●● Les associations un-à-un sont les moins courantes. À titre d’exemple, dans le contexte des
assurances, citons le contrat (classe) qui concerne (association) un véhicule (classe). Tout
véhicule n’est concerné que par un seul contrat.
28 © Éditions Eyrolles
●● Les associations un-à-plusieurs (hiérarchies) sont très courantes car omniprésentes dans
notre environnement. À titre d’exemple, une compagnie aérienne (classe) possède (associa-
tion) des avions (classe). Tout avion n’appartient qu’à une seule compagnie.
●● Les associations plusieurs-à-plusieurs sont aussi courantes car très présentes dans notre
Nous pouvons maintenant relier les deux classes de l’exemple du catalogue des services auto-
mobiles, l’association précise qu’un thème inclut plusieurs sujets et un sujet ne dépend que
d’un thème.
Figure 1-16. Thèmes et sujets reliés par une association UML un-à-plusieurs
Il est important de nommer chaque association par un verbe ou une forme nominale la plus
parlante possible.
Cela est particulièrement intéressant lorsque plusieurs associations relient deux mêmes classes.
Le plus souvent, il n’y a pas de corrélation entre les objets qui participent à ces différentes
© Éditions Eyrolles 29
associations. Chaque lien exprime une sémantique distincte. Dans le cas contraire, il sera
nécessaire d’utiliser des contraintes (voir à la fin de ce chapitre).
Le schéma suivant présente trois associations entre deux mêmes classes. Bien que la séman-
tique de ces trois associations soit distincte, il faudra par la suite contraindre ce schéma en
précisant que la gare de départ doit être différente de la gare d’arrivée. De plus, ces deux gares
devront être répertoriées au sein de l’association plusieurs-à-plusieurs desservir qui repré-
sente le trajet complet d’un train.
Les cardinalités d’une association binaire Merise sont inversées par rapport aux multiplicités
de la notation UML (qui se comporte comme les autres modèles entité-association).
30 © Éditions Eyrolles
Le schéma conceptuel Merise, équivalent du diagramme UML précédent, illustre cette différence.
Le tableau suivant résume les équivalences entre les écritures des multiplicités de la notation
UML et les cardinalités des autres formalismes entité-association.
0..1 0,1
1..1 (ou 1) 1,1
0..* (ou *) 0,N (ou 0,n)
1..* 1,N (ou 1,n)
a..b a,b
Il est peu courant que le nombre minimum d’objets soit supérieur à 1, mais c’est une possibilité
que tous les formalismes permettent. Le schéma suivant présente un cas où toutes les multipli-
cités sont bornées. Ce schéma exprime que tout administrateur se doit de conseiller entre 2 et
5 holdings. Par ailleurs, tout holding sera associée à au moins 3 administrateurs et au plus 10.
© Éditions Eyrolles 31
Vous n’aurez pas le droit à l’erreur lorsque vous déterminerez le nombre maximum d’une
multiplicité. En effet, le processus de transformation au niveau logique qui génère les clés
étrangères est basé sur le nombre maximum de toutes les multiplicités. La condition princi-
pale de ce processus est la suivante :
SI (multiplicite_maximum > 1) ALORS
Modélisation A
SINON
Modélisation B
FIN SI
Ne faites pas de confusion avec le sens de lecture des multiplicités de UML si vous lisez un
schéma au formalisme de Merise (il vous suffira de permuter les couples pour chaque association
le cas échéant).
Que vous choisissiez de borner vos multiplicités par un entier supérieur à 1 (2, par exemple)
ou que vous optiez pour * (ou N pour un formalisme entité-association), le schéma logique
obtenu sera identique (la structure des tables et la composition des clés seront identiques).
Les multiplicités minimales précisent les liens d’association et n’ont pas d’influence sur la
structure des tables et des clés de la base de données. En revanche, vous devrez mettre en
œuvre, en théorie, des contraintes si vous désirez implémenter chaque multiplicité minimale.
Je dis en théorie, car bon nombre de schémas sont pleins de bonnes intentions sur le papier
qu’il faut concrétiser correctement dans la programmation des transactions.
La mise en œuvre de contraintes SQL sera nécessaire pour implémenter chaque multiplicité
minimale. Pour les cas simples des associations un-à-un et un-à-plusieurs, une contrainte
NOT NULL pourra suffire (processus en général automatisé par les outils de conception). Pour
les autres cas, et par ordre de complexité, vous devrez ajouter des contraintes CHECK, des
colonnes (calculées ou pas), programmer des déclencheurs ou des transactions.
32 © Éditions Eyrolles
Considérons la classe Aeroport qui est reliée à deux associations un-à-plusieurs ayant du
côté « un » les multiplicités minimales respectives 1 et 0.
●● Le « 1 » de l’association situer du côté Ville exprime qu’un aéroport est situé sur une
être associé à un service douanier. Aucune contrainte NOT NULL ne sera générée.
Examinons à présent la sémantique des multiplicités minimales d’un diagramme un peu plus
complexe comme celui des actionnaires de SARL. L’association participation exprime
qu’une SARL doit avoir au minimum 2 actionnaires et au plus 10. Un actionnaire peut ne pas
être associé à une SARL, et est limité à 6 participations. Chaque actionnaire devra être détenteur
d’une à trois adresses électroniques.
© Éditions Eyrolles 33
●● Le « 1 » au minimum du côté Mails de l’association contacts n’est pas sujet à discus-
sion, car c’est l’expression du fait qu’un actionnaire dispose obligatoirement d’un e-mail.
Une contrainte NOT NULL sera générée pour implémenter ce contrôle. En affectant « 0 » à
cette multiplicité, la contrainte ne sera pas générée.
●● Le « 1 » au minimum du côté Actionnaires de l’association contacts peut être sujet
à discussion. Il s’agit de savoir si la base de données peut stocker des e-mails anonymes.
En théorie, il faudrait assurer un tel contrôle au niveau de la programmation. En affectant
« 0 » à cette multiplicité, vous relâchez ce contrôle.
●● Le « 0 » au minimum du côté SARL de l’association participation peut être sujet à
discussion. Il s’agit de savoir si la base de données peut stocker des actionnaires qui ne
participent à aucune SARL. Ici aucune contrainte n’est à mettre en œuvre. Le fait de choisir
« 1 » pour cette multiplicité nécessite, en théorie, la mise en œuvre de ce contrôle par
programmation (transaction ou déclencheur).
●● Le « 2 » au minimum du côté Actionnaires de l’association participation n’est
pas sujet à discussion, c’est l’expression d’une règle métier. Une simple contrainte CHECK
ne suffit pas et du code SQL doit implémenter cette règle (transactions et déclencheurs).
Ce code se chargera également de vérifier le non-dépassement du nombre maximal de la
multiplicité (10).
Si vous hésitez entre 0 et 1 pour une multiplicité minimale, choisissez 0 de sorte à moins
contraindre le schéma SQL. Vous pourrez toujours ensuite programmer une nouvelle
contrainte.
Réflexivité
Une association binaire (un-à-un, un-à-plusieurs, plusieurs-à-plusieurs) qui relie une classe à
elle-même est dite réflexive.
Bien que séduisant par sa sémantique, le concept de réflexivité produit des schémas relation-
nels plus complexes (en particulier avec des associations plusieurs-à-plusieurs) et induit une
programmation ardue qui peut s’avérer moins performante (requêtes récursives).
Afin de pallier ces problèmes potentiels, nous verrons qu’une association réflexive peut se
représenter, dans certains cas, à l’aide de plusieurs associations binaires non réflexives.
Le diagramme suivant décrit l’association un-à-plusieurs de parrainage qui relie (éventuel-
lement) un client à ses filleuls qui sont aussi des clients (0..*). Un filleul peut n’être associé à
aucun parrain (0..1), ce qui exprime qu’un client peut être ni parrain, ni filleul.
34 © Éditions Eyrolles
En considérant l’exemple des autoroutes françaises, il apparaît qu’une ville (source) est reliée à
une ou à plusieurs autres villes (cibles). Par ailleurs, une ville cible peut être reliée à plusieurs
villes sources.
© Éditions Eyrolles 35
Ce n’est pas la solution la plus simple pour modéliser un tel graphe. D’une part, la réflexi-
vité n’est pas le concept le plus adéquat, d’autre part, ce schéma relie une ville à plusieurs
autres sans préciser de quelle autoroute il s’agit, alors qu’il existe une forte contrainte entre les
deux associations. Une solution plus simple consiste à utiliser une classe supplémentaire pour
modéliser un tronçon (schéma décrit plus loin dans ce chapitre).
Les cardinalités Merise sont, comme au titre des associations binaires, simplement permutées
par rapport aux multiplicités (voir le schéma suivant).
Il est important d’utiliser des rôles pour préciser la sémantique d’une association UML a for-
tiori lorsque cette association est de nature réflexive.
Nous verrons, par la suite, qu’il est possible de relier une classe-association UML à une asso-
ciation réflexive à la condition qu’elle soit de type plusieurs-à-plusieurs.
Les rôles
Un rôle UML se note sur un lien d’association sous la forme d’un nom (forme nominale ou
verbale) qui décrit comment une classe source « voit » sa classe cible.
Dans l’exemple suivant, les comptes d’un client sont considérés comme un portefeuille, le
client d’un compte est son détenteur. Les rôles inscrits sur l’association réflexive précisent le
sens de lecture et la sémantique de l’association.
36 © Éditions Eyrolles
Bien qu’il soit possible de nommer les associations et les rôles dans un même diagramme de
classes, cela n’est pas forcément recommandé pour des raisons de lisibilité.
Les rôles sont particulièrement utiles pour les concepteurs qui écriront toutes leurs contraintes
à l’aide du langage OCL (voir en fin de chapitre).
Mise en pratique
Testez dès à présent vos aptitudes grâce à l’exercice 1.1 « La déroute des bleus », à la fin du
chapitre. Vous y modéliserez le schéma du premier tour de la coupe du monde de football 2010
en Afrique du Sud. Vous n’aurez pas à modéliser le second tour (vous vous rappelez que notre
équipe de stars n’a pas été qualifiée…). Suite de l’exercice peut-être en 2014.
Les classes-associations
Une classe-association UML :
●● est une classe rattachée à une association plusieurs-à-plusieurs ;
●● possède éventuellement des attributs, mais pas d’identifiant ;
●● est rattachée éventuellement à d’autres classes.
D’un point de vue sémantique, une classe-association c’est comme une agence matrimoniale :
ça forme des couples qui se lient ensemble éventuellement à d’autres objets.
© Éditions Eyrolles 37
Premier exemple
Dans l’exemple suivant, la classe-association Comp_Aero modélise tous les couples (com-
pagnie, aéroport) valides. À chaque couple, des données peuvent être associées. Ici, la date
d’arrivée d’une compagnie dans un aéroport et le nombre de comptoirs dont elle dispose.
Notez que les deux attributs de cette classe-association ne peuvent pas être disposés ailleurs.
●● La date d’arrivée ne dépend pas de la compagnie seule (Air France peut résider à Orly
depuis l’année 1967 alors qu’elle est arrivée à Blagnac au cours de l’année 1969, par
exemple). Cette date d’arrivée ne dépend pas non plus de l’aéroport seul, car Orly qui a
accueilli Air France en 1967 a vu débarquer Air Liberté en 1990.
●● Le nombre de comptoirs ne dépend ni de la compagnie seule, ni de l’aéroport seul. Sinon,
il s’agirait de cumuls. Dans le premier cas, s’il se trouvait dans la classe Compagnie,
l’attribut indiquerait le nombre de comptoirs détenus par la compagnie (sans préciser où
chacun se trouve). Dans le second, s’il se trouvait dans la classe Aeroport, l’attribut indi-
querait le nombre de comptoirs qui se trouvent dans un aéroport (sans préciser de quelle
compagnie il s’agit).
Tout attribut d’une classe-association doit dépendre simultanément des deux classes (pas
simplement de l’une ou de l’autre). Pour toute valeur d’un couple d’objets connectés, une
valeur au plus de l’attribut doit être associée, et cet attribut doit être contenu dans la classe-
association.
Vous ne savez pas comment appeler une classe-association ? Composez son nom avec les
préfixes des deux classes connectées.
38 © Éditions Eyrolles
Formalismes entité-association
Avec Merise et les autres formalismes, ces attributs qui dépendent de deux entités se trouvent
aussi dans une association plusieurs-à-plusieurs.
© Éditions Eyrolles 39
Classe-association réflexive
Une classe-association peut être liée à une association réflexive (à condition qu’elle soit de type
plusieurs-à-plusieurs).
Le premier exemple reprend la première modélisation des villes connectées par des auto-
routes. Modélisons un tronçon comme un couple de villes. Chaque tronçon a été ouvert à
une certaine date (postérieure à celle de l’autoroute, mais pas forcément identique) et chaque
tronçon mesure une certaine distance.
Ce n’est pas la modélisation la plus simple ; il n’apparaît pas explicitement la notion de sens,
du fait que les villes forment un graphe orienté. Dans ce schéma, on exprime toutefois qu’un
couple de villes forme un tronçon tout en permettant qu’entre deux villes, deux tronçons dis-
tincts existent : celui où vous roulez en regardant souvent votre compteur et votre avertisseur
de radar, et l’autre où ceux de la voie d’en face font pareil.
L’autre problème de cette modélisation concerne le lien entre Ville et Autoroute qui n’est
pas précis (il ne respecte pas la hiérarchie). La hiérarchie veut qu’une autoroute soit composée
de tronçons reliant chacun deux villes. Nous reviendrons sur cet écueil classique. Le schéma
suivant est de meilleure qualité.
40 © Éditions Eyrolles
Ces deux modélisations (les comptes et les tronçons autoroutiers) peuvent se simplifier du fait
de la présence de la multiplicité 1..1 du côté de la classe-association. Nous verrons à la section
« L’identification artificielle » les moyens de procéder à une telle simplification.
Mise en pratique
Appliquez le concept de classe-association grâce à la fin de l’exercice 1.1 « La déroute des
bleus ». Il s’agit de pouvoir nommer de manière différente une équipe en fonction de la langue.
Vous pouvez également réfléchir aux exercices 1.2 « L’organisme de formation » et 1.3 « Les
lignes de facture » qui ne font intervenir que des associations binaires.
© Éditions Eyrolles 41
●● Des logiciels sont installés sur des serveurs par des départements.
●● Les chantiers peuvent être visités plusieurs fois par jour par les véhicules de la société.
Évitez d’utiliser des associations n-aires, car votre modélisation produira un schéma rela-
tionnel non contraint (décidez plutôt de ne pas contraindre un schéma au niveau logique). La
majorité des associations n-aires doivent plutôt s’écrire, d’une manière hiérarchique, à l’aide
d’une ou de plusieurs classes-associations.
Cette section décrit tout d’abord comment décrypter une association n-aire. Ensuite, plusieurs
cas sont présentés qui mettrent en évidence le fait que l’on puisse parfois se passer de ce méca-
nisme d’association. Enfin, vous découvrirez comment décomposer une association n-aire en
une ou plusieurs classes-associations.
Avec le formalisme de Merise, les cardinalités sont lues du sens entité concernée → entités
connectées.
Dans les autres formalismes entité-association et avec UML, les multiplicités d’une classe sont
lues à partir des autres classes de l’association (sens classes connectées → classe concernée).
Pour les deux formalismes, une association n-aire peut contenir des attributs (par le biais
d’une classe-association pour UML).
Aucune de ces deux lectures n’est l’inverse ou l’opposée de l’autre ; le sens est tout bonnement
différent. Dans l’exemple suivant, l’utilisation de l’association n-aire Installer permet d’ex-
primer que des logiciels sont installés un certain jour (date_install) sur des serveurs par
des départements.
42 © Éditions Eyrolles
(Departement, Serveur) ;
●● côté Serveur, (0,n) signifie qu’un serveur peut être associé à aucun ou plusieurs couples
(Departement, Logiciel) ;
●● côté Departement, (0,n) signifie qu’un département peut être associé à aucun ou plu-
Le langage du formalisme
Quel que soit le nombre d’entités/classes connectées, le mécanisme de lecture est analogue à
l’exemple précédent. Pour une association reliant 4 entités/classes (de degré 4), vous devrez
considérer la relation entre triplets et singletons en partant de la cible ou de la source.
L’exemple suivant illustre ce propos avec Merise. De chaque côté, il est exprimé la cardinalité
(0,n) qui s’interprète pour toutes les entités ainsi : un objet est associé à plusieurs triplets d’ob-
jets ou à aucun. Du côté Employe, cette cardinalité signifie qu’un employé peut être associé à
plusieurs comptoirs dans différents aéroports (ou dans le même), pour le compte d’une com-
pagnie (ou pour plusieurs).
© Éditions Eyrolles 43
Avec le formalisme Merise, vous ne pouvez pas déduire grand-chose des associations n-aires.
La majorité d’entre elles ne contiennent que des cardinalités (0,n). La cardinalité (0,1) impose
une décomposition en degré inférieur (une association 3-aire se décompose en deux associations
binaires).
Avec le formalisme UML, les associations n-aires sont davantage parlantes. La multiplicité
(0..1) n’impose pas forcément une décomposition en degré inférieur. Le schéma suivant pré-
cise qu’un employé qui se trouve dans un comptoir d’un aéroport ne travaille que pour le
compte d’une seule compagnie. Symétriquement, un employé qui se trouve dans un comptoir
d’une compagnie est situé dans un seul aéroport.
Bien que UML semble plus explicite que Merise sur cet aspect des choses, ces deux schémas
ne sont pas satisfaisants. En effet, trop peu de contraintes sont présentes entre les 4 classes.
●● Pensez-vous réellement qu’en considérant un employé répertorié, un aéroport, une compa-
aéroport, qu’un comptoir ne se trouve que dans un aéroport, qu’une compagnie n’embauche
pas n’importe quel employé ?
Ce sont toutes ces questions que vous devrez vous poser de sorte à décomposer au mieux cette
association tentaculaire (celle-là et toutes les autres que vous rencontrerez).
44 © Éditions Eyrolles
Cela va coûter cher à la compagnie qui devra renouveler sa flotte à un rythme mensuel ou
hebdomadaire peut-être…
Dans le second schéma Merise, vous permet facilement (enfin la structure de la base le permet)
à un patient de se faire prescrire n’importe quel médicament par tout médecin…
La notation UML n’est pas en reste (même dans la documentation officielle de l’OMG).
●● Le premier schéma précise qu’une équipe peut faire jouer n’importe quel joueur quelle que
n’importe quelle année dans n’importe quel type de bureau (même si le bureau ou la voi-
ture n’existaient pas cette année-là…).
●● Le troisième schéma indique qu’un professeur peut enseigner n’importe quelle matière à
n’importe quel étudiant. C’est dans l’air du temps la polyvalence, mais là, ça s’apparente à
un grand écart (appelez le prof de gym !).
© Éditions Eyrolles 45
Comment se prémunir ?
Avant de chercher systématiquement à utiliser une classe-association afin de contraindre une
association n-aire, vous devez essayer de réduire le degré de l’association n-aire à l’aide de
plusieurs associations de degré inférieur à n. Ces cas se rencontrent lorsqu’il existe un lien fort
entre deux classes (entités) connectées indépendamment de l’association, mais toutefois dans
le contexte. Le cas échéant, une association 4-aire se décomposera en une association 3-aire
et plusieurs binaires. Une association 3-aire se dérivera ensuite éventuellement en plusieurs
associations binaires.
46 © Éditions Eyrolles
Dans l’exemple des contrats reliant véhicules, clients et sociétés d’assurance, vous pouvez
penser à une association de degré 3. Ici, le lien fort provient de la propriété d’un véhicule. Ce
lien doit se modéliser par une association binaire entre un client et ses véhicules.
© Éditions Eyrolles 47
Le contrat devient une simple association binaire reliant un véhicule à sa compagnie d’assurance.
L’exemple suivant utilise une association de degré 3 pour lister les qualifications des pilotes
relatives à certains types d’appareils.
Le problème de cette association est qu’elle mélange deux faits : le premier concerne les qua-
lifications qu’un avion impose (indépendamment du pilote) et le second que des pilotes soient
titulaires de différentes qualifications. Les associations binaires titulaire et necessite
simplifient le modèle initial. La troisième association est plus discutable puisqu’elle peut être
déduite des deux précédentes. La normalisation forcenée vous conduirait à ne pas la définir,
l’utilisation courante vous conseillera de la préserver.
48 © Éditions Eyrolles
Lorsqu’il ne vous est pas possible de réduire le degré d’une association n-aire du fait qu’il
n’existe aucun lien entre les différentes classes connectées, à part l’association elle-même,
trouvez s’il existe (et c’est souvent le cas) une hiérarchie à travers une ou plusieurs classes-
associations. En effet, une association n-aire exprime implicitement dans la majorité des cas
une ou plusieurs contraintes d’inclusion.
Décomposition en classe-association
Le processus décrit ici concerne une association de degré 3, mais il s’applique aux degrés
supérieurs par analogie de raisonnement.
Vous devez choisir le couple de classes le plus « fort ». Dans certains cas, le choix s’impose
facilement, dans d’autres, plusieurs couples peuvent être candidats.
Reliez ces classes par une association plusieurs-à-plusieurs, si ce n’est pas possible, votre
couple n’est pas solide (enfin, ce n’est pas ce que je veux dire !), piochez ailleurs (là non plus…).
Attachez ensuite à cette association une classe-association qui contiendra éventuellement
des attributs.
La classe restante est à associer à la classe-association et toutes les possibilités de multipli-
cités sont permises.
Concernant l’exemple des installations de logiciels, un premier choix peut se porter sur les
couples (logiciel, serveur) qui recensent toutes les compatibilités (et évitent ainsi les incom-
patibilités). La classe-association contient la date d’installation (qui dépend en fait du seul
couple). L’association d’installation concerne bien simultanément les trois classes en reliant un
couple (logiciel, serveur) au département acteur de l’événement.
© Éditions Eyrolles 49
Une deuxième alternative consiste à considérer les couples (logiciel, département) qui recen-
sent tous les achats (évitant ainsi d’installer un logiciel non acquis par le département). La
classe-association contient la date d’installation (qui dépend en fait du seul couple). L’asso-
ciation d’installation concerne toujours simultanément les trois classes en reliant un couple
(logiciel, département) aux serveurs dont le but est l’hébergement. La date d’installation doit
se trouver au niveau de cette association avec cette modélisation.
Une troisième alternative consiste à considérer les couples (département, serveur) qui recen-
sent toutes les autorisations (évitant ainsi d’installer un logiciel sur un serveur non accessible
par le département). Cette solution est symétrique à la précédente.
50 © Éditions Eyrolles
La dernière alternative consiste à inclure ces trois contraintes dans le même diagramme.
Il restera à préciser ces contraintes à l’aide d’un langage naturel ou par l’intermédiaire du
pseudo-code du langage OCL (voir la fin du chapitre).
Mise en pratique
L’exercice 1.4 « La décomposition des n-aires » vous permettra de décomposer les prétendues
associations n-aires (en les réduisant à des associations binaires ou en regroupant judicieu-
sement des classes en couple relié à une classe-association).
Les agrégations
La notion d’agrégation a été l’un des aspects les plus discutés de la notation UML. L’agréga-
tion concerne seulement les associations binaires (réflexives ou non). Une agrégation n’est pas
une association symétrique, car une des extrémités du lien d’association joue toujours un rôle
prédominant par rapport à l’autre.
Selon P. A. Muller, [MUL 00], une agrégation est préconisée dans les cas suivants :
●● une classe fait partie d’une autre classe ;
●● une action sur une classe implique une action sur une autre classe ;
●● les objets d’une classe sont subordonnés aux objets d’une autre classe.
© Éditions Eyrolles 51
La composition requiert qu’un objet appartienne au plus à une composition d’objets à un instant
donné. Cette appartenance peut changer au cours du temps. La composition implique en outre
une forme de propagation entre le composite et le composant (en particulier la destruction du
composite entraînera obligatoirement la destruction de ses composants). Cette agrégation est
représentée par un losange noirci du côté du rôle de la classe composite appelée « agrégat ».
L’agrégation partagée autorise qu’un objet appartienne simultanément à différentes compo-
sitions d’objets. Cette agrégation est représentée par un losange clair du côté du rôle de la
classe concernée par l’association appelée « agrégat ».
Les agrégations partagées sont un peu plus difficiles à définir, elles renforcent le couplage
d’une association binaire et interviennent lorsque la composition ne s’applique pas et que des
objets sont fortement dépendants par rapport à d’autres objets dans le cadre de l’association.
par un numéro et le numéro de son immeuble. Par ailleurs, il est entendu que sa destruction
entraînera la destruction des appartements associés.
52 © Éditions Eyrolles
●● Les agrégats partagés (habiter et localiser) renforcent une simple association par le
fait que la perte d’un copropriétaire ou d’un immeuble est susceptible d’entraîner la sup-
pression des adresses associées. Il ne s’agit pas ici d’une relation composite/composant, car
une même adresse (d’un immeuble ou d’un copropriétaire) peut être partagée par différents
copropriétaires.
Du fait que la suppression d’un appartement n’implique pas la perte du copropriétaire associé
(qui peut être copropriétaire d’autres appartements), l’association appartient est la moins
contrainte.
L’identification relative
Dans certaines situations, l’identification d’une classe nécessite de se positionner relativement
par rapport à une autre classe.
L’identification relative a son histoire, abordée initialement dans Merise ; elle est absente de
l’ouvrage de référence. À partir de 1987, A. Rochfeld et J. Morejon réhabilitent cette notion à
travers le concept d’entité faible qui s’intègre à Merise/2 ainsi que dans la plupart des outils
associés.
© Éditions Eyrolles 53
Par analogie, en qualifiant de faible, la classe qui nécessite l’identifiant d’une autre classe et
en utilisant l’agrégation forte, UML implémente ce mécanisme.
Réification
Dans la sémantique du discours, sous-tendue par la structure grammaticale, lorsqu’on passe
progressivement d’une association (groupe verbal) à un objet (groupe nominal), on parle
de réification (ou substantification). La modélisation conceptuelle est avant tout une vision
sémantique : la perception en classe ou association prime sur la manière de l’identifier. Ce n’est
pas l’identification qui détermine la modélisation, mais le choix de modélisation qui implique
l’identification.
Le concept à modéliser peut apparaître de prime abord en tant que forme verbale (une associa-
tion) : un avion est affrété par une compagnie. Puis progressivement, la forme verbale devient
substantive : pour chaque affrètement…, les vols affrétés… Ce groupe nominal (un objet d’une
classe) intervient à son tour dans des associations.
54 © Éditions Eyrolles
Considérons à présent des véhicules qui visitent quotidiennement des chantiers et appelons
mission chaque déplacement journalier. Chaque mission est identifiée par le véhicule et le
jour de sortie. L’attribut km_journalier de la classe faible Mission désigne la distance
parcourue d’un véhicule dans la journée.
Alternatives
À la question « Y a-t-il une unique solution à toute conception ? », la réponse est négative ;
plusieurs schémas différents peuvent modéliser le même système. Selon le mécanisme que
vous utiliserez, diverses solutions peuvent émerger. Les mécanismes qui sont potentiellement
interchangeables sont les classes-associations, les associations de composition et l’identification
artificielle.
Les modélisations suivantes sont équivalentes. Le premier schéma utilise une classe-associa-
tion pour décrire chaque mission, alors que le second considère une mission comme un objet
artificiel qu’il est nécessaire d’identifier.
© Éditions Eyrolles 55
Les différences vont se rencontrer au niveau logique. Il faudra alors préférer la solution opti-
male en termes de tables en raisonnant sur les index qu’il faudra générer.
Mise en pratique
Comment modéliser l’historique des rendez-vous de l’exercice 1.5 « Les comptes ban-
caires » ?
Trouvez les identifiants principaux et relatifs qui sont présents dans l’exercice 1.6 « Le
RIB ».
L’identification artificielle
Lorsque l’identification d’un objet est complexe ou met en jeu beaucoup trop d’autres classes,
vous pouvez faire appel à l’identification artificielle qui consiste à définir une classe (le plus
souvent de nature abstraite) afin d’héberger des attributs pour lesquels il est difficile d’y asso-
cier un identifiant naturel ou relatif. Une fois définie, la classe nécessite un identifiant (artificiel)
qui sera dépourvu de toute sémantique.
Considérons l’exemple des tronçons autoroutiers (section « Les classes-associations »). Alors
que la réflexivité n’était pas la solution la plus simple pour modéliser un tel graphe, l’identifica-
tion artificielle se révèle redoutable de simplicité. Un tronçon est désormais modélisé en tant
qu’objet relié à deux villes. L’association de composition permet en plus de pouvoir utiliser un
même numéro de tronçon pour différentes autoroutes.
56 © Éditions Eyrolles
Considérons l’exemple des installations de logiciels (section « Les associations n-aires »). Bien
que la classe-association soit une solution satisfaisante, l’identification artificielle est aussi pos-
sible. Une installation est modélisée en tant qu’objet abstrait relié aux classes qui interviennent
dans l’association.
© Éditions Eyrolles 57
Mise en pratique
Aidez-vous de l’identification artificielle pour :
●● compléter l’exercice 1.5 « Les comptes bancaires » en modélisant les virements internes
L’héritage
L’héritage est un mécanisme qui provient de la programmation objet et qui consiste à réutiliser
du code (en termes de fonctionnalités). Dans le contexte d’un modèle conceptuel, l’héritage va
permettre la réutilisation de structures (classes). Une classe générique (appelées surclasse) rend
possible la définition de classes plus spécifiques (appelées sous-classes). Par conséquent, cette
décomposition rend les associations entre classes plus précises.
À l’origine, les modèles entité-association ne disposaient pas de ce concept. Des extensions
comme Merise/2 ont rendu possible le mécanisme d’héritage qui permet d’organiser les entités
en hiérarchies. La notation objet UML propose l’héritage de classes depuis sa première
spécification.
Définition
Vous devez définir un héritage entre les classes C1 et C2 si vous répondez affirmativement à
la question : la classe C1 est-elle une sorte de C2 ?
La surclasse généralise le concept alors que les sous-classes le spécialisent.
L’héritage représente un lien très fort entre classes. Avec UML, un lien d’héritage est noté par
une flèche partant d’une sous-classe vers sa surclasse.
Dans l’exemple suivant, la surclasse Personnel permet aux sous-classes Navigant et
ommercial de récupérer les attributs nup, nom et salaire qui sont génériques. Chaque
C
classe (générique ou spécifique) peut être reliée à d’autres en exprimant davantage de séman-
tique qu’en l’absence d’héritage.
58 © Éditions Eyrolles
Identification
N’ajoutez pas d’identifiant à une sous-classe, car l’identifiant d’une sous-classe provient de
la surclasse.
Instances
Différents cas d’héritage peuvent être recensés en fonction de la population (instances) des
classes qui participent au graphe d’héritage [ADI 93].
Dans l’exemple précédent il faudra être capable de répondre aux questions suivantes : existe-
t-il un personnel qui ne soit ni navigant ni commercial ? Est-il possible qu’un navigant soit
aussi commercial ?
Nous étudierons cette classification à la section « Règles métier et contraintes ».
Héritage multiple
Relativement peu utilisé par les programmeurs objet, car complexe à mettre en œuvre, l’hé-
ritage multiple est le mécanisme qui autorise qu’une sous-classe hérite simultanément de
plusieurs surclasses. Dans l’exemple suivant, il permet de répondre à l’affirmative à la question :
est-il possible qu’un navigant soit aussi commercial ?
© Éditions Eyrolles 59
Bien que séduisant, ce mécanisme n’est implémenté dans aucune base de données objet et dans
très peu de langages. De plus, il est possible de s’en passer par l’intermédiaire des contraintes
sur un héritage simple.
Mise en pratique
Appliquez ce mécanisme aux différents cas de l’exercice 1.8 « L’héritage ».
Aspects temporels
Il est très fréquent d’avoir à prendre en compte des aspects temporels au niveau conceptuel. On
peut classifier trois modélisations : le moment, la chronologie et l’historisation.
Évitez de nommer un attribut temporel par un mot réservé du langage informatique (exemples :
date, month, day, etc.). Préférez des identificateurs plus parlants (exemples : date_nais-
sance, date_vente, mois_arrivee, etc.). Précisez toujours au niveau du dictionnaire de
données le format que vous attendez (jour/mois, jour/mois/année sur 4 positions, etc.).
60 © Éditions Eyrolles
Modélisation de chronologie
Il s’agit de modéliser des situations où le temps intervient de manière régulière (plannings,
emploi du temps, prévisions, statistiques, etc.). Le plus souvent, cet attribut sera considéré en tant
que classe. Les formats de cette donnée peuvent aussi être divers (jour, mois, jour/mois, etc.).
L’exemple suivant décrit les attributs de chronologie num_sem (de 1 à 52) et num_jour_an (de
1 à 365) qui identifient respectivement les classes Semaine et Jours. Ici, on suppose que la
précision d’une semaine est suffisante pour connaître l’activité des enseignes et des fournisseurs.
© Éditions Eyrolles 61
Modélisation de l’historisation
On utilise ce type de modélisation quand on désire conserver les valeurs antérieures d’un
attribut. Citons quelques exemples comme le montant d’un loyer (on désire connaître son évo-
lution) ou la valeur du coefficient bonus/malus d’un contrat d’assurance. En contre-exemple
(traité dans les exercices), le nombre de passagers d’un vol donné sera plutôt traité comme une
chronologie.
Alors que Merise/2 dispose d’un artifice pour noter l’historisation (symbole H sur un lien d’as-
sociation), l’historisation avec UML peut s’apparenter à de l’identification relative et donc
s’implémenter à l’aide d’une association d’agrégation forte (composition).
L’exemple suivant décrit deux historisations modélisées par une composition (une classe-asso-
ciation aurait aussi pu convenir). La classe Contrats permettra de lister les différents contrats
au cours du temps entre un supermarché et un fournisseur. La classe Gerances permettra de
faire évoluer l’appartenance d’un supermarché à une enseigne.
62 © Éditions Eyrolles
Mise en pratique
Utilisez ces aspects temporels pour :
●● gérer l’historique des coupes du monde de football (suite de l’exercice 1.1 « La déroute des
Bleus ») ;
●● faire évoluer le prix d’un produit et son taux de TVA (suite de l’exercice 1.3 « Les lignes
de facture ») ;
●● modéliser le cycle de vie des véhicules dans l’exercice 1.9 « Les cartes grises ».
© Éditions Eyrolles 63
La démarche à adopter
La première étape de conception est la mise en place du dictionnaire des données. Vous devrez
lister, de manière minimale, les attributs à stocker en rendant vos phrases élémentaires et sans
formuler des propositions incomplètes, redondantes, contradictoires ou fausses.
On peut modéliser Client, Produit et Fournisseur en tant que classe. Achat sera la
classe-association reliant Fournisseur au couple (Client, Produit).
Propositions incomplètes
Il ne doit pas exister de proposition incomplète. Ainsi toute proposition mettant en jeu plu-
sieurs classes « Un logiciel est installé par un département sur un serveur. » risque d’être
incomplète. Vous devrez préciser cet événement en considérant les classes deux à deux.
●● « Un département peut-il installer tout logiciel ? »
64 © Éditions Eyrolles
Il est peu probable que la réponse à chacune de ces propositions soit « oui ». Vous traduirez ainsi
chaque proposition en associations binaires en incluant éventuellement des classes-associations.
© Éditions Eyrolles 65
Autrement dit, ces attributs doivent être placés dans des entités secondaires associées à
l’entité primaire que constitue la personne. On aura donc trois entités supplémentaires :
l’une pour les téléphones, l’autre pour les adresses et la troisième pour les e-mails. Notez
que cette conception induit de multiples avantages parmi lesquels chaque personne peut
avoir un nombre indéterminé de téléphones (fixe, fax ou GSM…), plusieurs adresses et
une multiplicité d’e-mails, ce qui est courant !
Le fait de mettre tous les attributs de contacts dans une seule et même entité « personne
physique » contribue à créer des tables obèses dont les performances seront catastro-
phiques lors de la montée en charge de la base.
À lire sur le sujet : http://blog.developpez.com/sqlpro/p10070/langage-sql-norme/base-
de-donnees-et-performances-petites/.
Quelques conseils
Afin de rendre optimal un schéma conceptuel (minimiser les modifications à opérer avant de
créer des tables et index), quelques principes doivent être adoptés.
Décomposez si nécessaire
Décomposez tout attribut dont la structure est complexe en autant d’attributs que nécessaire.
Chacun de ces attributs devra être indécomposable (atomique). L’exemple le plus marquant est
l’adresse normée dont chaque champ possède une sémantique propre.
Ainsi, préférez l’utilisation de la classe Adresse à l’attribut de même nom. D’une part, cette
classe pourra être connectée à différentes autres classes (Client, Fournisseur, Succur-
salle, etc.). D’autre part, il sera possible d’indexer différentes colonnes pour faciliter des
recherches dans la base de données (sur le code postal, le nom d’une rue, etc.).
66 © Éditions Eyrolles
Pour compléter cette modélisation, il faudrait connecter la classe Ville à la classe Adresse.
© Éditions Eyrolles 67
Le ventilateur
Afin d’éviter le piège dit « du ventilateur », soignez vos parcours d’associations (particulièrement
pour les liens à terminaison *) et suivez la hiérarchie.
Dans le premier exemple, s’il est vrai qu’un employé est embauché par une entreprise com-
posée de départements, il apparaît aussi qu’il est impossible de savoir à quel département est
rattaché chaque employé (lien Composer à terminaison *). En réorganisant la hiérarchie de
ces classes, ce problème est résolu.
68 © Éditions Eyrolles
Dans le second exemple, s’il est vrai qu’un serveur est responsable de plusieurs tables, il appa-
raît aussi qu’il est impossible de savoir quel serveur a encaissé une note (lien planning à
terminaison *). Une association supplémentaire résout ce problème.
L’abîme
Le piège de « l’abîme » concerne la présence de multiplicités minimales à zéro sur le parcours
de lecture d’associations entre deux classes reliées indirectement.
Dans l’exemple suivant, la multiplicité 0..1 du lien gestionnaire signifie que certains ser-
veurs peuvent être anonymes en termes de propriétaire. Pour remédier à ce risque de perte
d’informations, il suffit de rajouter un lien d’association rendant le parcours plus direct.
© Éditions Eyrolles 69
70 © Éditions Eyrolles
Concernant le second exemple, le lien embaucher peut sembler redondant. Le problème vient
d’un risque d’abîme en ne sachant pas de quelle entreprise un représentant dépend du fait que
ce dernier peut ne pas être rattaché à une succursale.
© Éditions Eyrolles 71
Données ●● Tout passager d’un vol commercial dispose d’un siège numéroté.
prépondérantes ●● Un client cumule des miles à chaque voyage.
Données et un peu de ●● Un passager peut embarquer avec un bagage pas trop volumineux ni trop lourd.
traitement ●● Un passager peut disposer ses affaires dans un coffre à bagages.
Traitements ●● Le solde du compte du client ne doit pas être négatif pour pouvoir commander un billet.
prépondérants ●● Le montant du billet est débité sur le compte du client dès la commande.
Les données sont prépondérantes, car les attributs num_siege, nom_client et nombre_
miles apparaissent assez facilement.
Un peu de traitement est mélangé avec des données lorsqu’il faut approfondir certaines ques-
tions telles que « Doit-on stocker le volume ou le poids du bagage à main des passagers ? »,
« Doit-on connaître la contenance ou la charge limite d’un coffre à bagages utilisé lors du
voyage ? ». Peut-être des attributs tels que masse_bagage_main, masse_max et volume_
max devront être pris en compte.
Les traitements sont prépondérants lorsqu’il s’agit de processus dépendants de la valeur de
certains attributs déjà existants ou mettant à jour de tels attributs.
d’une autre classe reliée par une association. Concept analogue au « private » des
langages objet, il ne peut être implémenté que par programmation. Dans l’exemple
suivant, l’association prefere vise à interdire que tout candidat puisse connaître ses
électeurs ;
●● association dérivée : déductible de plusieurs autres associations. Préfixée par le symbole /,
grâce à une clé. L’exemple suivant est extrait de l’article Applying UML and Patterns: UML
Class Diagrams de C. Larman (disponible sur http://www.informit.com). Le qualificateur
itemID enrichit l’identifiant de la classe Product Catalog. Ainsi, à tout couple (numéro
de produit, itemID) est associé une seule description.
72 © Éditions Eyrolles
Les associations navigables ne sont pas significatives du point de vue des données, mais des
traitements.
Les associations dérivées peuvent être perçues comme redondantes, mais si elles doivent
être définies, elles devront être considérées comme des associations binaires standard.
Les associations qualifiées doivent être mises en œuvre par le concept d’agrégation forte
(composition).
© Éditions Eyrolles 73
Quelles que soient les contraintes que vous définirez dans vos diagrammes conceptuels,
aucune modification structurelle ne sera répercutée dans les schémas relationnels générés.
Toute contrainte devra être implémentée au niveau du code SQL (par contraintes, déclen-
cheurs ou procédures cataloguées).
Pour les contraintes personnalisées, des rôles doivent être utilisés au niveau des associations
qui seront concernées par une contrainte.
La spécification UML 2 ne propose pas beaucoup de contraintes prédéfinies et bien peu d’ou-
tils les incluent. En contrepartie, toute contrainte peut être écrite soit à l’aide du langage OCL
(Object Constraint Language), soit en langage naturel.
Graphiquement, une contrainte est un texte encadré d’accolades qui s’applique au niveau d’un
attribut, d’un rôle, ou entre associations nommées.
Les contraintes qui s’appliquent à un ou entre plusieurs éléments peuvent être notées de diffé-
rentes façons [AUD 09] :
●● en plaçant la contrainte à côté d’un attribut ou à l’extrémité d’une association ;
●● en plaçant la contrainte sur une flèche en pointillés joignant les deux éléments de modèle
74 © Éditions Eyrolles
●● en utilisant une note reliée, par des traits en pointillés, à chacun des éléments de modèle,
subissant la contrainte commune, quand cette contrainte s’applique sur plus de deux éléments
de modèle.
Contraintes prédéfinies
Les contraintes prédéfinies se notent en général à l’extrémité d’un lien d’association (au même
niveau que le rôle). Les plus intéressantes dans un contexte de bases de données sont :
●● {subsets nom_rôle} exprime l’inclusion d’une association par rapport à une autre ;
●● {xor} qui indique le OU exclusif entre objets reliés par deux associations.
Dans l’exemple suivant, la contrainte xor précise qu’un consultant est soit associé à un projet,
soit à une formation, mais jamais aux deux simultanément.
Dans l’exemple suivant, la contrainte subsets exprime le fait que les formations effectuées
par un stagiaire ont été préalablement listées au niveau de l’association vœux.
© Éditions Eyrolles 75
En l’absence de ces contraintes (cas le plus général et celui par défaut), la terminaison d’une
association est dite de type set (chaque objet relié n’est présent au plus qu’une seule fois
dans l’association).
Pour formaliser toute autre contrainte, vous pouvez utiliser le langage OCL.
76 © Éditions Eyrolles
L’exemple suivant s’inspire de [MAK 08] et présente deux contraintes basées sur des ensembles
d’objets.
© Éditions Eyrolles 77
La règle OCL (R1) qui décrit la contrainte des clauses du contrat est la suivante :
context Vehicule inv R1 :
self.implique → forAll
(s | s.option → forAll
(c | c.prevoit → exists(co |
➥co.beneficiaire=self)))
Contraintes d’héritage
L’héritage a été présenté à la section « Les associations plus complexes » avec l’exemple de la
surclasse Personnel qui permet de spécialiser les sous-classes Navigant et Commercial.
Dans tout graphe d’héritage, différents cas peuvent être recensés en fonction des instances des
classes. Ces cas traduisent des contraintes que Merise/2 nommait la partition (appelée aussi
exclusion et totalité). En considérant les personnels comme navigants et commerciaux, cette
population peut être composée :
●● de navigants ou commerciaux exclusivement (cas A) ;
78 © Éditions Eyrolles
Contraintes prédéfinies
Le tableau suivant illustre, pour chaque cas d’héritage, la contrainte à mettre en œuvre dans
le formalisme Merise et la notation UML. Notez que l’absence de contrainte dans un graphe
d’héritage n’a pas la même signification dans Merise/2 et dans UML. Le premier autorise
qu’une occurrence appartienne à plusieurs entités sous-types. UML considère que par défaut
un objet n’existe que dans une classe pour un niveau de hiérarchie donné.
Couverture Non-couverture
Disjonction (cas A) (cas B)
Merise/2 : Partition (XT) Merise/2 : Exclusivité (X)
UML : {complete,disjoint} UML : {incomplete,disjoint} (par défaut)
Non-Disjonction (cas C) (cas D)
Merise/2 : Totalité (T) Merise/2 : pas de contrainte (par défaut)
UML : {complete,overlapping} UML : {incomplete,overlapping}
Le schéma suivant précise l’association d’héritage en indiquant qu’il n’existe pas de personnel
qui ne soit ni navigant ni commercial.
© Éditions Eyrolles 79
À titre d’exemple, les écritures suivantes décrivent la contrainte de partition (cas A) entre les
navigants et les commerciaux. La première règle, attachée à la classe Navigant, signifie
qu’un navigant ne peut pas être commercial. Notez l’utilisation de la fonction allInstances
qui retourne pour un type donné l’ensemble de ses instances, incluant aussi les instances de
ses sous-classes.
context Navigant inv Partition1 :
Commercial.allInstances.nup®excludes(self.nup)
Mise en pratique
Rendez-vous à l’exercice 1.10 « Les contraintes » pour écrire formellement les expressions
OCL afin d’enrichir différents schémas.
Règles de validation
La notation UML ne propose aucun moyen de s’assurer de la cohérence d’un diagramme de
classes. Cela est particulièrement pénalisant pour les diagrammes qui visent à modéliser une
base de données. Les règles que vous devrez adopter s’inspirent des règles de validation et de
normalisation introduites avec les modèles entité-association et la méthode Merise. La plupart
de ces règles datent du milieu des années 1970. Ces règles sont majoritairement basées sur les
dépendances fonctionnelles.
Il est aisé de transposer ces règles à vos diagrammes de classes UML de manière à obtenir
automatiquement un schéma relationnel de qualité, en limitant les risques d’erreurs de modé-
lisation lourdes de conséquences au niveau de la base de données.
80 © Éditions Eyrolles
© Éditions Eyrolles 81
●● num_dossier → jour_depart ;
●● num_dossier → num_classe ;
●● num_dossier → num_voiture ;
●● num_dossier → num_siege ;
●● num_train → ville_depart (si on considère qu’un numéro de train désigne le même
trajet régulier) ;
●● num_train → heure_depart.
La première dépendance n’est pas optimale, car le nom d’un passager dépend davantage d’un
code client que des voyages qu’il a réalisés. Ainsi, il conviendrait d’introduire un identifiant
pour le passager et les dépendances induites seraient :
●● num_dossier → num_client (si on considère que tous les passagers sont « fichés ») ;
●● num_client → nom_passager.
Pour connaître la composition de chaque train (voiture 12 en tête, voiture 14 en position 2,
etc.), il convient de déterminer de quoi dépend la position d’une voiture : du trajet à un jour
donné. Ces deux attributs interviennent donc dans l’identifiant qui nécessite un troisième
composant (le numéro de la voiture ou la position) afin de pouvoir déterminer le quatrième
(la position ou le numéro de la voiture). Les deux dépendances suivantes sont donc équiva-
lentes :
●● num_train, jour_depart, num_voiture → position ;
●● num_train, jour_depart, position → num_voiture.
Vérification
Non-redondance
Un attribut ne figure qu’à un seul endroit du diagramme : soit dans une classe, soit dans une
classe-association.
Si vous découvrez sur un diagramme des attributs qui se répètent dans différentes classes,
deux cas se présentent.
●● L’attribut identifie une classe à un endroit et il est répété en tant que clé étrangère.
●● L’attribut ne joue pas le rôle d’identifiant et il est redondant partout où il est dupliqué.
Le diagramme UML suivant trouvé sur le Web présente des redondances au niveau des iden-
tifiants. En réalité, ce diagramme décrit un modèle relationnel et non un modèle conceptuel.
D’un point de vue conceptuel, ce diagramme n’est pas correct, mais d’un point de vue rela-
tionnel, il ne pose pas de problème au premier abord.
82 © Éditions Eyrolles
Bien que la normalisation soit un processus qui concerne le modèle relationnel, il est toutefois
intéressant de l’étudier au niveau conceptuel, de sorte à produire des diagrammes de classes
optimaux. Vous trouverez dans la littérature et sur le Web un très grand nombre de définitions
mathématiques des formes normales. Ne comptez pas sur moi ni pour en rajouter ni pour sou-
ligner les incohérences de l’une ou de l’autre. Je vais simplement illustrer chaque cas par un
exemple. Vous devrez transposer vos problématiques à chaque exemple présenté.
Les attributs multivalués (associés à plusieurs valeurs comme un tableau ou une liste) sont
proscrits de tout schéma conceptuel. En revanche, un schéma conceptuel doit être composé
© Éditions Eyrolles 83
d’attributs monovalués pouvant contenir au plus une valeur de tout type (chaîne de caractères,
date, entier…).
L’exemple suivant modélise le fait qu’un client dispose de trois e-mails au plus. Les deux
premières modélisations ne respectent pas la première forme normale. La première considère
l’e-mail comme un tableau, tandis que la seconde utilise plusieurs attributs de même sens.
Au final, les tables issues de cette modélisation seront difficilement indexables, contiendront
nombre de valeurs nulles et les requêtes à écrire seront infiniment plus complexes que dans le
cas d’une solution normalisée.
Le diagramme suivant ne respecte pas la deuxième forme normale, car plusieurs attributs de
la classe-association ne dépendent pas simultanément du couple (id_cli, immatriculation).
84 © Éditions Eyrolles
En raisonnant avec les dépendances fonctionnelles, toutes celles qui concernent les attributs
d’une classe-association doivent être élémentaires (minimales en partie gauche).
●● id_cli, immatriculation → date_achat minimale si on considère qu’un client ne
peut pas racheter une voiture lui ayant déjà appartenu.
●● id_cli, immatriculation → mise_circulation non minimale, car la date de première
mise en circulation ne dépend pas du client (immatriculation → mise_circulation).
●● id_cli, immatriculation → km minimale si on désire conserver le kilométrage lors
de l’achat.
●● id_cli, immatriculation → total_km non minimale, car le kilométrage total ne
dépend que du véhicule (immatriculation → total_km).
●● id_cli, immatriculation → tel_cli non minimale, car le téléphone du client ne
dépend pas du véhicule (id_cli → tel_cli).
En appliquant ces dépendances au diagramme précédent, on réduit la complexité de la classe-
association.
© Éditions Eyrolles 85
La limitation de ce diagramme réside dans le fait qu’un client ne peut racheter sa voiture dans
le temps. Pour pallier cette limitation, utilisez l’identification relative pour exprimer le fait
qu’un achat est caractérisé par un couple (véhicule, date) qui ne peut être associé qu’à un seul
client.
La classe suivante ne respecte pas la troisième forme normale, car il existe une dépendance
entre deux attributs non identifiants (id_constructeur → marque). Il convient de préserver
cette dépendance dans une autre classe.
86 © Éditions Eyrolles
En raisonnant avec les dépendances fonctionnelles, il faut que toutes les dépendances soient
directes (issues de l’identifiant primaire de toute classe).
●● immatriculation → id_constructeur est directe, un véhicule est associé à un
constructeur.
●● immatriculation → marque n’est pas directe, car la marque dépend davantage de
l’identifiant du constructeur.
●● id_constructeur → marque est directe et donc il faut ajouter une classe modélisant
cette dépendance.
L’éventuelle limitation de ce diagramme réside dans le fait qu’une même appellation puisse
être partagée par plusieurs véhicules. Ainsi, cet attribut devrait être considéré comme un
libellé qui doit être associé à un identifiant.
© Éditions Eyrolles 87
88 © Éditions Eyrolles
D’après moi, cette forme normale ne doit pas être mise en œuvre d’un point de vue conceptuel.
Elle est davantage à étudier au niveau logique ou physique afin d’éviter d’éventuelles redon-
dances et anomalies de mises à jour.
En considérant que la catégorie d’un avion est en relation directe avec son envergure, l’asso-
ciation appartient ne respecte pas la forme normale domaine-clé, car suivant la valeur de
l’envergure de chaque avion, on pourrait déduire cette information.
© Éditions Eyrolles 89
La classe suivante ne respecte pas la quatrième forme normale, car il existe des dépendances
entre des couples de classes. Il convient de préserver ces dépendances par le biais d’associations
binaires.
Si la modélisation initiale n’avait pas prévu le fait qu’un pilote puisse détenir des qualifica-
tions indépendamment des avions sur lesquels il est apte à voler, la cinquième forme normale
n’aurait pas été respectée. Le diagramme suivant pallie cet éventuel inconvénient.
90 © Éditions Eyrolles
Mise en pratique
Respectez ces principes pour résoudre les exercices 1.11 « La carte d’embarquement », 1.12
« Deux cafés et l’addition ! », 1.13 « La thalasso », 1.14 « Le centre de plongée » et 1.15
« L’élection présidentielle ».
Bilan
Après avoir examiné différents formalismes de modélisation de bases de données (le modèle
de Chen, le MCD de Merise et ses extensions Merise/2), la notation UML semble très bien
adaptée pour les raisons suivantes.
●● UML propose autant de concepts que Merise/2, avec la possibilité de définir en plus des
stéréotypes personnalisés.
●● La représentation de certaines contraintes sur des associations n-aires est implicite avec
les classes-associations.
●● L’utilisation de la notation UML permet aux concepteurs de travailler dans un environne-
ment plus évolutif, notamment avec la possibilité d’interfacer plus facilement les langages
évolués C++ ou Java.
Exercices
Pour que vos diagrammes soient le plus en phase avec les corrigés (en annexes), le nom des
attributs est indiqué pour la plupart des exercices en police Courier.
© Éditions Eyrolles 91
92 © Éditions Eyrolles
Associations binaires
Qui dit libellé, dit identifiant, et qui dit identifiant, dit classe. Voilà donc les premières classes
simplement découvertes à partir des attributs initiaux.
© Éditions Eyrolles 93
Il reste à caser :
●● jour_match, heure_match et score qui caractérisent une rencontre, concept qui n’est
pas encore représenté (classe Match à définir, donc identifiant à ajouter, car aucun de ces
attributs ne peut assurer ce rôle) ;
●● classement qui concerne une équipe (et non un groupe). En effet chaque équipe doit être
associée à un seul classement, alors qu’un groupe peut être associé à plusieurs classements
(4 par groupe en fait).
Les six classes du schéma sont à présent au complet. Vous devez les relier par des associations
judicieusement choisies.
Classe-association
Si vous savez vous servir d’une classe-association, vous pouvez réfléchir à l’évolution de ce
schéma afin de prendre en compte l’affichage des résultats dans différentes langues. Ainsi,
le nom de l’équipe d’Afrique du Sud (lib_equipe) doit pouvoir être associé à différents
libellés, par exemple « South Africa » en anglais ou « África del Sur » en espagnol. Utilisez
la classe Langue constituée d’un identifiant id_langue (par exemple, fr) et d’un libellé
lib_langue (par exemple, France).
Historique
Modifiez le diagramme pour mémoriser l’historique des coupes du monde (qui a lieu tous
les 4 ans : annee), notamment pour savoir quelle était le pays organisateur et la composition
94 © Éditions Eyrolles
des groupes de l’époque. Notez que le groupe n’est pas composé selon l’ordre alphabétique.
En effet, la position (position) dans le groupe s’effectue selon le classement lors du 1er tour.
Sachez également que cet événement ne peut être organisé que par 2 pays maximum.
Inscriptions
En début d’année, chaque salarié remplit une fiche sur laquelle il indique son nom (nom), son
e-mail (mail), le code de son entreprise (codent) et la liste des formations qu’il envisage de
© Éditions Eyrolles 95
suivre dans l’année (6 maximum parmi les 450 présentes au catalogue). Un code lui est ensuite
automatiquement attribué (idsta).
Chaque formation est définie par un code (codef), un titre (titref) et une durée (duree),
et placée sous la responsabilité d’un consultant caractérisé par un code, un nom et un e-mail
(idemp, nomemp et mailemp).
Tout consultant doit être disponible un jour par semaine (jsem) et durant une plage horaire
définie (hrens) afin de renseigner le public à propos des formations dont il est le responsable.
Plannings
1. Modifiez le schéma pour qu’un consultant puisse être interrogé à différents moments de la
semaine tout en respectant un seul créneau par formation qu’il supervise.
2. Modifiez le schéma pour qu’un consultant puisse donner des renseignements sur une
formation qu’il supervise à différents moments de la semaine.
96 © Éditions Eyrolles
Concernant le prix et le taux de TVA, distinguez les conditions initiales (aucune facture n’est
émise le matin du premier jour de l’exercice comptable) de la facturation courante.
Stages
Chaque stage référencé dans le catalogue peut se dérouler dans différentes villes et à diffé-
rentes périodes. Les classes principales sont Stage, Ville et Periode.
© Éditions Eyrolles 97
Cote automobile
Il s’agit de référencer les cotes des véhicules d’occasion selon la marque, le modèle et l’année.
Prenez en compte également les autres caractéristiques (type de carrosserie, énergie, émissions
de carbone et nombre de chevaux fiscaux).
98 © Éditions Eyrolles
N’oubliez pas que vous devez être en mesure d’imprimer à la demande ce tableau.
Associations binaires
Complétez le diagramme suivant pour modéliser :
●● le nom du propriétaire de chaque compte et la date d’ouverture du compte ;
●● les mandataires (clients non propriétaires) des comptes et leurs divers droits asso-
ciés (retrait, virement ou clôture). Notez qu’un mandataire ne peut pas gérer plus de
5 comptes.
© Éditions Eyrolles 99
Identification relative
Modélisez l’historique des rendez-vous de chaque client avec le conseiller rencontré et la date
de dernier entretien. Il est intéressant de connaître les différents produits financiers qui auront
été vendus au client lors de ces rendez-vous. Chaque conseiller perçoit une prime en fonction
du produit vendu pour toute souscription.
Identification artificielle
Modélisez les virements entre comptes. Il s’agit de connaître le montant en euros, le client
initiateur et la date de l’opération.
1.6 Le RIB
Positionnez-vous au niveau de la Banque de France en modélisant les comptes des clients de
tous les organismes bancaires. Considérez notamment les attributs suivants :
●● nom_banque, nom_agence, num_compte, cle_RIB, nom_client ;
Sessions
Les sessions de formations sont assurées par des formateurs en interne (c’est un consultant qui
n’est pas forcément le responsable du cours). Chaque session ne dépasse pas 5 jours.
À la fin de chaque session, chaque stagiaire note la formation qu’il a suivie (notec).
Il faut mémoriser la date du cours (datec) et l’identité du formateur de la session.
Salles
Chaque session se déroule dans une des salles de l’organisme de formation. Les locaux de
l’organisme sont composés de plusieurs étages. Chaque salle est numérotée et dispose d’un
nombre de places limité (capacite). Il faut au minimum 2 stagiaires inscrits et aucune salle
ne dépasse 12 places.
Des techniciens s’occupent de la configuration des salles à chaque session. Pour chaque session,
le technicien résume ses actions dans un mémo (memo).
Il est intéressant de connaître le temps de présence (temps_presence) de chaque technicien
passé pour chaque jour de la session.
1.8 L’héritage
Organisme de formation
Dans quelle mesure l’héritage permet de préciser le diagramme de l’exercice 1.7« l’organisme
de formation »?
Comptes bancaires
Comment pouvez-vous utiliser l’héritage pour préciser le diagramme de l’exercice 1.5 « Les
comptes bancaires » ?
Ancien régime
Le premier document à analyser est le suivant. Lorsqu’un véhicule change de propriétaire son
immatriculation est modifiée.
Modélisez un premier schéma en fonction des attributs que vous devez considérer :
●● immatriculation, date_immat, mise_circu, nom_departement, taxe_region ;
Coût du cheval
Modélisez le fait que chaque région (nom_region) fixe annuellement (annee) par délibé-
ration du conseil régional la valeur du cheval fiscal (euros_cv) rentrant en compte dans le
calcul de la taxe du certificat d’immatriculation.
Nouvelle numérotation
Deux systèmes cohabitent actuellement en France. L’ancien système basé sur un comptage
départemental, en place depuis 1950, est désormais remplacé depuis le 15 avril 2009 par un
système entièrement national.
Ce nouveau numéro est attribué définitivement au véhicule, jusqu’à sa destruction ou son
exportation. La plaque intègre, sur sa partie droite, un identifiant territorial composé d’un
numéro de département et du logo de la région correspondante. Cet identifiant est choisi par le
propriétaire et n’a pas obligatoirement de rapport avec le lieu de résidence.
Contrôles techniques
Indépendamment du système d’immatriculation, chaque véhicule doit passer tous les deux
ans un contrôle technique. Plusieurs enseignes existent et différents centres de contrôle
détenant un numéro d’agrément sont présents en France. Modélisez l’historique de ces évé-
nements en prenant en compte de nouveaux attributs : limite_echeance, nom_enseigne,
adresse_centre, nom_centre, num_agrement, date_visite, num_visite et num_
carte_grise.
L’organisme de formation
●● Un consultant doit proposer entre 2 et 4 créneaux par semaine pour enseigner un cours.
●● Un technicien doit rédiger un mémo de Ses actions pour toute formation qu’il prend en charge.
●● Le nombre de stagiaires ne doit pas dépasser la capacité d’une salle pour toute session.
Vols catalogue
Les autres attributs que vous devez considérez apparaissent clairement sur le document et
sont les suivants : nom_client, prenom_client, num_vol, jour_mois, heure_dep,
heure_emb, nom_aeroport, num_porte et num_siege. Un aéroport est identifié par un
code international (par exemple, Paris Orly est codifié « LFPO » par l’OACI, l’Organisation
de l’aviation civile internationale).
Distinguez un vol « catalogue » d’un vol réel. Le vol réel transporte plusieurs clients, tandis
que le vol catalogue renseigne les caractéristiques d’un trajet indépendamment du jour.
Vols réels
Modifiez le précédent diagramme pour :
●● calculer des statistiques des retards en mémorisant les heures de départ et d’arrivée réelles
(dep_reel, arrivee_reelle) ;
●● qu’un client puisse réserver plusieurs sièges pour le même trajet ;
●● connaître le planning annuel de chaque vol. Dans l’exemple suivant, le vol AF6146 n’est
pas ouvert du samedi 16 au mardi 19. L’heure d’arrivée catalogue (heure_arr) est égale-
ment à prendre en compte.
repas) ;
●● le taux de TVA dépend de chaque produit ;
1.13 La thalasso
Les principaux attributs sont les suivants : num_client, num_sejour, nom_client, jour_
soin, heure_soin, num_vestiaire, lib_soin et lib_lieu.
Un type de soin n’a lieu que dans un seul espace et il peut être effectué plusieurs fois le même
jour.
Chaque sortie d’un bateau se réalise sur l’un des sites existants. Tout site est limité en nombre
de mouillages (lib_site, nb_bateau_max). La taxe journalière de chaque site est variable
en fonction de la saison (mois) et du site. Les sites ne sont pas ouverts à tous les bateaux.
Chaque bateau ne peut effectuer plus de quatre sorties par jour. Les dates et heures de chaque
sortie doivent être mémorisées (date_sortie et heure_sortie).
Lors de chaque sortie, plusieurs plongeurs sont embarqués. Ces plongeurs composent dif-
férentes palanquées (groupe d’au maximum cinq plongeurs réalisant la même plongée).
Un plongeur peut être rattaché à un club extérieur pour lequel des accords ont été passés
avec l’organisateur. Chaque plongeur doit être enregistré (num_brevet, nom_plongeur,
niveau_plong) et on doit pouvoir connaître le chef de chaque palanquée. Certaines palan-
quées sont dirigées par des moniteurs du club.
Le prix de chaque plongée est indépendant du site, mais peut varier selon le mois. Il existe
deux tarifs (prix_plongee) : en autonome et accompagné d’un des moniteurs du club. À la
fin de chaque plongée, le chef de palanquée annonce la durée d’immersion, ainsi que la profon-
deur maximale atteinte au cours de la plongée (duree_plongee et profondeur_max). Ces
deux chiffres doivent être consignés.
Il est important de connaître le leader courant de chaque parti. Les principaux attributs à
considérer sont les suivants : nom_politicien, prenom_politicien, date_naiss, nom_
parti, annee_creation, annee_fin, date_entree et date_sortie.
Figure 1-114. Historique des résultats d’un parti. Extrait du site http://fr.wikipedia.org
Titre suprême
Le ministère de l’Intérieur propose d’analyser les résultats des premier et second tours de
l’élection au niveau national, par région ou par département.
Quelle que soit la précision choisie, le résultat du premier tour est présenté sous la forme suivante.
Le niveau logique
Ce chapitre détaille la deuxième étape de conception d’une base de données : il s’agit d’éla-
borer un schéma logique (modèle relationnel) ; la dernière étape étant la création des tables
(génération de scripts SQL) puis des vues (requêtes SQL).
Les avantages d’utiliser un modèle logique de données sont nombreux :
●● rester indépendant du SGBD (mais plus proche des tables) ;
●● réduire la complexité du modèle (décider de ne pas créer certaines tables déduites toutefois
du modèle conceptuel) ;
●● renommer des objets (colonnes, clés, contraintes et tables) ;
notamment) ;
●● calculer la volumétrie prévisionnelle.
Ce chapitre se divise en trois parties. La première partie décrit les concepts du modèle rela-
tionnel. La deuxième partie présente les règles qui permettent de dériver un schéma logique
à partir d’un modèle conceptuel. La dernière partie traite de la normalisation et du calcul de
volumétrie.
Deux autres aspects importants du modèle relationnel existent. Le premier concerne l’inté-
grité des données qui est abordée au chapitre 3 (contraintes SQL). Le dernier aspect recouvre
la manipulation des données au sens des opérateurs relationnels (algèbre relationnelle, base
mathématique du langage de requêtes SQL). Vous trouverez de nombreuses ressources sur le
Web et dans la bibliographie.
●● Attribut : représentation d’une information atomique qui préfigure une colonne d’une
table. Un domaine de valeurs devrait être défini ainsi que d’éventuelles règles de validation
(contraintes).
●● Clé primaire : attribut(s) identifiant une relation qui préfigure(nt) la primary key de la table.
●● Clé étrangère : attribut(s) qui référence(nt) une tierce relation, préfigure(nt) une foreign key
de la table.
Le diagramme suivant illustre les principaux concepts du modèle relationnel. Trois relations
simples sont présentées (aucune des clés primaires ou étrangères n’est composée et il n’y a pas
plusieurs clés étrangères par relation). Chacune de ces relations dispose d’une clé primaire
(notée pk par l’outil Power AMC). Les clés étrangères sont notées fk.
La relation Aeroport dispose d’une clé étrangère (attribut Vil_idville) qui référence la
relation Ville. La relation Ville dispose d’une clé étrangère (attribut idpays) qui référence
la relation Pays. Le nom des contraintes de clés étrangères apparaît ici. En revanche, le nom
des autres contraintes (clé primaire, unique ou de vérification) est absent de cet affichage.
Notez qu’une clé étrangère peut porter un autre nom que le nom de la clé primaire (ou unique)
référencée.
Une fois ce modèle établi (automatiquement par un outil de conception), vous pouvez le modifier
à loisir. Changer le nom d’un attribut (colonne), le type, etc.
Vous trouverez de nombreux formalismes graphiques qui reprennent ces fondamentaux. Le
diagramme suivant, issu du logiciel Access de Microsoft, illustre cinq relations et quatre clés
étrangères. Les clés primaires sont indiquées en gras.
Le diagramme DB Designer suivant contient trois relations et deux clés étrangères. Les clés
primaires sont iconisées, tandis que les clés étrangères sont suffixées par fk.
Le choix de l’outil Rational Rose (inclus dans l’offre Data Modeler d’IBM) est de préfixer les
attributs clés : pk pour les clés primaires, fk pour les clés étrangères et pfk pour les attributs
jouant les deux rôles.
Depuis la version 7, SQL Server propose un outil pour construire un modèle de tables. Les
clés primaires sont notées à l’aide d’une icône clé, les clés étrangères ne sont pas explicitement
distinguées.
Du conceptuel au relationnel
Cette partie présente les règles qui permettent de créer un schéma relationnel à partir
d’un modèle conceptuel exprimé par un diagramme de classes UML. Ces règles sont
surtout basées sur l’existence des associations et la valeur des multiplicités de chaque asso-
ciation.
Bien que ces règles soient, en principe, correctement programmées dans tout outil digne
de ce nom, il est nécessaire de vérifier le schéma résultant avant de créer votre base.
Ainsi, la connaissance de ces règles vous permettra de vérifier la cohérence des relations
générées.
En appliquant cette règle à l’exemple suivant, la relation Aeroport préfigure la table de même
nom.
L’attribut identifiant de la relation parent migre dans la relation enfant et devient clé étrangère
dans la relation fils issue de l’association.
Appliquons cette règle à l’exemple suivant, il vient deux clés étrangères. Notez qu’une classe
peut être considérée à la fois parent pour une association et enfant pour une autre.
Le fait que la multiplicité minimale du lien côté parent soit 0 ou 1 n’a pas d’influence sur la
structure du schéma relationnel généré. Seul le modèle physique permet de différencier ces
deux cas en ajoutant une éventuelle contrainte NOT NULL appliquée à la colonne clé étran-
gère.
Toute association plusieurs-à-plusieurs devient une relation qui porte le nom de l’association.
La clé primaire de cette relation est composée par le couple des identifiants des deux relations
(initiales) qui sont déduites des classes connectées à l’association initiale. Chaque attribut clé
primaire de la nouvelle relation est une clé étrangère vers la relation initiale associée.
De l’application de cette règle à l’exemple suivant, émanent deux nouvelles relations. L’iden-
tifiant de chaque nouvelle relation est composé du couple d’identifiants des deux relations
initiales. Les clés étrangères relient la nouvelle relation à ses deux relations initiales associées.
Le fait que la multiplicité minimale d’un lien soit 0, 1 ou n (n>1) n’a pas d’influence sur la struc-
ture du schéma relationnel généré. Seule une programmation permettra de mettre en œuvre
une telle contrainte.
Pour toute association un-à-un, considérez la relation du côté de la multiplicité 1..1 en tant
que parent et appliquez la transformation d’une association un-à-plusieurs. Si aucune mul-
tiplicité n’a cette valeur (les deux valant 0..1), appliquez la transformation d’une association
un-à-plusieurs sans considérer une relation en tant que parent en particulier. Si les deux mul-
tiplicités valent 1..1, vous devriez visiblement modifier votre schéma en fusionnant les deux
classes en une seule…
Appliquons cette règle à l’exemple suivant, deux clés étrangères doivent être générées. La
première clé étrangère (num_proj dans Collaborateur) qui concerne l’association un-à-
plusieurs devrait apparaître naturellement. En revanche, vous devrez vous assurer du bon
positionnement de la seconde clé étrangère (id_coll dans Projet).
En considérant ainsi la relation parent comme étant celle du côté de la multiplicité minimale 1,
vous réduirez considérablement le nombre de valeurs NULL dans les colonnes clés étran-
gères de vos tables.
Toute association réflexive doit être considérée comme une association binaire et en fonction
des multiplicités existantes, il convient d’adopter une des règles précitées.
Je précise que les associations réflexives suivent les mêmes règles de transformation :
• une association réflexive un-à-un conduit à une double clé et une assertion ;
• une association réflexive un-à-un conduit à une double clé ;
• une association réflexive un-à-un conduit à une table de jointure.
En renommant les colonnes clés étrangères provenant d’associations réflexives, vous amélio-
rerez considérablement, par la suite, la lisibilité de la table. Les rôles UML peuvent vous aider
dans ce sens. Dans l’exemple précédent, il convient de renommer par exemple id_emp2 par
id_mon_pote et id_emp3 par id_manager.
Vous devez vous demander comment dériver un schéma relationnel lorsqu’une classe-asso-
ciation est reliée à une autre classe. Eh bien, le plus naturellement du monde : en considérant
la classe-association comme une classe à part entière et en adoptant les règles précitées en
fonction des multiplicités de l’association à traduire.
Nous verrons plus loin quelques exemples qui incluent des classes-associations connectées à
d’autres classes.
Transformation de l’héritage
Il existe trois transformations possibles pour chaque association d’héritage.
Il n’existe pas de solution miracle et vous devrez choisir la meilleure option en fonction de
la nature de la contrainte qui concerne l’héritage (partition, exclusion, totalité ou absence de
contrainte).
La transformation par distinction d’une association d’héritage est la plus polyvalente. Sous
réserve de codage, elle permet d’implémenter n’importe quelle autre contrainte d’héritage
(partition, exclusion et totalité).
Le troisième exemple présente la transformation d’un héritage simple par push-up. Cette
solution permet d’implémenter toutes les contraintes, mais convient vraiment mieux lorsque
chaque personnel peut occuper plus d’un type d’emploi.
Le tableau suivant précise les options souhaitables pour chaque contrainte d’héritage. Quelle
que soit la solution que vous choisirez, vous devrez programmer la contrainte sous la forme
de directives SQL CHECK, déclencheurs ou à l’intérieur de vos procédures cataloguées (voir
le chapitre 3), sauf en ce qui concerne la transformation par distinction et lorsqu’il n’est pas
nécessaire d’assurer l’exclusivité.
La solution « universelle »
Il existe une transformation qui peut convenir à toute association binaire (un-à-un, un-à-
plusieurs, plusieurs-à-plusieurs et réflexive). Il s’agit de générer une nouvelle relation munie
de deux clés étrangères (qui préfigure la table d’association ou « table de jointure »). La clé
primaire de cette relation est composée soit par un des identifiants, soit par le couple des iden-
tifiants des deux relations initiales.
Appliquons cette règle à l’exemple de deux associations binaires. Deux relations doivent être
générées. L’association un-à-un est traduite par la relation diriger et l’association un-à-
plusieurs est traduite par la relation affecter.
Pour s’assurer qu’un collaborateur ne dirige qu’un projet, il conviendra d’ajouter, au niveau
physique, une contrainte UNIQUE sur la clé étrangère (id_coll) dans la table diriger.
Dans l’autre table d’association, la clé primaire id_coll permettra de s’assurer qu’un colla-
borateur ne puisse être affecté à plusieurs projets.
Ce principe de transformation est idéal lorsque les multiplicités de vos associations sont sus-
ceptibles de changer avec le temps (dans notre exemple, le fait qu’un collaborateur puisse
diriger plusieurs projets ou participer à différents projets). En ce cas, et même avec des données
en base, il suffira d’activer ou de désactiver telle contrainte ou telle clé.
Ainsi, pour l’association universelle de type un-à-un, il faut choisir la clé primaire de
la table de jointure qui peut venir indifféremment de l’une ou l’autre des entités. Mon
conseil est donc le suivant : prenez toujours celle de l’entité qui existe avant l’autre. Dans
l’exemple proposé, la table de jointure diriger se voit dotée d’une clé primaire venant
de l’entité Projet. C’est à mon sens une erreur, car il me semble difficile qu’un projet
existe dans votre entreprise, si vous n’avez aucun collaborateur !
Cette transformation est à éviter, car la table d’association qu’on obtiendra ne permettra aucun
contrôle de cohérence. Ainsi, avec ce schéma, il est possible d’installer un logiciel qui n’est pas
compatible avec un serveur ou qu’un département ne détient pas par exemple.
Il est évident que toutes les associations n-aires alourdissent les clés des tables d’asso-
ciation. Chercher donc à réduire le nombre de colonnes est important et lorsque l’on ne
peut pas le faire, il devient souvent intéressant de créer artificiellement une entité asso-
ciative (classe artificielle en UML) afin d’alléger la clé primaire ce qui est grandement
bénéfique pour les performances. Il faudra, dans ce cas, ajouter une contrainte d’uni-
cité pour l’ensemble des clés étrangères composant l’association. Cette technique rajoute
effectivement une colonne, mais allège bien des objets physiques sous-jacents à la table,
comme l’écriture de certaines requêtes. La plupart des outils de modélisation permettent
d’automatiser ce genre de transformation.
Dans la majorité des cas, il n’est pas utile de traduire cette relation en table. Elle est toutefois
indispensable au niveau conceptuel, car elle permet de faire migrer dans la table d’association
la colonne qui représente le jour de visite. Certains la traduiront pour disposer d’une table de
référence de dates, astuce qui permet de faciliter les requêtes interrogeant la base à propos de
dates où aucune visite n’a été réalisée.
Les classes qui ont une sémantique faible et qui ne sont reliées à aucune autre classe, à part
dans le cadre d’une association, sont en général de bons exemples de classes qui ne doivent
pas nécessairement être transformées en tables.
La question d’une entité DATE (ou parfois NOMBRE) paraît anodine, mais s’avère
cruciale.
Dans un modèle de données, il devrait toujours figurer une table des dates et une table des
nombres. En effet, un problème important à résoudre dans les requêtes est de retrouver
des données qui ne figurent pas dans la base. Pour cela, il faut artificiellement créer ces
données pour des ensembles continus. Par exemple, une table des dates sur quelques
siècles. Il devient alors facile et pertinent de retrouver des dates « absentes » des données
de production à l’aide d’une jointure externe droite sur la table des dates. Un exemple
que je donne en démonstration est celui d’un SAV ou je montre une table avec des lignes
d’appareils portés en réparation pendant toute une semaine. J’y omets sciemment un jour,
mettons le mercredi et demande à calculer le nombre moyen d’appareils traités par jour
au cours de cette semaine. La plupart du temps, la requête produite sera fausse, car le
jour absent n’est pas compté !
CREATE TABLE T_SAV (SAV_DATE DATE, SAV_APPAREIL VARCHAR(16));
INSERT INTO T_SAV VALUES
('2011-11-12', 'TV'), ('2011-11-14', 'RADIO'), ('2011-11-12', 'FRIGO'),
('2011-11-13', 'FOUR'), ('2011-11-16', 'RADIO'), ('2011-11-14', 'RADIO'),
('2011-11-12', 'FOUR'), ('2011-11-13', 'FOUR'), ('2011-11-16', 'TV');
requête naïve:
SELECT COUNT(*) / CAST(COUNT(DISTINCT SAV_DATE) AS FLOAT) AS NB_
APPAREIL_PAR_JOUR FROM T_SAV;
NB_APPAREIL_PAR_JOUR
----------------------
2,25
Ce résultat est faux, car la date du 15 novembre 2011 ne figure pas dans la table (peut-être
une grève ?). La solution consiste donc à rajouter une table de date :
CREATE TABLE T_DATE (D DATE);
INSERT INTO T_DATE VALUES ('2011-11-12'), ('2011-11-13'),
('2011-11-14'), ('2011-11-15'), ('2011-11-16');
La requête suivante est correcte :
SELECT COUNT(SAV_APPAREIL) / CAST(COUNT(DISTINCT D) AS FLOAT) NB_
APPAREIL_PAR_JOUR FROM T_SAV
Il est ensuite facile de rajouter à cette table de dates d’autres informations : numéro de
jour, semaine, mois, année, trimestre, semestre, jours fériés, congés… et d’indexer cette
table tout en la déclarant en lecture seule afin d’éviter tout verrou !
Mise en pratique
Les exercices 2.1 « Les associations binaires », 2.2 « L’héritage et la composition », 2.3 « Les
classes-associations » et 2.4 « Traduire ou ne pas traduire ? » vous proposent de traduire
manuellement différents modèles conceptuels en schémas relationnels.
domaine de valeurs).
●● Actualité : les données doivent être à jour au bon moment (vérification périodique ?).
●● Compréhension : le nom d’une colonne ne doit pas permettre d’ambiguïté sur son sens.
●● La colonne prix n’est pas précise (de quelle devise s’agit-il ?). Cette colonne sera-t-elle
actualisée au bon moment ? Cette colonne n’est pas compréhensible (s’agit-il d’un prix
TTC, HT, unitaire, de revient, etc. ?). Enfin, le type flottant (FLOAT) peut réserver des
surprises lors de calculs intermédiaires importants (12.499999999 ou 12.5000000001 ?).
●● La colonne quantite n’est ni précise (les décimales doivent-elles être acceptées, pour
stocker par exemple 1,5 pour un kilo et demi ?), ni compréhensible (quelle est l’unité du
produit, des mètres, des kilos, des livres, etc. ?), ni complète (les contraintes NOT NULL
sont absentes du fait que la case « O » comme obligatoire n’est pas cochée).
Vous trouverez quelques pistes en parcourant les liens suivants :
●● documentation d’Oracle : http://download.oracle.com/docs/cd/E11882_01/appdev.112/
e17125/adfns_sqltypes.htm#i1006173 ;
●● types SQL-Server, MySQL et Access : http://www.w3schools.com/sql/sql_datatypes.asp ;
●● documentation de MySQL : http://dev.mysql.com/doc/refman/5.0/en/choosing-types.html-
Billet ;
●● à propos de SQL-Server : http://www.techrepublic.com/blog/10things/10-common-
questions-about-sql-server-data-types/355.
La normalisation
Bien que les outils permettent de modéliser un schéma logique dans ce modèle de données,
aucun n’offre la possibilité d’automatiser une quelconque normalisation. Les avantages de
normaliser un schéma relationnel sont les suivants.
●● Éviter des redondances potentielles (donc minimiser l’espace de stockage et diminuer les
risques d’incohérences qui sont appelées anomalies transactionnelles).
●● Faciliter la programmation de n’importe quelle opération sur les tables (ajout, modification
et suppression).
●● Renforcer l’intégrité des données.
Le schéma relationnel suivant, de par sa structure, rend problématique les futures (mais très
probables) actions suivantes.
●● Ajout d’un client s’il n’est pas inscrit à un cours (la clé primaire de la table Inscriptions
est composée des colonnes et interdit donc qu’une des deux colonnes soit nulle).
●● Modification du nom d’un client ou de la société d’un client (la mise à jour doit être réper-
cutée dans toutes les lignes concernées). Si une modification est partielle, la table est tout
bonnement inexploitable (au niveau de ces deux colonnes).
●● Suppression d’une inscription (qui entraînerait la perte des données du client).
Enfin, il n’existe pas d’outil d’aide au processus de normalisation (Embarcadero Schema Exa-
miner reste très pauvre tout en étant relativement cher). Ainsi, encore une fois, la ressource
humaine est nécessaire et c’est une bonne nouvelle. Pas d’off-shore en Inde et ce ne sont pas
des programmeurs roumains qui vont normaliser vos bases de données.
Dépendances fonctionnelles
La normalisation est basée sur les dépendances fonctionnelles (DF). E. Codd fut le premier à
publier sur ce type de dépendances [COD 72]. Bien que le qualificatif de « fonctionnelles » soit
communément utilisé, ces dépendances sont davantage liées aux valeurs qu’à une fonctionna-
lité particulière. Le terme qui conviendrait mieux à les qualifier serait donc : « dépendances
de valeurs ».
Plusieurs attributs peuvent apparaître dans la partie gauche d’une DF. Plusieurs attributs peu-
vent apparaître dans la partie droite d’une DF. Dans ce cas, il convient de considérer chaque
DF en gardant la partie gauche et en faisant intervenir un seul attribut dans la partie droite.
Exemples
Étudions les exemples suivants inspirés du monde aéronautique commercial. Chaque pilote est
doté d’un numéro, d’un nom et d’une fonction (copilote, commandant ou instructeur).
●● L’écriture num_pilote → nom_pil,fonction est équivalente aux écritures num_
pilote → nom_pil et num_pilote → fonction qui sont deux DF, car tout pilote n’est
doté que d’un seul nom et d’une fonction à tout instant. Avec ces hypothèses, l’écriture
num_pilote → nom_pil,fonction est une DF.
●● L’écriture num_pilote,jour → nb_heures_vol peut être considérée comme une DF
si à tout couple cohérent et susceptible d’être stocké (num_pilote, jour), on désire
associer au plus un nombre d’heures de vol (qui sera le cumul de tous ses vols journaliers).
●● L’écriture nom_pilote → fonction peut être considérée comme une DF si on suppose
qu’il n’existera aucun homonyme dans la population des pilotes (cas peu probable). En res-
tant dans le cadre le plus général, cette écriture ne doit pas être considérée comme une DF.
●● L’écriture fonction → nom_pilote n’est évidemment pas une DF, car plusieurs pilotes
peuvent être dotés de la même fonction.
DF élémentaire
DF directe
Une DF a → c est directe si elle ne peut pas être déduite par transitivité de deux DF avérées,
c’est-à-dire que les écritures suivantes a → b et b → c ne sont pas des DF.
Il est difficile de statuer sur le fait qu’une DF est directe. En revanche, il est plus facile de
déterminer qu’une DF est indirecte (si on trouve un parcours de DF cohérent). En consé-
quence, toutes les DF qui ne sont pas considérées comme indirectes doivent être considérées
comme directes.
Considérons l’exemple qui fait intervenir les attributs suivants : (immat : numéro d’imma-
triculation d’un avion, type_avion : type de l’aéronef, nom_const : nom du constructeur
de l’aéronef). L’écriture immat → nom_const n’est pas une DF directe, car les dépendances
suivantes sont directes :
●● immat → type_avion
●● type_avion → nom_const
La relation Product ne respecte pas la règle de la première forme normale, car la colonne
color est prévue pour stocker différentes couleurs.
dans la majorité des lignes de la table. Modifier le libellé d’une couleur en particulier peut
s’avérer dangereux si toutes les répercussions ne se produisent pas.
●● L’incohérence d’informations, suite à une mise à jour défectueuse ou une insertion non
maîtrisée, mène à des résultats erronés (il est probable que la requête qui doit extraire les
produits de couleur bleue à l’aide d’une condition WHERE color LIKE %Blue% ne retrouve
pas le produit 456…
●● La complexité assurée pour toutes les requêtes relatives aux coloris, de même que leur
●● Toutes les requêtes relatives aux coloris se programmeront par jointures rendues perfor-
mantes par la présence d’index et par le type de la clé étrangère (ici numérique).
D’accord, il s’agit de prévoir que chaque attribut soit atomique. Mais il ne faudrait pas
oublier que tout attribut d’une relation doit être évalué (donc pas de NULL) ! (en sus du
fait que la relation doit impérativement avoir une clé).
Mais qu’est-ce que l’atomicité d’un attribut ? Une date est-elle atomique ? N’est-elle pas
elle-même composée d’une année, d’un mois et d’un jour ? Un numéro de Sécurité sociale
n’est, par nature, pas du tout atomique. Il incorpore plusieurs notions telles que le sexe,
l’année, le mois et la commune de naissance…
Pour autant, on peut inverser le problème. Demandez donc à un vendeur de listes si
l’adresse dont il a fourré tous les éléments (nom de voie, type de voie, numéro dans la
voie…) dans un seul et même attribut considère que cette information n’est pas atomique !
Bref, la notion d’atomicité est relative à la problématique du modèle analysé…
Pour autant, certaines informations sont composées de plusieurs éléments décompo-
sables, et peuvent bien entendu être considérées comme atomiques. C’est le cas par
exemple des périodes (un début + une fin) et plus généralement des intervalles, mais aussi
des objets géographiques (points, lignes, polygones…). Il devient alors très complexe de
savoir ce que représentent certaines notions d’unicité dans ce genre de cas de figure. À
titre d’exemple, voici deux polygones identiques (SQL SIG) :
POLYGON ((3 7, 5 7, 5 2, 4 2, 3 7))
POLYGON ((4 2, 3 7, 5 7, 5 2, 4 2))
Et deux intervalles se chevauchant : [33..52] et [47..49[.
Il ne semble pourtant pas évident de savoir ce qu’une contrainte d’unicité (clé de la rela-
tion par exemple) doit faire dans un tel cas de figure !
On dit bien qu’un attribut doit être atomique. Ce n’est pas pour autant que l’on devrait
cacher la non-atomicité par une fantaisie de modélisation… Je m’explique. On trouve
souvent dans les tables des attributs de même nom numéroté de 1 à…, par exemple
TELEPHONE1, TELEPHONE2, TELEPHONE3… Et, pourquoi pas, 4, 5, voire 10 téléphones ?
Dans ce cas, c’est un tableau de téléphone que l’on devrait mettre. Or, un tableau n’est à
l’évidence pas atomique, donc il se doit d’être transformé en entité à part entière.
Plus vicieux sont les attributs similaires non numérotés. Par exemple : TELEPHONE_FIXE,
TELEPHONE_MOBILE, TELECOPIE, TELEPHONE_DOMICILE, TELEPHONE_TRAVAIL!
Là aussi, la transformation est indispensable : une entité TELEPHONE avec un typage
des téléphones suffit. Songez donc au jour où votre patron vous demandera de retrouver
le client dont le numéro de téléphone est 75 78 45 15 79… Si vous avez disséminé vos
numéros de téléphone à travers plusieurs colonnes, voire plusieurs tables, ne vous étonnez
pas que la requête soit un veau et que tous les index du monde n’y pourront rien en plus
de rendre les tables bovines…
Tout attribut doit être évalué. Cette règle est aussi impérative, contrairement à SQL où
une colonne d’une table peut ne pas avoir de valeurs (dans ce cas, le marqueur NULL y
figure, mais ce n’est généralement pas très bon pour les performances). Se pose alors
la question de savoir comment modéliser lorsque l’information est connue de manière
partielle ?
Prenons par exemple le cas d’une personne modélisée traditionnellement avec les attributs
nom, prénom et date de naissance :
PERSONNE_PHYSIQUE (PRP_ID INT auto, PRP_NOM A60, PRP_PRENOM A32,
PRP_NAISSANCE DATE), l’identifiant étant PRP_ID.
Mais si nous ne connaissons pas le nom, ou le prénom ou la date de naissance d’une per-
sonne, alors que faire ? Il suffit tout simplement de décomposer l’entité en trois :
PERSONNE_PHYSIQUE_NOM (PRP_ID INT auto, PRP_NOM A60),
l'identifiant étant PRP_ID.
PERSONNE_PHYSIQUE_PRENOM (PRP_ID INT auto, PRP_PRENOM A32),
l'identifiant étant PRP_ID.
PERSONNE_PHYSIQUE_NAISSANCE (PRP_ID INT auto, PRP_NAISSANCE
DATE), l'identifiant étant PRP_ID.
Pour reconstituer l’information d’une personne, il suffira de faire des jointures externes
bilatérales. A priori ce découpage semble utopique, car il va générer de nombreuses opé-
rations de jointures… Pour autant, certains SGBDR comme Sybase IQ le font sans vous
le dire, car ce modèle (toutes les tables sont dotées d’une clé et au plus d’un seul attribut),
en sus d’être parfait, est extrêmement performant sur de grands volumes et de nombreuses
transactions. En effet :
• il répartit la charge de mise à jour sur différents objets, ce qui est moins bloquant que
d’avoir un seul objet bloqué pour tout un tas de mises à jour différentes ;
• il économise du volume (on ne stocke pas de lignes pour le NULL) ;
• il permet une indexation systématique de tous les objets (il suffit de poser un seul index
sur le seul attribut pour que tout soit indexé).
Bien entendu, si votre SGBDR ne dispose pas d’un tel mécanisme, vous pouvez le simuler
avec des vues !
Une relation est en deuxième forme normale si la première forme normale est assurée et si
tout attribut non clé est en dépendance fonctionnelle élémentaire avec la clé.
La relation Coloris ne respecte pas la règle de la deuxième forme normale, car la colonne
poids_kg ne dépend que du produit et non de la couleur (enfin, en général, c’est comme ça).
En revanche, il est plausible que le prix d’un produit dépende aussi de sa couleur (avez-vous
remarqué que les iPhone blancs sont plus chers ?).
les coloris possibles de ce produit. Modifier un poids peut s’avérer risqué si tous les coloris
ne se sont pas impactés simultanément.
●● L’incohérence d’informations, suite à une mise à jour incomplète d’un poids.
●● La redondance d’informations : le poids d’un produit n’est stocké qu’une seule fois, ce qui
annule une éventuelle incohérence d’informations.
●● Les requêtes relatives aux poids n’ont plus besoin de jointures.
Seules les relations ayant des clés primaires composées sont potentiellement concernées par
la deuxième forme normale.
Une jointure permet de reconstituer la relation originale. Une vue peut être programmée à cet
effet.
Une relation est en troisième forme normale si elle respecte la deuxième forme normale
et si les dépendances fonctionnelles entre la clé primaire et les autres attributs sont toutes
directes. En d’autres termes, aucun attribut ne doit pouvoir être identifié par autre chose que
la clé (primaire ou candidate).
La relation Product ne respecte pas la règle de la troisième forme normale, car la colonne
nom_marque n’est pas en dépendance directe avec la clé (itemID). En effet, le nom
d’une marque doit être identifié par un code et un produit sera associé ensuite à sa marque.
associés.
Cette solution évite les inconvénients précédents, car le nom de la marque est unique dans
la table de référence (Marques) et ne se répète pas pour chaque produit. En revanche, les
requêtes relatives aux marques nécessiteront davantage de jointures.
Une jointure permet de reconstituer la relation originale. Une vue peut être programmée à cet
effet.
Une relation est en forme normale de Boyce-Codd [COD 74] si elle respecte la troisième forme
normale et que le seul déterminant (membre gauche d’une DF) de la relation est la clé pri-
maire (mis à par d’éventuels identifiants alternatifs). En d’autres termes, aucune dépendance
vers une partie de la clé ne doit exister.
En supposant qu’un produit puisse être fabriqué dans une région de différents pays, la relation
Fabrication ne respecte pas la règle de Boyce-Codd. En effet, il existe une dépendance
entre la colonne region et une partie de la clé (itemID) qui s’explique par le fait qu’une
région est toujours associée à un unique pays.
Par ailleurs, le nom de la région est un libellé qui doit être associé à un identifiant. La prise
en compte de ces deux remarques mène à la normalisation en forme de Boyce-Codd de ce
schéma.
La théorie montre que toute relation a une décomposition sans perte en forme normale de
Boyce-Codd. En revanche, une telle décomposition ne préserve pas toutes les DF (dans
l’exemple la DF itemID, id_pays → region a été supprimée). Il est cependant possible de
la retrouver en réalisant une jointure entre les relations normalisées.
Seules les relations ayant des clés primaires composées sont potentiellement concernées par
la forme normale de Boyce Codd.
Une jointure permet de reconstituer la relation originale. Une vue peut être programmée à cet
effet.
Une relation est en forme normale domaine-clé si toutes les contraintes qui s’appliquent à la
relation sont la conséquence logique des contraintes de domaines et des contraintes de clé.
Le premier schéma relationnel ne vérifie pas la forme normale domaine-clé, car la relation
Avion contient le code catégorie (id_cat) qui peut être calculé en fonction de la colonne
envergure. Cette redondance est problématique si les règles régissant les catégories évo-
luent. En effet, l’adoption de l’éclatement du groupe I pour former deux nouveaux groupes
« Ia » concernant les avions d’envergure inférieure à 20 ft et « Ib » pour ceux d’envergure
jusqu’à 49 ft nécessiterait la mise à jour de nombreuses lignes de la table. Si ces mises à jour
ne forment pas une transaction, des anomalies de mises à jour peuvent se produire.
Le deuxième schéma relationnel qui est décomposé selon la forme normale domaine-clé
présente l’avantage de ne pas être sensible à de telles modifications.
Une inéqui-jointure permet de reconstituer la relation originale. Une vue peut être programmée
à cet effet.
Afin de dissocier ces deux états de faits, il est nécessaire de décomposer Qualifier en deux
relations Qualif_necessaire (constitue les correspondances entre un type d’avion et les
qualifications) et Aptitude (pour connaître quels sont les pilotes qualifiés pour chaque type
d’appareil).
Considérons à nouveau la relation initiale Qualifier et supposons qu’elle inclut également
les qualifications que possède chaque pilote, sans pour autant que ces qualifications soient
concernées par un type d’appareil quelconque. Cette relation ne respecte pas la cinquième
forme normale, car il existe des dépendances de jointure.
Afin de dissocier ces trois états de faits, il est nécessaire de décomposer Qualifier en trois
relations : Qualif_necessaire et Aptitude pour répondre aux deux premiers états de
faits, et Qualif_detenues pour modéliser l’hypothèse de travail.
Seules les relations ayant des clés primaires composées de plus de deux colonnes sont
potentiellement concernées par les quatrième et cinquième formes normales.
Si vous suivez les préconisations du chapitre 1, vous éviterez de modéliser chaque asso-
ciation n-aire en l’état (sans décomposition systématique en classes-associations), et
vous obtiendrez un schéma qui respecte naturellement les quatrième et cinquième formes
normales.
Mise en pratique
L’exercice 2.5 « La normalisation » vous propose de normaliser une relation qui contient peu
de colonnes, mais beaucoup d’informations.
Calculs de volumétrie
L’analyse de la volumétrie d’une base est un calcul a priori. Pour chaque relation, vous devrez
estimer la longueur d’un n-uplet (une ligne) : l. En considérant, d’une part, une valeur moyenne
de la taille de chaque colonne :
Une fois toutes les tables renseignées en termes de volume, un calcul théorique peut être exé-
cuté. Dans l’exemple suivant, il faudra disposer de plus de 103 Mo.
Vous venez sans doute de constater qu’un bon modèle de données est constitué d’une mul-
tiplicité d’entités. Sans doute beaucoup plus que vous ne l’auriez imaginé et certainement
plus que ce que vous avez déjà fait, si jamais vous avez commencé à travailler les bases
de données sans passer par l’étape modélisation.
Pour autant, vous vous posez avec sérénité la question des performances du fait des mul-
tiples jointures à faire lors du codage des applications, et donc de l’exploitation de la
base. Bien entendu, toute opération de jointure a un coût. Mais ce coût peut devenir très
minime en face du bénéficie considérable d’une bonne modélisation… Autrement dit, vous
ne devez pas avoir peur du nombre d’entités et donc de tables de votre base.
Mais écrire de multiples jointures pour la moindre requête vous fatigue ! Vous avez
raison, un bon informaticien doit être faignant… La solution réside donc dans la création
des vues. Ainsi, pour une personne dont vous voulez, et les données personnelles, et les
données de contact, créez une vue synthétisant toutes ces informations. N’hésitez pas à
l’utiliser systématiquement dans tous vos codes, même pour la mise à jour (nous verrons
comment mettre à jour les vues dans un chapitre ultérieur).
Sachez qu’un bon SGBDR ignorera certaines jointures inutiles d’une vue, si les infor-
mations à retourner ne sont pas utiles pour votre requête. Sachez aussi que le nombre
de jointures qu’un SGBDR peut supporter est assez élevé. C’est en général plusieurs
centaines. Sachez enfin que le coût d’une jointure entre une clé primaire (identifiant de
l’entité) et une clé étrangère (qui se doit d’être indexée) est très minime si vous avez opté
pour une clé auto-incrémentée (SEQUENCE ou IDENTITY). Apprenez que le coût d’une
jointure entre deux tables de 100 millions de lignes, devant retourner une unique ligne,
ne dépasse pas six lectures…
Enfin, si tout cela ne vous a pas convaincu, venez en discuter ici : http://www.
developpez.net/forums/d1099389/bases-donnees/decisions-sgbd/optimisations/petites-
tables-grandes-tables-consequences-performances/.
Exercices
2.5 La normalisation
En considérant la relation suivante qui vise à modéliser les différents gagnants de tournois de
tennis, trouvez la clé, puis normalisez cette relation le plus possible.
Le niveau physique
Le niveau physique présenté dans ce chapitre correspond à la définition des tables, des clés
étrangères ainsi qu’à l’implémentation des éventuelles règles métier par des contraintes de clés,
de validation ou par des déclencheurs.
Le langage SQL
Le langage SQL provient du langage System R d’IBM. SQL est implanté dans des produits
commerciaux à la fin des années 1970 avec la première version d’Oracle et de SQL/DS
d’IBM. SQL est une norme ANSI depuis 1986 et une norme ISO depuis 1987. La norme
ANSI (SQL-86) est le résultat d’un compromis entre constructeurs, mais a été fortement
influencée par le dialecte d’IBM.
La version SQL2 (appelée aussi SQL-92) a été normalisée par l’ANSI et l’ISO en 1992. Les
langages proposés par les SGBD actuels sont proches de cette norme qui définit trois niveaux
de conformité : le niveau d’entrée (entry level), le niveau intermédiaire (intermediate level) et
le niveau maximum (full level). Les langages SQL des principaux éditeurs de SGBD relation-
nels (Oracle, IBM, Microsoft, Sybase…) sont conformes au premier niveau et ont beaucoup de
caractéristiques qui relèvent des niveaux supérieurs.
SQL3 comporte de nombreuses parties (On Line Analytical Processing, séries temporelles,
accès à des sources non SQL, réplication des données, objet, XML, etc.).
Les différentes normes sont reconnues et numérotées de la manière suivante :
●● SQL1 ISO 9075:1986 (SQL86/SQL1) ISO 9075:1989 (SQL89) ;
●● SQL2 ISO 9075:1992 (SQL92/SQL2) 600 pages, 4 niveaux (entry qui reprend SQL1,
transitional, intermediate et full), ISO 9075-4:1996 (SQL/Persistant Stored Module for
SQL92), ISO 9075-3:1995 (SQL/Call Level Interface for SQL92) ;
●● SQL3, des milliers de pages, mises à jour continuelles, codifications : ISO/IEC 9075-x (x
désignant l’année, par exemple : ISO/IEC 9075-1:2008, Information technology - Database
languages - SQL -- Part 1: Framework).
Vous trouverez les dernières spécifications relatives à la gestion de données et à SQL en
particulier sur http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_tc_browse.
htm?commid=45342.
Le langage SQL vous permettra de déclarer, de manipuler et d’interroger des données, mais
aussi de contrôler leur accès. De plus, vous pourrez intégrer vos données dans vos programmes
écrits dans tout langage (COBOL, C, C++, Java avec JDBC, C#, etc.), car il existe des API pour
chaque langage et chaque SGBD du marché.
Les instructions du langage SQL qui nous intéressent sont principalement CREATE TABLE
qui crée une table et ALTER TABLE qui permet d’ajouter une contrainte à une table existante.
Les schémas
Une table est un objet nommé d’un schéma (notion de propriétaire) qui est composé de colonnes
et d’éventuelles contraintes (clés ou valeurs). La description de chaque table se trouve stockée
dans le dictionnaire de données du SGBD, ce qui permet notamment aux outils d’opérer du
reverse engineering. Une table sera par la suite éventuellement indexée, partitionnée ou clus-
terisée.
La notion de « schéma » n’a pas la même signification selon certains SGBD : certains l’assi-
milent à la notion de database (MySQL) à la notion de user comme Oracle. SQL Server est
multischéma et multibase. Un schéma joue le rôle de bibliothèque (tel un espace de noms) dans
lequel les privilèges se gèrent plus facilement.
Un serveur SQL (aussi appelé « instance ») est une machine logique installée sur un
ordinateur lui-même physique ou logique. La plupart des éditeurs permettent d’installer
plusieurs serveurs SQL sur une même machine. Dans chaque serveur SQL, il peut y avoir
plusieurs bases de données (limité à 32 000) et dans chaque base des schémas SQL (la
limite théorique étant 4 milliards par bases…) qui constituent autant d’espace logique,
dont le but est triple :
• fournir un moyen de ranger les différents objets en différentes catégories (par exemple,
un schéma pour les ressources humaines, un autre pour la comptabilité, un troisième
pour la production…) ;
• permettre d’associer des privilèges au niveau du schéma à des utilisateurs, ce qui
allège la tâche d’administration de sécurité pour les objets futurs (par exemple, GRANT
SELECT ON SCHEMA::COMPTA TO DOMINIQUE) ;
• autoriser dans un ordre CREATE SCHEMA de créer des objets mutuellement dépendants
sans pour cela se contraindre à un ordre logique particulier (voir http://blog.deve-
loppez.com/sqlpro/p5835/langage-sql-norme/de-l-interet-des-schema-sql/ et http://
docs.postgresqlfr.org/9.0/sql-createschema.html).
Il existe toujours un schéma par défaut pour la base et pour l’utilisateur.
En cas d’absence du préfixe de schéma pour atteindre un objet, le serveur doit effectuer
une résolution de nom en commençant par chercher l’objet dans le schéma associé à
l’utilisateur, et s’il ne le trouve pas, le serveur l’associe au schéma par défaut de la base.
Dans tous les cas, cette phase prend du temps et peut conduire à des problèmes de pertes
de cache donc, de mauvaises performances. Il vaut donc mieux être précis et préfixer tous
les objets de vos requêtes par le schéma dans lequel ils ont été créés.
MySQL n’implémente pas la notion de schémas SQL, mais laisse entendre que cela est
similaire à la création de multiples bases dans une même instance. Certains SGBD, en
particulier MS SQL Server et MySQL, autorisent nativement des requêtes interbases avec
des noms qualifiés (par exemple MaBase.MonSchema.MaTable pour MS SQL Server).
Pour faire cela, sous Oracle ou PostGreSQL, il faut recourir à un mécanisme de DBlink
qui semble plus lourd et moins performant.
Bien souvent, les développeurs se posent cette question cruciale : « Faut-il que je fasse
plusieurs schémas SQL ou est-il préférable de passer par plusieurs bases ? » Mais cette
question est idiote ! En effet, schémas et bases de données n’ont absolument pas le même
rôle et prendre l’un pour l’autre comme le fait MySQL peut s’avérer catastrophique à tous
les plans (logique, physique et administratif…).
Le schéma SQL est un conteneur logique pour les objets d’une base. Il n’a donc rien
à voir avec un stockage physique. Si votre SGBDR gère correctement les espaces de
stockage, vous pouvez avoir n tables toutes créées dans un schéma S1 et chacune de ces
tables peut stocker ses données où bon lui semble et pourquoi pas un espace de stockage
spécifique à chaque table.
Répartir les objets d’une base de données dans différents schémas SQL est une excellente
approche, car cela permet d’organiser la base en différents pans sémantiques ou fonc-
tionnels. En revanche, répartir les objets d’une même application dans différentes bases,
pose des problèmes impossibles à résoudre.
• On ne peut pas faire de contraintes SQL d’une base à une autre. En revanche, au sein
d’une même base et même si les objets sont dans différents schémas SQL c’est possible.
• On ne peut pas sauvegarder les données de deux bases différentes de manière syn-
chrone alors que la sauvegarde d’une base emporte la sauvegarde de tous les schémas
d’un seul coup au même point de synchronisation.
• La gestion des privilèges est spécifique à une base. Elle couvre les schémas, mais elle
ne peut passer de base en base (MS SQL Server est le seul SGBDR à permettre cette
fonction, mais elle s’avère complexe à mettre en œuvre).
Schémas et propriétaires
Comme tout objet de la base, un schéma est créé par un utilisateur, ce qui confère à cet
utilisateur d’être le propriétaire du schéma, à moins qu’il ne spécifie un autre utilisateur
dans l’ordre SQL CREATE SCHEMA .
Le propriétaire d’un schéma est un peu comme un châtelain du Moyen Âge… Il a le droit
de vie ou de mort sur ses sujets, je voulais dire « ses objets », tout le temps qu’il est respon-
sable de la création des objets figurant à l’intérieur de son schéma. Mais rien n’empêche
de créer au sein du schéma de Pierre un objet dont le propriétaire est Paul (une sorte de
concession en somme) !
Il y a longtemps eu une confusion au sein des éditeurs de SGBDR entre la notion de
propriétaire (la norme SQL parle d’« autorisé ») et la notion de schéma. C’est ainsi que
dans certains SGBDR le schéma par défaut porte le même nom que l’utilisateur qui en est
propriétaire, histoire d’entretenir la confusion !
Les contraintes
Les objectifs des contraintes au niveau des tables sont multiples : renforcer l’intégrité de la
base, programmer des règles de gestion élémentaires et alléger la programmation côté client.
La mise en œuvre des contraintes va s’opérer lors de la création des tables (ou ultérieurement),
la déclaration d’une contrainte lors de la création SQL peut être réalisée en ligne (in line sur la
même ligne que la colonne de la table elle-même) ou hors ligne (out of line). Les principales
contraintes de SQL que vous avez à disposition sont :
●● UNIQUE (colonne1 [,colonne2]...)
●● PRIMARY KEY (colonne1 [,colonne2]...)
●● FOREIGN KEY (colonne1 [,colonne2]...)
REFERENCES nom_table_parent(colonne1 [,colonne2]...)
●● CHECK (condition)
Une fois définie et activée, une contrainte peut être désactivée ou supprimée. Dès qu’une
contrainte n’est pas respectée au cours du temps, une exception est levée et la transaction, dans
laquelle se trouve l’instruction qui concernait la table, est annulée.
L’outil que vous utiliserez éventuellement est capable de générer un script qui contiendra ces
deux types d’instruction.
CREATE TABLE [nom_schema.]nom_table
(colonne_1 type_1 [NOT NULL] [DEFAULT valeur],
[, colonne_2 ...]
[, CONSTRAINT nom_contrainte_1 type_contrainte_1 ...])
options physiques;
De plus, il faudrait signaler l’unicité des noms des objets à travers les schémas (tables,
contraintes…) et la possibilité d’avoir des doublons de noms sur les objets primaires des
bases si on les situe dans différents schémas.
Afin de rendre les scripts plus clairs, les instructions SQL sont notées en majuscules et les
noms d’objets (tables, colonnes et contraintes) apparaissent en minuscules.
Étudions à présent les mécanismes qui régissent le passage d’un modèle relationnel au script
SQL. Les exemples traités sont identiques à ceux du chapitre 2 de manière à ce que vous
puissiez retrouver facilement le modèle conceptuel initial. Suivant ces principes, pour tous vos
futurs schémas, vous devriez obtenir des scripts SQL analogues.
La contrainte NOT NULL oblige la colonne à contenir une valeur non nulle (qui est différente de
0, blanc ou plusieurs espaces). Certains outils disposent systématiquement cette contrainte
sur les clés primaires.
La contrainte NOT NULL sur une colonne clé étrangère traduit une multiplicité minimale à 1
d’une association un-à-plusieurs (ici la colonne id_ville dans la table Aeroport).
Il existe d’autres formes d’associations un-à-un comme dans le cas de l’héritage ou d’un
lien identifiant (la clé est la même entre les diverses tables).
De la même manière qu’il existe trois sortes de cardinalités de liens entre deux relations,
il en existe autant pour les autoréférences d’une même relation.
• Autoréférence avec cardinalité un-à-un : le cas est rarissime. On peut donner un
exemple d’un point de vue statique. Dans une table de personnes physiques et dans nos
religions occidentales, une personne ne peut avoir qu’un seul conjoint. Ainsi, à l’ins-
tant t, une occurrence de personne peut être en lien 0 ou 1 à une autre personne (peu
importe qu’il soit homme ou femme, certains pays ayant admis le mariage homosexuel
et c’est le cas du Pacs en France).
• Autoréférence avec cardinalité un-à-plusieurs : c’est un cas très courant, car il conduit
à modéliser une arborescence. On le trouve typiquement dans les organigrammes d’en-
treprise pour savoir qui est le chef. Il est aussi souvent présent dans les nomenclatures
pour lesquelles les données sont emboîtées.
• Autoréférence avec cardinalité plusieurs-à-plusieurs : c’est le cas des graphes mathé-
matiques qui représentent des réseaux (lignes de métro, de bus, réseaux routiers,
télécommunications, réseaux informatiques…). Dans ce cas, le graphe peut être
vu de deux façons : orienté ou non, conduisant à une multiplicité des cardinalités.
Graphe non orienté : c’est le cas notamment des réseaux de type full duplex. Par
exemple, si l’on veut modéliser la distance des routes aériennes entre deux aéroports,
peu importe le sens, car il n’y a pas de couloir aérien à sens unique ! Le résultat est
que la matrice des combinaisons est « triangulaire ». Il est ainsi inutile de stocker
la distance pour l’aller et le retour, une seule de ces deux informations suffit. En
revanche, pour la circulation des bus dans une grande ville, la présence de voies
à sens unique va multiplier les trajets orientés et donc doubler potentiellement le
nombre des combinaisons.
Vérifiez que la clé primaire de la table « composant » est constituée en partie de la clé primaire
de la table « composite ».
Vérifiez que la clé primaire de la table d’association est composée de deux clés étrangères.
Solution universelle
Le tableau suivant décrit la transformation de deux associations binaires entre les relations
Projet et Collaborateur. L’association affecter est de type de un-à-plusieurs l’associa-
tion diriger est de type de un-à-un.
Chaque association doit se traduire par une table d’association munie de deux clés étrangères.
Les contraintes UNIQUE et NOT NULL sur chacune de ces clés permettront d’implémenter telle
ou telle multiplicité.
La contrainte NOT NULL sur la colonne id_coll dans la table diriger signifie que tout
projet est dirigé par un collaborateur (multiplicité minimale 1). La contrainte UNIQUE sur
cette même colonne implémente le fait qu’un collaborateur ne peut diriger plusieurs projets
(multiplicité maximale 1).
L’absence de contrainte NOT NULL sur la colonne num_proj dans la table affecter signifie
qu’un collaborateur ne peut participer à aucun projet (multiplicité minimale 0). La contrainte
UNIQUE (du fait de la clé primaire) sur la colonne id_coll de cette même table implémente le
fait qu’un collaborateur ne peut participer à plusieurs projets (multiplicité maximale 1).
Cette solution présente l’avantage d’être la plus évolutive si les multiplicités viennent à
changer. En effet, nul besoin de modifier la structure d’une table, seules des contraintes seront
à activer ou à désactiver.
Mise en pratique
Les exercices 3.1 « La création de tables (carte d’embarquement) » et 3.2 « La création de tables
(horaires de bus) » vous proposent de déduire le script SQL à partir de différents modèles
conceptuels.
projet VARCHAR2(254),
CONSTRAINT pk_manager
PRIMARY KEY (idpers));
CREATE TABLE PERSONNEL (
idpers INTEGER NOT NULL,
nom VARCHAR2(40),
indice INTEGER,
CONSTRAINT pk_personnel
PRIMARY KEY (idpers));
ALTER TABLE administratif
ADD CONSTRAINT fk_admin_personne
FOREIGN KEY (idpers)
REFERENCES personnel (idpers);
ALTER TABLE commercial
ADD CONSTRAINT fk_commerci_personne
FOREIGN KEY (idpers)
REFERENCES personnel (idpers);
ALTER TABLE manager
ADD CONSTRAINT fk_manager_personne
FOREIGN KEY (idpers)
REFERENCES personnel (idpers);
Contrainte d’exclusivité
La contrainte d’exclusivité (cas par défaut, le diagramme de classes UML ne comporte aucune
indication) exprime les règles métier suivantes.
●● Il n’est pas possible qu’un personnel appartienne simultanément à plusieurs classifications
et administratif).
La première règle de gestion s’implémente à l’aide de trois déclencheurs : un sur chaque table
spécifique (commercial, manager et administratif). Il s’agit d’interdire qu’un manager
de numéro 100 soit aussi également référencé dans une autre table spécifique avec ce même
numéro (commercial et administratif). Le raisonnement devra s’appliquer à l’identique
pour les tables des commerciaux et celles des administratifs.
Le premier déclencheur est décrit dans le tableau suivant avec une syntaxe Oracle. Si vous
aviez à le programmer avec SQL Server, vous devriez utiliser les pseudo-tables Inserted et
Updated.
Si vous ne souhaitez pas travailler avec des déclencheurs, vous devrez coder ces règles
métier dans vos procédures cataloguées.
Absence de contrainte
L’absence de contrainte (notation {incomplete, overlapping} avec UML) permet les
scénarios suivants.
●● Il est possible qu’un personnel appartienne à une ou plusieurs classifications (commercial,
manager ou administratif).
●● Il est possible qu’un personnel ne soit associé à aucune classification (ni commercial, ni
manager, ni administratif).
Le premier scénario s’implémente naturellement du fait de l’existence de la clé étrangère dans
chaque table spécifique. En effet, il est autorisé que le personnel numéro 100 soit aussi égale-
ment référencé dans n’importe quelle table spécifique avec ce même numéro.
La deuxième règle de gestion est programmée aussi du fait de l’existence de la clé étrangère de
la même manière qu’au cas précédent.
Héritage en push-down
Suivant le principe de la décomposition descendante, seules les tables spécifiques créées et
toutes les colonnes et la clé primaire de la table générique se propagent.
Contrainte de partition
La contrainte de partition (notation {complete, disjoint} avec UML) interdit les scéna-
rios suivants.
●● Un personnel appartient simultanément à plusieurs classifications (commercial, manager
ou administratif).
●● Un personnel n’est associé à aucune classification (ni commercial, ni manager, ni admi-
nistratif).
La première règle de gestion s’implémente à l’aide de trois déclencheurs : un sur chaque table
spécifique. Il s’agit d’interdire qu’un manager de numéro 100 soit également référencé dans
une autre table spécifique avec ce même numéro (commercial et administratif). Le
raisonnement devra s’appliquer à l’identique pour les tables des commerciaux et celle des
administratifs. Le code du déclencheur est décrit au paragraphe précédent.
La deuxième règle s’implémente naturellement du fait de l’inexistence d’une table générique.
Ici seuls managers, commerciaux ou administratifs peuvent être stockés.
Héritage en push-up
Suivant le principe de la décomposition ascendante, seule la table générique est créée et ras-
semble toutes les colonnes des tables génériques.
Contrainte d’exclusivité
La contrainte d’exclusivité interdit le fait qu’un personnel appartienne à plusieurs classifica-
tions (commercial, manager ou administratif) tout en permettant à un personnel de n’être
rattaché à aucune classification.
La première règle de gestion s’implémente à l’aide d’une contrainte de vérification (CHECK).
Il s’agit d’interdire que toutes les colonnes provenant des tables spécifiques disposent toutes
d’une valeur. Si les colonnes relatives à un manager sont renseignées, alors les autres (relatives
aux commerciaux et aux administratifs) doivent être nulles. Le même raisonnement devra
s’appliquer pour les colonnes des commerciaux et des administratifs.
Le tableau suivant présente cette contrainte ainsi que quelques insertions valides et une inva-
lide (personnel à la fois commercial et administratif).
-- commercial
ALTER TABLE personnel INSERT INTO personnel VALUES
ADD CONSTRAINT ck_exclusivite (100,'F. Brouard',500,47800,NULL,NULL,NULL,NULL);
CHECK 1 row created.
((projet IS NOT NULL AND nbhmois IS NOT NULL
AND prime IS NULL
AND syndicat IS NULL -- manager
AND nbheuressupp IS NULL) INSERT INTO personnel VALUES
La deuxième règle de gestion s’implémente dans cette même contrainte en permettant que
toutes les colonnes spécifiques soient nulles simultanément.
Contrainte de partition
La contrainte de partition s’implémente en interdisant que toutes les colonnes spécifiques
soient nulles simultanément. Il suffit d’enlever la dernière partie de la condition composée. Le
tableau suivant décrit l’écriture de cette contrainte avec deux insertions invalides : la première
du fait d’un personnel non qualifié, la seconde à cause d’une double qualification.
Contrainte de totalité
La contrainte de totalité permet des multiqualifications mais interdit les personnels non quali-
fiés. Le tableau suivant décrit l’écriture de cette contrainte avec deux insertions invalides : la
première du fait d’un personnel non qualifié, la seconde à cause d’une double qualification. La
contrainte doit signifier que les colonnes spécifiques ne doivent pas être nulles simultanément
(ce qui n’interdit pas des nullités partielles).
-- aucune qualification
INSERT INTO personnel VALUES
(103,'C. Bravo',457,NULL,NULL,NULL,NULL,
NULL);
*
ERROR at line 1:
ORA-02290: check constraint (SOUTOU.CK_
TOTALITE) violated
Absence de contrainte
Si l’héritage ne présente pas de restriction, aucune contrainte SQL n’est à mettre en œuvre.
Dans le cas de la modélisation des héritages, les contraintes à poser portent souvent sur
plusieurs tables. Rien n’empêche une contrainte SQL de table de s’intéresser aux données
présentes dans d’autres tables… sauf certains éditeurs de SGBDR !
En effet, Oracle s’interdit toutes contraintes de table portant sur une autre table et il n’y
a aucune échappatoire possible, pareil pour MySQL… En revanche, pour PostGreSQL,
comme pour MS SQL Server, même s’ils n’acceptent pas de référencer directement une
autre table dans une contrainte de validation CHECK , il est possible de biaiser en créant
une fonction utilisateur (ou UDF pour User Defined Function) qui lit une autre table afin
de fournir l’information nécessaire à la contrainte.
En plus des contraintes classiques, la norme SQL décrit les assertions de portée multi-
base. Pour une raison défendable, la plupart des éditeurs de SGBDR ont préféré ne pas
implémenter les assertions leur préférant les déclencheurs (triggers en anglais). On reste
cependant confondus devant les simplicités d’expression d’une assertion face à l’alterna-
tive CHECK + UDF ou trigger.
Voici un exemple d’assertion pour assurer l’exclusion mutuelle dans le cas d’un héritage
entre les personnes physiques et les personnes morales :
CREATE ASSERTION a_exclure_personne AS
CHECK NOT EXISTS(SELECT *
FROM t_personne_physique AS pp
INNER JOIN t_personne_morale AS pm
ON pp.prs_id = pm.prs_id);
Pour exprimer la même chose sous forme de déclencheurs, il faut beaucoup plus de code.
Quant à la version avec UDF, en voici un exemple, toujours sous MS SQL Server :
CREATE FUNCTION f_check_exclure_personne (@prs_id INT)
RETURNS BIT AS
BEGIN
RETURN CASE WHEN EXISTS(SELECT …
FROM t_personne_physique AS pp
INNER JOIN t_personne_morale AS pm
ON pp.prs_id = pm.prs_id
WHERE pp.prs_id = @prs_id)
THEN 1
ELSE 0
END;
END;
Contraintes prédéfinies
cLe chapitre 1 a présenté deux contraintes prédéfinies de UML : subsets (qui exprime une
contrainte d’inclusion) et xor (qui indique un ou exclusif).
Contrainte d’inclusion
Dans l’exemple suivant, la contrainte subsets exprime le fait qu’une inscription à une forma-
tion par un stagiaire (relation effectue) ne sera possible que si ce même stagiaire a choisi au
préalable cette formation (relation vœux). Le script SQL décrit n’inclut pas la contrainte qui
n’est pas générée automatiquement, mais qu’il faudra coder manuellement.
Le codage de cette contrainte se résume à la déclaration d’une nouvelle clé étrangère (com-
posée de deux colonnes) qui aura pour but de vérifier si tout couple (stagiaire, formation)
décrivant une inscription existe au préalable dans la table de référence des vœux.
Contrainte du ou exclusif
Analogue à l’héritage par exclusion, la contrainte xor suivante précise qu’un consultant est
soit associé à un projet, soit à une formation, mais pas aux deux simultanément. L’outil ne
génère pas cette contrainte dans le script SQL.
La condition xor se programme à l’aide d’une contrainte de vérification qui vérifiera que tout
consultant soit associé à une formation ou à un projet, mais pas aux deux ou à aucun.
ALTER TABLE consultant INSERT INTO projet VALUES (1, 40700, 'Viaduc de Millau');
ADD CONSTRAINT ck_xor CHECK INSERT INTO formation VALUES (10,'No SQL','SGBD Open source');
((id_proj IS NULL INSERT INTO consultant VALUES (100,1,NULL,'Fred
Brouard',SYSDATE,200);
AND formid IS NOT NULL)
INSERT INTO consultant VALUES (101,NULL,10,'Rudi
OR Bruchez',SYSDATE,150);
(id_proj IS NOT NULL
AND formid IS NULL))); SQL> INSERT INTO consultant VALUES (102,NULL,NULL,'Jean
Problem',SYSDATE,10);
ERROR at line 1: ORA-02290: check constraint
(SOUTOU.CK_XOR) violated
Contraintes personnalisées
Le chapitre 1 a présenté quelques possibilités du langage OCL afin de spécifier des contraintes
à l’aide d’invariants de classes, de préconditions et postconditions à l’exécution d’opérations.
L’utilisation de rôles au niveau des liaisons entre classes du modèle conceptuel est bien souvent
nécessaire. Une expression OCL ne décrit pas l’implémentation d’une méthode, mais s’appa-
rente à un pseudo-algorithme.
L’exemple suivant décrit la contrainte que tout employé est soit chef, soit sous la responsabilité
d’un chef qui doit être employé dans la même entreprise que lui. L’outil ne génère pas cette
contrainte dans le script SQL. Il est préférable d’utiliser la solution universelle pour traduire
l’association réflexive de façon à pouvoir programmer un déclencheur dans de bonnes condi-
tions (éviter l’erreur des tables mutantes, avec Oracle : « ORA-04091: table name is
mutating, trigger/function may not see it »).
Je n’ai jamais rien compris à cette histoire de tables mutantes, limitation qui, à ma
connaissance, n’existe que chez Oracle. La norme SQL accepte qu’un déclencheur puisse
accéder à la table cible dudit déclencheur. SQL Server l’a mis en œuvre :
CREATE TRIGGER e_personne ON t_personne FOR UPDATE
AS
UPDATE t_personne SET nom = UPPER(nom)
WHERE prs_id IN (SELECT prs_id FROM inserted) -- table
comportant les données modifiées (équivalent du NEW)
GO
Mise en pratique
L’exercice 3.3 « La programmation de contraintes » vous propose de programmer quelques
contraintes sur différentes tables.
Dénormalisation
Avant de penser à la dénormalisation, il faut que vous soyez assuré que vos tables sont nor-
malisées au préalable… La majorité des problèmes de performances des applications en
production survient à la montée en charge au niveau du volume des données. En d’autres
termes, manipuler des tables mal conçues devient seulement pénalisant quand elles deviennent
volumineuses et ne tiennent plus en RAM. Quand les experts étudient le code et se rendent
compte que les tables ne sont pas normalisées, il est souvent déjà un peu trop tard. Partez sur
de bonnes bases (c’est le cas de le dire) : normalisez au maximum en amont !
Si vos tables sont normalisées et vos clés étrangères indexées, le plus gros du travail est fait.
Vous disposez d’autres outils que sont le partitionnement ou les vues matérialisées. Si malgré
tout ça, vos temps de réponse sont inacceptables, vous pouvez essayer de dénormaliser certaines
tables.
Vous pouvez dénormaliser une table en ajoutant des colonnes qui permettront de stocker
soit des colonnes calculées (qui éviteront des calculs), soit des données redondantes (mais
plus accessibles) ou des clés primaires (de taille plus réduite : une séquence par exemple) ou
étrangères (qui diminueront les jointures). Dans bien des cas, vous devrez programmer des
déclencheurs afin de maintenir l’intégrité dans le temps de votre nouvelle base. Si vous n’êtes
pas un adepte des déclencheurs, ce traitement devra être codé dans vos procédures.
La dénormalisation sera profitable si votre application effectue beaucoup de lectures et peu de
mises à jour. Si beaucoup de mises à jour sont réalisées, la dénormalisation dégradera sen-
siblement certaines performances. En revanche, si votre application effectue peu de lectures,
dénormaliser ne sert à rien (a fortiori lorsqu’il existe beaucoup de mises à jour).
Colonnes calculées
Dans l’exemple suivant, l’ajout des colonnes totaljp (nombre de jours à facturer) et totalj
(nombre de jours de formation dans l’année) évitera tout calcul impliquant des jointures avec
la table Inscriptions.
Duplication de colonnes
Dans l’exemple suivant, l’ajout des colonnes identite2 (nom du client) et ste2 (société du
client) évitera toute jointure avec la table Client pour lister les détails des inscriptions. Ici, on
régresse de la troisième à la première forme normale.
Les inconvénients de ce mécanisme sont d’une part l’espace utilisé, d’autre part le risque d’in-
cohérence si le nom d’un client vient à changer (ou le nom de sa société). La solution consiste
à utiliser un déclencheur sur la table Client ou une vue matérialisée (contenant entre autres
ces colonnes additionnelles).
On retrouve les mêmes inconvénients que précédemment (espace perdu et redondances). Pour
y remédier, il faudra programmer un déclencheur ou passer par une vue matérialisée.
Exemple de stratégie
Dénormaliser est une action forte sur la base, car la structure des tables sera altérée, des redon-
dances vont apparaître et des déclencheurs seront à mettre en œuvre. En conséquence, cette
technique doit être la dernière réponse à un problème de temps de réponse en exploitation et
en aucun cas justifiée par l’intérêt du programmeur.
Dans une base de données relationnelle, donc fortement transactionnelle, rien ne justifie
a priori la dénormalisation. Il faut avant tout normaliser au maximum. La dénormali-
sation étant un acte fort, elle ne peut que résulter d’une décision risquée prise en pleine
connaissance de cause à l’aide des critères suivants.
• Le gain de dénormalisation doit être prouvé : il faut donc mettre à l’épreuve la base
avec un volume de données significatif et une concurrence équivalente à celle de l’ex-
ploitation. Cela ne peut se faire généralement qu’en cours d’exploitation…
• Le gain doit être très important. Un gain minime sera généralement perdant à long
terme du fait du surcroît de volume généré par la redondance et l’accroissement des
temps de transaction (plus de données à mettre à jour, c’est toujours plus long).
• Le gain doit s’analyser globalement. L’erreur la plus courante est de ne mesurer que
le gain apporté à la table qui est dénormalisée. Or, la dénormalisation entraîne systé-
matiquement des effets de bord, qu’il est souvent difficile de mesurer de prime abord.
Par exemple, l’accroissement du volume des données comme l’allongement du temps
de mise à jour induit par la dénormalisation, a des répercussions sur les transactions
dont la durée augmente. De ce fait, les verrous durent plus longtemps et les risques de
blocage comme d’interblocage sont accrus.
Plus une table est petite (en nombre de colonnes), plus elle est facile à indexer. D’ailleurs,
le respect absolu de la normalisation des relations (pas de valeurs NULL) conduit à une
base dont les tables sont formées d’une clé et d’au plus un attribut non clé.
Enfin, avant de dénormaliser, il existe d’autres techniques telles que : l’hypernormalisa-
tion (par exemple ajouter une table des prénoms au lieu de mettre la colonne prénom dans
la table personne) ou le partitionnement.
Quelle que soit la solution d’implémentation que vous choisirez : normaliser au maximum,
dénormaliser, indexer telle ou telle colonne, programmer une contrainte dans une procédure
plutôt que dans un déclencheur, etc., vous rencontrerez des avantages, mais aussi des inconvé-
nients. Vous devrez toujours peser le pour et le contre de toute implémentation ou optimisation
pour décider finalement le plus souvent après des tests à grandeur nature.
idée reçue, composer sa base avec plus de tables ayant peu de colonnes rendra meilleures
les performances de vos requêtes.
2. Une clé primaire artificielle est préférable à une clé métier (sémantique).
En choisissant le numéro d’immatriculation d’une voiture, qui vous dit qu’à la création
de l’enregistrement, l’information sera connue ou que cette valeur n’évoluera pas dans
le temps (entraînant des effets de bord très coûteux). La clé métier est en général plus
volumineuse qu’une simple colonne NUMBER . L’idéal, c’est de définir une clé primaire
artificielle et de disposer aussi d’une clé métier (contrainte UNIQUE).
3. Ne codez jamais (à part dans vos tests ou démonstrations), une requête du type « SELECT
* … », cela pour les trois raisons principales suivantes :
Moins il y a de données qui circulent sur le réseau, plus les temps de réponse sont courts.
Il est donc préférable d’indiquer dans la liste des colonnes uniquement celles qui sont
nécessaires.
Allégez la charge du transformateur de requêtes en lui évitant de rechercher les informa-
tions dans les tables système pour déduire la liste de toutes les colonnes et les privilèges
associés.
Allez-vous interdire implicitement que vos tables évoluent en termes de structure ? Ajouter
ou supprimer une colonne risque de rendre le code inopérant à tout endroit où cette
instruction se trouvera.
4. Évitez si possible d’utiliser des curseurs dans vos transactions.
Les curseurs imposent une programmation itérative (où les données sont traitées ligne
par ligne comme avec un simple fichier) et non ensembliste. Un SGBD est optimisé pour
traiter de manière ensembliste les données avec SQL. Depuis la version SQL:1999, la
récursivité est prise en charge et SQL devient un langage complet (au sens de la machine
de Turing) où tout traitement peut être théoriquement programmé à l’aide de requêtes.
5. Écourtez la durée de vos transactions et programmez côté serveur (procédures cata
loguées).
Une transaction nécessite d’accéder souvent exclusivement aux données et des verrous
sont mis en œuvre automatiquement. Les verrous induisent des temps d’attente pour les
utilisateurs concurrents. Si votre code n’est pas optimisé ou s’il s’exécute du côté du client,
la contention devient inévitable.
6. Utilisez le SQL dynamique pour écrire des requêtes simples.
Le fait d’écrire une instruction avec du SQL dynamique évite au transformateur de
requêtes un certain nombre de tâches et permet la réutilisation du plan d’exécution.
7. Paramétrez la bonne collation.
Une collation sert à gérer la manière dont les chaînes de caractères, constituant les
données de la base, vont se comporter face aux opérateurs de comparaisons et à l’ordon-
nancement des données (tri). La gestion des majuscules/minuscules, accents, ligatures
(par exemple, cœur), etc. doit être prévue.
8. N’utilisez jamais une requête du type « SELECT MAX(...)+1 … » pour générer une clé
primaire.
Ce mode de calcul est à proscrire, car il peut conduire un jour ou l’autre au mieux à un
télescopage de clé, au pire à un blocage total. En effet, tant que la nouvelle ligne pourvue
de cette nouvelle clé n’est pas encore insérée dans la base, toute autre transaction peut
effectuer le calcul générant la même valeur. Afin de rendre cohérent ce mécanisme, il
faudrait programmer une transaction intégrant le calcul du max+1 et l’ordre d’insertion
avec la nouvelle clé (ce qui n’est pas aussi simple qu’il y paraît).
Préférez le mécanisme d’auto-incrément de votre SGBD qui pour Oracle est la séquence.
SEQUENCE et IDENTITY ont été normalisés (SQL:2008) SQL Server et IBM DB2 pren-
nent les deux en charge. PostGreSQL propose le SERIAL (équivalent du IDENTITY en
plus de la séquence).
9. Utilisez avec parcimonie les tables temporaires.
Chaque objet temporaire créé au sein d’un SGBDR déclenche une écriture coûteuse au
journal de transactions et dans le dictionnaire des données. Si de nombreuses transac-
tions sont effectuées en parallèle et qu’elles génèrent de nombreux objets temporaires, des
points de contention peuvent apparaître. Préférez l’utilisation de requêtes contenant des
fonctions table ou des CTE.
10. Utilisez des index, mais à bon escient.
Indexez vos clés étrangères et choisissez bien le mode d’indexage (B-tree, bitmap ou IOT).
Si une table IOT convient à une séquence, elle peut mener à des performances désas-
treuses pour une clé sémantique alphanumérique de taille variable.
Peu importe le nombre d’index d’une table, si chaque index apporte un gain considérable.
Avec un gain de 100 voire 1 000 (facilement obtenu sur des tables ayant un grand nombre
de lignes) c’est autant de temps de gagner pour les mises à jour, dont on oublie trop sou-
vent qu’elles nécessitent pour la plupart une lecture positionelle qui sera d’autant plus
rapide qu’il existe un index adéquat !
Mise en pratique
L’exercice 3.4 « La dénormalisation » vous invite à dénormaliser un schéma, mais quelle table
sera impactée ?
Dans l’exercice 3.5 « Ma psy oublie tout », vous devez aider ma psy qui oublie tout.
L’exercice 3.6 « Le planning d’une école de pilotage » est consacré à la gestion d’un planning
d’une école de pilotage.
Exercices
Vous devez définir un index sur chaque clé étrangère et typer les colonnes de la manière la
plus adéquate.
code_OACI Le code des aéroports est un classement géographique défini par 4 lettres
l’Organisation de l’aviation civile internationale.
heure_dep_reel, Heures de départ et d’arrivée réelles. Les heures vont de 0 à 23, et Heures et
heure_arr_reelle, les minutes de 0 à 59. minutes :
min_dep_reel, 2 chiffres
min_arr_reelle
Vous devez définir un index sur chaque clé étrangère et typer les colonnes de la manière la
plus adéquate.
id_jour, id_ligne Identifiants des jours (3 occurrences), des lignes (moins d’une Numériques de 1 à
et id_sta centaine) et des stations (plus de 300). 3 positions
lib_jour, nom_ligne Libellés des jours (30 caractères), des lignes (60 caractères) et Caractères de taille
et nom_station des stations (25 caractères). variable
heure, minute Heures et minutes de passage. Les heures vont de 0 à 23, les Numériques de
minutes de 0 à 59. 2 positions
(même si, parfois, il arrive qu’on atterrisse là où on décolle, mais ce n’est pas prévu au
programme en général).
●● Le nom des types de cartes est unique.
●● Les données dans les colonnes heures et minutes prévisionnelles doivent être valides (entre
0 et 23 pour les heures, tous les quarts d’heure pour les minutes).
●● Les heures de départ sont inférieures d’au moins une heure à celles d’arrivée.
Horaires de bus
Programmez les contraintes suivantes.
●● Pas plus de trois libellés « Lundi à vendredi », « Samedi » et « Dimanche et jours fériés »).
●● Les horaires sont à afficher sous la forme hh.min (avec hh de 6 à 22 et min de 0 à 59).
●● Seuls les clients arrivés depuis plus de 4 ans peuvent détenir jusqu’à 5 adresses e-mails.
3.4 La dénormalisation
Carte d’embarquement
Dénormalisez les tables du schéma de la carte d’embarquement pour, d’une part, connaître le
nombre de vols effectués par les passagers et, d’autre part, optimiser l’affichage suivant. Les
données additionnelles à prendre en compte sont le prix de chaque vol (seul le montant total
est affiché), les noms de chaque compagnie et des aéroports, et un libellé qui indique qu’il ne
reste qu’un faible nombre de places disponibles.
Horaires de bus
Réduisez le plus possible le schéma relationnel normalisé des horaires de bus quitte à dénor-
maliser certaines tables ou à abandonner de la cohérence.
Rendez-vous
Pour sa fête, ma psy a reçu un ordinateur d’un patient passionné. Connaisant ma névrose
du rangement et de l’organisation des données, elle m’a demandé de l’aider à mettre un peu
d’ordre dans ses fiches patients. Voici les données à conserver.
●● Qui est venu la voir et à quelle heure. La classification qui l’intéresse est la suivante :
enfant, ado, femme, homme ou couple. Notez que les séances d’un couple peuvent se pour-
suivre individuellement et qu’un patient ado peut revenir quelques années plus tard en tant
qu’adulte.
●● Par quel moyen (autre patient, docteur, bouche à oreille, Pages Jaunes, Internet, etc.) le
Confrères et livres
Pour débrieffer certaines séances lourdes, pour rigoler ou, parfois, pour pleurer, ma psy voit
des psys. Ses confrères sont de professions diverses (psychologue, psychotérapeute, psychiatre,
psychanaliste, sophrologue, marabout, etc.). Certains ont deux voire trois qualifications.
Les rendez-vous avec ses confrères doivent être modélisés. Elle désire noter les circonstances
de la première rencontre avec chacun des spécialistes côtoyés, pour raisons professionnelles
ou privées.
Elle envoie également certains de ses patients en consultations ponctuelles chez ses confrères
qui lui transmettent par la suite un mémo résumant la séance.
De plus, elle prête également des livres à ses patients, sans retour parfois. Elle souhaite donc
endiguer ce phénomène. Par contre, elle passe sous silence le fait que certains patients lui prêtent
des livres qu’elle dispose ensuite dans sa bibliothèque…
Ma psy ne fait pas un boulot facile alors ne ratez pas sa base de données !
Flotte
La flotte de l’école est composée de différents aéronefs. Les types se caractérisent le plus
souvent par un libellé avec ou sans code (par exemple, Aquila-AT01, Robin DR400-120, CES-
SNA-172N, DA40, SR20-G3, TB20, etc). L’immatriculation de l’avion, sa puissance et son
prix horaire doivent aussi être sauvegardés. Il est possible que l’école possède plusieurs aéro-
nefs de même type. Pour chaque avion 2 indicateurs sont importants à mettre à jour : le nombre
d’heures de vol de la cellule et le nombre d’heures de vol du moteur (qui est changé plusieurs
fois au cours de la vie de l’appareil).
Chaque aéronef doit être révisé périodiquement en fonction du nombre d’heures d’utilisation
(50 h, 100 h, 500 h, 1 000 h ou 2 000 h). Les dates de ces visites de maintenance doivent être
mémorisées de même qu’un éventuel commentaire. Il en va de même pour le détail des pièces
achetées (prix TTC) lors de l’entretien, ainsi que le nombre total d’heures de travail néces-
saires.
Acteurs
Élèves pilotes et instructeurs évoluent dans cette structure. Les élèves s’inscrivent à une date
qui doit être mémorisée. Pour tous, les nom, prénom et adresse doivent être connus. Tous dis-
posent d’un compte sur lequel ils peuvent déposer une somme d’argent. Les sommes prélevées
correspondent au montant du vol effectué par un élève pilote ou par un instructeur s’il réserve
l’avion pour lui.
Les instructeurs, qui sont identifiés sur le planning par un trigramme inspiré de leur nom,
bénéficient d’une réduction sur le coût horaire (différente en fonction de chaque type d’avion).
Notez qu’un instructeur n’est pas forcément qualifié sur tous les types d’appareils de l’école.
Chaque séance de vol (soit en instruction, soit en solo lorsque l’élève pilote vole seul) effectuée
est décomptée en dixièmes d’heures (par exemple, 1.5 signifie 1 h 30 de vol) et doit être mémo-
risée avec la date du vol. Le nombre total d’heures de vol pour un élève ou pour un instructeur
doit être facilement accessible, que ce soit pour les vols d’instruction (en double commande)
ou en solo.
Élèves et pilotes doivent passer annuellement ou semestriellement une visite médicale. Sa date
et son résultat (apte ou inapte) doivent être consignés, ainsi qu’un éventuel commentaire.
Rendez-vous
Tous peuvent effectuer des réservations. Il suffit de s’inscrire sur le planning en sélectionnant
l’aéronef, la plage horaire et, éventuellement, l’instructeur désigné par ses initales. Il est égale-
ment possible de noter un commentaire et le nombre de places disponibles. Notez que certains
avions peuvent être indisponibles, durant une période plus ou moins longue, pour cause de
maintenance.
Le niveau externe
Le niveau externe présenté dans ce chapitre concerne la définition et la manipulation des
vues (views). Les vues agissent comme des fenêtres sur la base de données. Une vue est
construite à l’aide d’une requête qui retourne un résultat tabulaire. C’est pour cette raison
qu’un vue apparaît à un utilisateur sous la forme d’une table. En réalité, une vue ne contient
pas de données (excepté les vues matérialisées), elle ne fait que filtrer les données issues de
tables.
Pour tout développement de qualité, les vues sont indispensables pour éviter tout accès direct
aux tables. En pratique, bon nombre d’applications se passent de ce concept, en manipulant
directement les tables.
En plus d’un contrôle fin à l’accès aux données (confidentialité, sécurité et privilèges), une vue
permet de masquer la complexité ou de dénormaliser des schémas relationnels, d’implémenter
des contraintes de valeur (ou d’intégrité) et de simplifier la formulation de requêtes complexes.
La figure suivante illustre trois accès à une base de données. Chaque utilisateur opère sur un
schéma externe composé des vues accessibles pour son profil. Les données peuvent provenir
de différentes tables et sont toujours stockées dans des tables (sauf pour le cas des vues maté-
rialisées qui combinent les concepts de table et de vue).
La majeure partie des opérations réalisées sur une vue sont des extractions, mais dans cer-
tains cas, une vue peut être modifiable (les mises à jour impacteront alors la table source). Par
ailleurs, nous verrons qu’un type de déclencheur (instead of trigger) permet de programmer
des mises à jour de vues multitables.
Le niveau externe concerne aussi les routines SQL permettant de présenter ou de mettre
à jour les données de manière indirecte (procédures stockées, déclencheurs et UDF ou
User Defined Function).
Somme toute, une vue n’est qu’un nom de table donné à une requête d’extraction de
données (SELECT) et on constatera d’après la norme SQL que les vues sont considérées
comme des tables d’un type particulier VIEW, les tables conventionnelles étant considé-
rées en tant que BASE TABLE . Notons dès à présent qu’il est possible, dans certains cas,
de mettre à jour par INSERT, UPDATE , DELETE ou MERGE , les données des tables à travers
les vues.
Une catégorie particulière de routines, les fonctions table, permet de mettre en œuvre des
vues avancées. Le fait qu’une fonction table admette des paramètres en entrée et retourne
un jeu de données, rend possible la réalisation de vues paramétrables.
Globalement, les procédures stockées permettent de réaliser des traitements complexes
de mise à jour en masquant la complexité à l’utilisateur. Une procédure stockée peut aussi
renvoyer un ou plusieurs jeux de données.
Enfin, des déclencheurs d’un type particulier, les trigger INSTEAD OF, permettent de
réaliser des traitements complexes, à la manière des procédures, lorsque survient une
opération de mise à jour (INSERT, UPDATE ou DELETE).
Tous ces éléments constituent le modèle externe de données (MED).
Pour tout développement de qualité, les objets du MED sont indispensables pour éviter
tout accès direct aux tables. En pratique, bon nombre d’applications se passent de ce
concept en manipulant directement les tables. Et c’est une erreur ! En effet, la couche d’in-
terface ou d’abstraction apportée par le modèle externe de données rend indépendants la
structure de la base et l’accès aux données. En gros, une modification de la structure des
tables de la base n’affecte pas la couche externe et si l’application a été développée sur
cette couche, il n’est généralement pas nécessaire de la modifier pour qu’elle continue de
fonctionner, sauf si les modifications de structure apportent de nouvelles fonctionnalités
ou portent atteinte aux données stockées dans la base.
En combinant vues, fonctions table, déclencheurs INSTEAD OF et procédures stockées,
on peut concevoir des structures de données proches de celles des objets applicatifs et y
greffer les méthodes CRUD de manipulation desdits objets (INSERT, SELECT, UPDATE ,
DELETE). En fait, le modèle externe de données simule de manière performante ce qu’un
ORM (Object Relational Mapping) fait de manière contre-performante !
La syntaxe SQL utilisée dans ce chapitre est celle d’Oracle ; elle est relativement proche du
standard en comparaison avec d’autres SGBD (excepté concernant les vues objet).
Une vue est créée à l’aide d’une instruction SELECT appelée « requête de définition ». Cette
requête interroge une ou plusieurs tables, vues (ou vues matérialisées). Une vue se recharge
chaque fois qu’elle est interrogée.
●● alias désigne le nom de chaque colonne de la vue. Si l’alias n’est pas présent, la colonne
prend le nom de l’expression renvoyée par la requête de définition.
●● requête_SELECT extrait des données en provenance d’une ou de plusieurs tables, vues
ou vues matérialisées. Tous les éléments de la clause SELECT doivent comporter un nom
unique.
●● WITH READ ONLY déclare la vue non modifiable par INSERT, UPDATE ou DELETE.
●● WITH CHECK OPTION garantit que toute mise à jour de la vue par INSERT ou UPDATE
s’effectuera conformément au prédicat de la requête de définition.
Classification
On distingue les vues simples des vues complexes en fonction de la nature de la requête de
définition. Le tableau suivant résume cette classification.
Une vue monotable est aussi considérée comme étant complexe si la requête comporte le
mot-clé DISTINCT, les clauses HAVING , GROUP BY ou WINDOW, une fonction de fenêtrage,
ou des colonnes définies par des expressions calculées ou constantes.
Avec Oracle, une vue est complexe si la requête comporte le mot-clé DISTINCT, ROWNUM
ou ROW_NUMBER, ORDER BY, HAVING ou CONNECT BY, des colonnes définies par des
expressions ou des colonnes NOT NULL dans les tables qui ne sont pas sélectionnées par
la vue.
La structure de ces tables est présentée dans le tableau suivant. Les colonnes NOT NULL
doivent être tout particulièrement considérées lors d’éventuelles mises à jour.
Vues monotables
Le tableau suivant crée la vue monotable v_employes dans le schéma soutou. Cette vue
décrit les employés dont le salaire dépasse 10 000 (restriction du WHERE) et masquant certaines
colonnes (restriction du SELECT). Notez les alias de colonnes qui permettent de masquer le
nom des colonnes originales de la table source.
Une fois créée, la vue s’interroge comme une table par un utilisateur, sous réserve de détenir
le privilège de lecture (GRANT SELECT ON nom_vue TO nom_schema). Le tableau suivant
présente deux extractions de cette vue.
ID_EMPLOI COUNT(ID_EMP)
----------- --------------
SA_REP 14
SA_MAN 5
AD_VP 2
MK_MAN 1
PR_REP 1
AD_PRES 1
PU_MAN 1
AC_ACCOUNT 1
AC_MGR 1
FI_MGR 1
Vues complexes
Une vue complexe est caractérisée par le fait qu’elle contient, dans sa définition, plusieurs
tables (jointures, sous-requêtes, expressions de tables : CTE), une fonction appliquée à
des regroupements, une fonction de fenêtrage, le mot-clé DISTINCT ou des expressions de
colonnes.
La mise à jour directe (par INSERT ou UPDATE ou DELETE) de telles vues n’est pas possible
sans programmer un déclencheur INSTEAD OF.
Le tableau suivant présente la vue multitable v_dept_calculs du schéma soutou qui extrait
pour chaque département, le nom du manager, le nombre d’employés, ainsi que les salaires
minimum, maximum et moyens.
Conseil avisé
Il est toujours préférable de programmer une jointure à l’aide de l’opérateur relationnel
INNER JOIN plutôt que dans WHERE : d’une part, pour des raisons de performances (cer-
tains SGBD y sont sensibles), d’autre part, d’un point de vue de la maintenance du code
(il est plus efficace de modifier une requête ainsi écrite).
Une fois créée, la vue multitable s’interroge simplement (sans jointure). Le tableau suivant
présente une extraction de cette vue.
Il est possible de mettre à jour toutes les vues, soit directement, soit indirectement par
l’intermédiaire de déclencheurs INSTEAD OF (RULE et FUNCTION pour PostgreSQL).
Vues modifiables
Lorsqu’il est possible d’exécuter des instructions insert, update ou delete directement sur
une vue, elle est dite modifiable (updatable view). Pour mettre à jour une vue simple, il doit
exister une correspondance biunivoque entre les lignes de la vue et celles de l’objet source.
Pour pouvoir mettre à jour une vue complexe, il est nécessaire de programmer un déclen-
cheur de type INSTEAD OF.
Il va de soi qu’une vue créée avec la directive WITH READ ONLY ne peut être mise à jour quelle
que soit sa structure…
La première vue monotable (employés dont le salaire dépasse 10 000) citée en exemple est
modifiable sous réserve de renseigner les colonnes déclarées non nulles (la clé primaire en fait
partie). Ici, la condition de correspondance biunivoque est respectée.
En revanche, la deuxième vue multitable (employés, manager et détails sur les employés) ne
peut pas être mise à jour d’une manière directe, car d’une part, la clé primaire n’est pas pré-
sente, d’autre part, les résultats fournis proviennent de calculs d’agrégats et il serait insensé de
vouloir insérer un calcul directement.
Le tableau suivant présente quelques mises à jour possibles (sous réserve de respecter en amont
les contraintes de clés et de valeurs qui existent au niveau de la table source).
Opérations Résultat
La première instruction est un peu paradoxale, car elle permet l’ajout, en passant par la vue,
d’un employé qui ne repassera plus par la suite le filtre de la vue (l’information du salaire est
manquante et forme la condition de filtre de la vue).
La directive WITH CHECK OPTION, qui empêche un ajout ou une modification non conforme
à la définition de la vue, permet d’éviter ce genre d’effets de bord qui peuvent être indésirables
pour l’intégrité de la base.
Contrainte de vérification
Il est nécessaire de redéfinir la vue, le tableau suivant décrit cette action et la tentative d’ajout
d’un employé non doté de salaire.
View created.
Les règles qui régissent les insertions ne sont pas identiques à celles qui concernent les
mises à jour ou suppressions. Des vues complexes peuvent être modifiables, dans une cer-
taine mesure, lorsqu’une table source est dite protégée par sa clé (key preserved).
Une table est dite protégée par sa clé (key preserved) si sa clé primaire est préservée dans
la clause de jointure et se retrouve en tant que colonne de la vue multitable (pouvant jouer le
rôle de clé primaire de la vue).
Considérons la vue complexe qui joint les tables des départements et des employés en incluant
toutes les colonnes non nulles. On pourrait penser que les deux tables sont protégées par clé et
sont modifiables par la vue.
En réalité, seule la table employees est protégée par clé dans cette vue, car elle joue le rôle de
la relation enfant tandis que la table departments joue le rôle de parent. En effet, toute ligne
de cette table contiendra un unique numéro d’employé, tandis que le numéro de département
est susceptible de se dupliquer.
Avec Oracle, afin de savoir dans quelle mesure les colonnes d’une table sont modifiables par
une vue (insertion, modification ou suppression), il faut interroger le dictionnaire des données
par l’intermédiaire de la vue USER_UPDATABLE_COLUMNS.
Requête Résultat
Le tableau suivant présente quelques mises à jour valides (sous réserve de respecter en amont
les contraintes de clés et de valeurs qui existent au niveau de la table source).
Opérations Résultat
La première instruction est encore un peu étrange, car elle permet l’ajout, en passant par la
vue, d’un employé qui ne repassera plus par la suite le filtre de la vue (l’information du dépar-
tement d’appartenance est manquante).
Les vues peuvent également servir à assurer la confidentialité, simplifier l’écriture de requêtes
complexes, implémenter l’intégrité référentielle et dénormaliser.
Confidentialité
La confidentialité reste une des vocations premières des vues. En plus de renommer ou de
masquer des colonnes, il est possible de restreindre l’accès à des données d’une manière tem-
porelle. La vue suivante restreint les accès à une table d’un point de vue temporel.
Il est possible de restreindre davantage les accès à un utilisateur particulier en utilisant les
mécanismes de transmission ou de révocation de privilèges. Il est par ailleurs toujours préfé-
rable qu’un utilisateur transmette des droits sur ses données en utilisant des vues.
Les privilèges objet (en opposition aux privilèges système comme pouvoir démarrer la base,
créer un schéma, etc.) qu’il est possible d’attribuer sur une vue sont les mêmes que ceux qui sont
applicables sur une table (à savoir SELECT et UPDATE sur des colonnes, INSERT et DELETE).
GRANT SELECT ON soutou.v_employes_JO Accès pour tous (sous réserve d’un jour ouvré…) en lecture
TO PUBLIC; sur la vue v_employes_JO du schéma soutou.
Simplification de requêtes
Considérons la table jobs qui appartient aussi au schéma hr d’Oracle. Une partie des données
est présentée ci-après.
La requête à simplifier est celle qui doit extraire, pour chaque département, la masse salariale
médiane de chaque département en fonction des types d’emplois. Par exemple, le départe-
ment 90 est composé d’un employé de type AD_PRES et de deux employés de type AD_VP. Le
montant calculé pour ce département doit être égal à : 1 × (40 000 – 20 080) + 2 × (30 000
– 15 000) = 49 920.
Construisons les vues nécessaires pour simplifier cette requête. La première vue groupe les
effectifs de chaque département par type d’emploi.
30 PU_CLERK 5
30 PU_MAN 1
40 HR_REP 1
50 SH_CLERK 20
50 ST_CLERK 20
50 ST_MAN 5
60 IT_PROG 5
70 PR_REP 1
80 SA_MAN 5
80 SA_REP 29
90 AD_PRES 1
90 AD_VP 2
100 FI_ACCOUNT 5
100 FI_MGR 1
110 AC_ACCOUNT 1
110 AC_MGR 1
La deuxième vue joint ces effectifs pour extraire le salaire médian de chaque type d’emploi. Il
s’agit ici d’une vue complexe interrogeant conjointement une table et une autre vue.
30 PU_CLERK 5 3000
30 PU_MAN 1 7000
40 HR_REP 1 5000
50 SH_CLERK 20 3000
50 ST_CLERK 20 2992
50 ST_MAN 5 3000
60 IT_PROG 5 6000
70 PR_REP 1 6000
80 SA_MAN 5 10080
80 SA_REP 29 6008
90 AD_PRES 1 19920
90 AD_VP 2 15000
La troisième vue cumule le salaire médian de chaque type d’emploi pour tout département.
N_DEPT ID_EMPLOI CUMUL
---------- ------------ ---------
80 SA_MAN 50400
80 SA_REP 174232
90 AD_PRES 19920
90 AD_VP 30000
La requête finale cumule ces sommes pour chaque département. Aucune jointure n’intervient
et toute la complexité est masquée par les trois niveaux de vues en amont. Essayez d’écrire
cette requête sans utiliser de vues intermédiaires, vous m’en direz des nouvelles.
L’exemple le plus classique de simplification par les vues est la présentation de l’infor-
mation par tranches… Par exemple, l’évolution des taux de TVA est fonction d’une date
d’application, qui rend de fait caduque l’application du barème précédent à la date J-1…
TVA_TAUX FLOAT)
INSERT INTO T_TVA VALUES
('Super Réduit', '1982-07-01', 5.50),
('Super Réduit', '1989-01-01', NULL),
Ce serait une énorme faute que de rajouter à la table une date de fin d’application, car en cas d’erreur de
saisie, on pourrait se retrouver soit avec plusieurs taux différents pour un même jour, soit aucun…
À noter : la présence d’une ligne avec un taux à NULL signifie tout simplement la disparition de ce taux
de TVA !
La vue v2 restitue les départements qui n’embauchent aucun employé. La vue v1 restitue les
employés associés à un département existant et ceux qui ne sont associés à aucun département
(la condition IS NULL peut être omise dans la vue si chaque enfant doit être obligatoirement
rattaché à un parent).
Les règles que vous devez respecter pour manipuler les données sont les suivantes.
• Côté parent : modifications, insertions et suppressions par la vue v1 et lecture de la table t1.
• Côté enfant : modifications, insertions, suppressions et lecture par la vue v2.
Toute suppression est possible à travers la vue v2 (sous Suppression correcte (enfants absents) :
réserve de l’existence d’autres contraintes référentielles). DELETE FROM v1
WHERE department_id = 900;
Le raisonnement sur deux tables peut se généraliser à une hiérarchie d’associations ou à diffé-
rentes associations issues de la même table.
Chacun sait qu’une parcelle de terrain est un polygone et qu’un polygone se doit d’avoir
au moins 3 sommets. Tant que l’on n’a pas saisi 3 points, pas de polygone. Or, aucune
contrainte ne peut « attendre » l’arrivée du troisième point pour valider ou invalider les
données. Dans ce cas, la solution réside dans la vue :
CREATE VIEW V_PARCELLE_GEOMETRIE_PCG AS
SELECT * FROM T_PARCELLE_GEOMETRIE_PCG AS P1
WHERE EXISTS(SELECT 1
FROM T_PARCELLE_GEOMETRIE_PCG AS P1 AS P2
WHERE P1.PCL_NUMERO_CADASTRAL = P2.PCL_NUMERO_CADASTRAL
AND P1.PCG_NUMERO_POINT = P2.PCG_NUMERO_POINT
GROUP BY P2.PCG_NUMERO_CADASTRAL, P2.PCG_NUMERO_POINT
HAVING COUNT(*) >= 3);
Cette dernière ne fera apparaître que les données des points des parcelles pour celles
formant des polygones… Mais comme on ne sait pas à l’avance le nombre de points d’un
polygone, la manière la plus pratique est de rajouter cette information de « fermeture »
du polygone à un niveau supérieur :
CREATE TABLE T_PARCELLE_PCL
(PCL_NUMERO_CADASTRAL VARCHAR(16) NOT NULL PRIMARY KEY,
PCL_SAISIE_FINALISE BOOLEAN NOT NULL DEFAULT 0);
Dès lors, lorsque le géomètre a terminé sa saisie, il fait passer l’information PCL_
SAISIE_FINALISE à 'true' et le polygone représentant la parcelle devient visible à
travers la vue suivante :
CREATE VIEW V_PARCELLE_GEOMETRIE_PCG AS
SELECT * FROM T_PARCELLE_GEOMETRIE_PCG AS PCG
INNER JOIN T_PARCELLE_PCL AS PCL
ON PCL.PCL_NUMERO_CADASTRAL = PCG.PCL_NUMERO_CADASTRAL
WHERE PCL_SAISIE_FINALISE;
Un autre exemple concerne les clients et les prospects. Un prospect n’est autre qu’un
client qui n’a jamais effectué de commande. Dès lors, clients et prospects peuvent figurer
dans la même table physique (CONTACT) ce qui simplifie beaucoup les choses. Il n’y aura
qu’à créer deux vues modifiables, chacune d’elles avec toutes les colonnes de la table des
contacts, l’une présentant les données des prospects, l’autre celle des clients, avec les
définitions de vues suivantes :
CREATE VIEW V_CLIENT_CLI AS
SELECT * FROM T_CONTACT_CTC
WHERE CTC_ID IN (SELECT CTC_ID FROM T_COMMANDE_CMD);
Dénormalisation
Les vues peuvent aider à dénormaliser un schéma relationnel. Il est possible de créer volon-
tairement des résultats tabulaires qui ne respectent aucune des formes normales (de la 1re à
la 5e).
L’exemple suivant ne respecte pas la deuxième forme normale. En effet, la clé étant id_emp,
la présence de la colonne department (nom du département qui dépend davantage d’un code
département) fait abandonner la troisième forme normale.
Pour quitter la virtualisation, si vous rendez cette vue physiquement existante (materialized
view), vous implémentez une dénormalisation.
Lorsque l’on parle de « modèle relationnel », ce n’est pas à un modèle particulier que
nous nous adressons, mais à l’ensemble des modèles nécessaires à la « fabrication » d’une
base de données. Ainsi, comme nous l’avons vu, ce fameux modèle relationnel se décline
en (dans l’ordre) MCD, MLD, MPD et MED. Piqûre de rappel…
Le modèle conceptuel de données est le premier des modèles relationnels qui doit être
établi. Il découle de l’analyse et permet de rendre compte de la sémantique des données.
Son formalisme a été élaboré par Peter Chen en 1976. Il compte des entités et des asso-
ciations. Ces objets peuvent être représentés par différentes notations comme la très
française MERISE, la plus moderne UML 2 ou encore IDF1X, ER, etc.
Le modèle logique de données est le deuxième des modèles et se trouve être la traduc-
tion mathématique du premier. Ce modèle, élaboré par Frank Edgar Codd dans les
années 1970, comporte des « relations » (c’est-à-dire des objets mathématiques porteurs
d’informations) constituées d’attributs dont certains, communs entre différentes rela-
tions, servent de liens. Il permet d’affiner le modèle conceptuel d’un point de vue logique,
mais pas physique.
Le modèle physique de données est le troisième des modèles et découle directement du
second dont il n’est que la traduction physique, c’est-à-dire sur une machine SQL. Ce
modèle a aussi été élaboré par Frank Edgar Codd, mais c’est Larry Ellison, alors tout
jeune entrepreneur, qui en fait la première implémentation sur un produit qu’il dénomme
Oracle V2 (version 2, la première n’ayant jamais existé). Selon que l’on utilise Oracle,
SQL Server, DB2 ou PostgreSQL, le modèle est légèrement différent, car il résulte de la
capacité à prendre en compte ou non tel ou tel type de données, telle ou telle contrainte…
Il est constitué de tables et de colonnes, mais aussi de contraintes et d’index.
Le modèle externe de données est le dernier des modèles relationnels. Souvent oublié, il
permet de présenter les informations d’une manière lisible, simplifiée et enrichie de façon
à faciliter le travail des développeurs et à rendre évidente la compréhension des données
par les utilisateurs. Il est constitué de vues et de routines SQL : procédures, déclencheurs,
fonctions. À nouveau, il a été élaboré par Franck Edgar Codd, dans les années 1980, au
tout début des premières expériences sur les SGBDR commerciaux que sont Sytème R
et Oracle. Son but est de rendre indépendante la structure physique de la base, de celle
perçue au niveau du développement, afin que des modifications apportées aux tables n’en-
traînent que peu d’effets sur le code applicatif.
Bien que les développeurs ne pensent jamais à utiliser proprement le modèle externe de
données, ils en utilisent généralement une partie, celle consacrée aux routines, à force
de constater que les performances du code de traitement d’un SGBDR sont sans com-
mune mesure avec celles qu’ils peuvent obtenir d’un traitement itératif dans un langage
hôte, dès que la montée en charge se fait sentir (accroissement du volume des données
ou de la concurrence…). Il est alors dommage de constater l’absence de vues, qui leur
auraient grandement facilité le travail, surtout en termes d’évolution de la structure de
la base…
De même, l’utilisation inconsidérée des ORM (Hibernate, Symfony, Doctrine…) n’est
qu’un pis-aller de substitution au MED et possède l’inconvénient majeur de dégrader
singulièrement les performances applicatives. En effet, il n’est pas rare qu’un ORM
multiplie par 10 ou 20 les temps de réponse par rapport à une approche procédurale
en SQL.
Les vues matérialisées contribuent à l’amélioration des jointures du fait du stockage de lignes
précalculées et de la possibilité de réécriture de requêtes (query rewrite). De plus, il est pos-
sible d’utiliser le partitionnement et l’indexation sur une vue matérialisée.
Réécriture de requêtes
La réécriture de requêtes est une technique d’optimisation qui transforme une requête complexe
émise sur une table volumineuse en une requête sémantiquement équivalente interrogeant la vue
matérialisée. Dès qu’il est plus intéressant d’utiliser la vue matérialisée parce qu’elle contient des
résultats déjà calculés (agrégats et jointures), toute requête est réécrite par le moteur relationnel
du SGBDR d’une manière transparente pour l’utilisateur et utilise la vue à la place de la table
(initialement interrogée). Aucun code n’est à ajouter dans l’instruction SQL qui ne référence que
la ou les tables interrogées, la substitution se faisant à la volée à l’exécution de la requête.
En général, les vues matérialisées sont basées sur la clé primaire des tables sources (ou sur la
colonne rowid). Dans un contexte d’entrepôts de données, les vues matérialisées composent
généralement des regroupements (agrégations) et des jointures.
Du fait du stockage de données redondantes (lignes présentes physiquement à la fois dans les
tables sources et dans la vue matérialisée), des méthodes de rafraîchissement (refresh) sont dis-
ponibles et peuvent être de nature incrémentale (fast refresh) ou complète (complete refresh).
Les vues matérialisées (vues indexées chez MS SQL Server) se basent le plus souvent sur
la clé primaire ou sur un identifiant interne de ligne (rowid pour Oracle) de manière à
connaître la provenance des données.
La mise à jour d’une vue peut être synchrone ou asynchrone. Dans le cas d’une mise à
jour synchrone, la vue et les tables sous-jacentes doivent avoir une relation univoque de
manière à savoir quelle ligne est à modifier dans la vue du fait des changements dans les
tables sources. En effet, la modification des données de la vue se fait par différence et
non par recalcul afin de minimiser l’impact des mises à jour dans les tables sources. Pour
les vues asynchrones, on peut généralement choisir la méthode de rafraîchissement des
données de la vue comme sa fréquence. Oracle supporte les vues asynchrones, MS SQL
Server ne propose pour l’heure que des vues synchrones.
Les jointures entre employés et départements de ce lieu utiliseront la vue à la place des tables
d’une manière bien plus efficace. Pour les besoins d’une requête en particulier, des index
uniques ou non peuvent s’ajouter : CREATE INDEX … ON nom_vue (colonne1,colonne2…).
Le rafraîchissement
Le rafraîchissement incrémental évite de reconstruire la vue matérialisée entièrement. Cepen-
dant, ce mécanisme doit s’opérer relativement rapidement (à la demande ou périodiquement)
pour garantir l’intégrité des données. Chaque table est associée à un journal d’opérations
(materialized view log) qui recense toutes les modifications effectuées sur la table.
Dans un contexte de réplication, les vues matérialisées permettent de maintenir sur une base
locale des copies de données distantes. Ces copies peuvent être modifiables (sous réserve que
le SGBD le permette, avec Oracle il s’agit de l’option Advanced Replication).
Le rafraîchissement automatique nécessite de créer un journal d’opérations par table interrogée.
Les exemples suivants décrivent des vues matérialisées qui se mettront à jour automatique-
ment. La première vue (tous les employés) sera mise à jour dès que la table employees sera
modifiée. La deuxième (tous les départements) sera systématiquement actualisée tous les
lundis à 15 h.
CREATE MATERIALIZED VIEW LOG ON hr.departments d Création du journal des opérations qui sera vidé
WITH PRIMARY KEY, ROWID tous les 5 jours.
PURGE REPEAT INTERVAL '5' DAY;
Les vues indexées ou matérialisées ne sont pas la panacée et doivent être abordées avec
circonspection…
Tout d’abord, la vue doit être déterministe, c’est-à-dire toujours fournir les mêmes résul-
tats si les tables sources ont les mêmes données, ce qui exclut l’appel à des fonctions
comme celles fournissant la date et l’heure courantes ou encore celles renvoyant des
données aléatoires (RAND, GUID ou UUID…).
Il existe de nombreuses restrictions à l’écriture de vues synchrones. Comme les lignes
originelles doivent pourvoir être retrouvées, cela exclut certains opérateurs d’agréga-
tion autres que SUM , COUNT, MAX et MIN , les jointures externes, les sous-requêtes, les
valeurs non définies (NULL), les opérations ensemblistes (UNION , INTERSECT, EXCEPT),
l’opérateur DISTINCT, les fonctions de fenêtrage, les groupages OLAP (CUBE , ROLLUP,
GROUPING) et presque tous les opérateurs particuliers spécifiques à certains SGBDR.
Lorsque la vue contient des calculs mathématiques, il est important (mais pas impératif)
que les expressions intègrent des calculs précis, c’est-à-dire effectués sur des types SQL à
précision fixe, définie et limitée. On devra alors utiliser du DECIMAL (ou NUMERIC) ou des
entiers (SMALLINT, INT, BIGINT). En effet, l’emploi d’un type de données numériques à
précision flottante comme REAL ou FLOAT, induirait fatalement des erreurs de calcul du
fait que les données sont mises à jour par différence et non par recalcul (erreurs d’écart
d’arrondi).
Bien que les vues indexées ou matérialisées soient d’une puissance phénoménale
lorsqu’elles sont judicieusement utilisées, il ne faut pas les systématiser. En effet, le but
d’une telle vue n’est pas de fournir l’exacte réponse à une requête, mais de participer à la
simplification d’une partie de la requête finale…
Ainsi, il ne faut pas chercher à créer autant de vues indexées qu’il y a de requêtes
« lourdes », mais trouver quels sont les dénominateurs communs de ces lourdes requêtes
et factoriser le point dur par une vue matérialisée.
En effet, et comme toujours dans les bases de données, l’excès d’utilisation d’un système,
même très alléchant, peut conduire à l’effet inverse, car n’oublions pas que de telles vues
stockant les données constituent de la redondance, plombent le volume global de la base,
et plus encore, encombrent le cache des données…
Les vues objet de tables relationnelles permettent de conserver les données telles quelles, sans
modifier structurellement la base. Ce mécanisme est intéressant, car il permettra aux pro-
grammeurs de migrer sans effet de bord vers la technologie objet. Par la suite, des méthodes
peuvent être programmées. Ces méthodes peuvent coder des transactions tout en manipulant
des données tabulaires.
Décrivons les mécanismes qu’Oracle propose.
Étapes à respecter
Plusieurs étapes sont nécessaires à la définition d’une vue objet.
●● Utiliser un type (existant ou à créer) qui formera la structure de la vue. Ce type peut inclure
●● Spécifier un identifiant (OID), valeur unique basée sur un attribut clé primaire en général.
Cet identifiant permettra de créer une référence vers chaque objet de la vue (comme pour
les tables objet qui peuvent être accessibles par références).
●● Si la vue doit être modifiable (updatable object view), il faudra programmer un déclencheur
INSTEAD OF.
La syntaxe simplifiée de création d’une vue SQL3 est la suivante.
CREATE VIEW [nom_schéma.]nom_vue
[ (alias1, alias2… ) ]
OF [schéma.]nom_type
{ WITH OBJECT IDENTIFIER { DEFAULT | ( colonne [, colonne]...) }
| UNDER [nom_schéma.]nom_super_vue }
AS requête_SELECT
[WITH { READ ONLY | CHECK OPTION } ];
●● OF nom_type précise le nom du type qui forme la structure de la vue.
●● WITH OBJECT IDENTIFIER précise la clé primaire de la table source.
●● UNDER spécifie l’héritage de vue.
●● requête_SELECT requête de définition interrogeant une ou plusieurs tables ou vues.
●● WITH READ ONLY et WITH CHECK OPTION ont la même signification que les vues SQL2.
Étudions la construction et la manipulation d’une vue objet à partir des tables relationnelles
employees et departments. Suivons les étapes énoncées précédemment.
associer plusieurs employés à tout département. Si le nombre d’employés est limité, on choisira
de travailler avec un varray, sinon il faudra utiliser une nested table.
En construisant des résultats tabulaires incluant des collections, vous dénormalisez en deçà
de la première forme normale.
Trois types sont nécessaires pour composer la structure de la vue : celui de l’élément de la
collection, celui de la collection elle-même et celui du type de la vue qui contient la collection.
Il est possible de construire dynamiquement des collections (NESTED TABLE ou VARRAY) lors
de la création d’une vue objet à l’aide des directives CAST et MULTISET. La directive cast
convertit un résultat dans un type (ici, la requête crée une collection qui est nommée). Si le
résultat d’une requête retourne plusieurs enregistrements, il est nécessaire d’utiliser conjointe-
ment la directive multiset.
La définition de la vue inclut la spécification de l’OID basé sur la clé primaire de la table source
(colonne department_id). La requête extrait, dans un premier temps, quatre colonnes de
la table departments. Par la suite, pour chaque enregistrement de la table employees, la
directive MULTISET construit un ensemble d’éléments composé de plusieurs colonnes de la
table enfant. La directive CAST nomme l’ensemble obtenu emps_nt, collection affectée à la
dernière colonne du type de la vue.
Oracle dispose de nombreux opérateurs qui permettent de manipuler des collections au sein
de requêtes (CARDINALITY, MULTISET EXCEPT, MULTISET INTERSECTION, MULTISET
UNION, etc.).
Pour toute mise à jour qu’il n’est pas possible d’écrire directement, vous devrez programmer
un déclencheur INSTEAD OF qui se chargera de propager les nouvelles valeurs des colonnes
modifiées de manière cohérente à travers les tables sources.
CREATE OR REPLACE TYPE BODY departement_t AS Codage des deux méthodes. Le mot-clé SELF
MEMBER FUNCTION nbre_emp RETURN NUMBER IS désigne l’objet qui appelle la méthode.
total NUMBER := 0;
BEGIN
SELECT COUNT(id_emp) INTO total
FROM TABLE
(SELECT emps_nt FROM v_obj_dept_emps
WHERE n_dept=SELF.n_dept);
RETURN total;
END nbre_emp;
MEMBER PROCEDURE ajoute_emp(id IN NUMBER,
pr IN VARCHAR, no IN VARCHAR, da IN DATE)
IS
BEGIN
INSERT INTO hr.employees
(employee_id,first_name,last_name,email,
phone_number, hire_date,job_id,salary,
commission_pct,manager_id,department_id)
VALUES (id,pr,no,'mail',NULL,da,'IT_PROG',
NULL,NULL,NULL,SELF.n_dept);
COMMIT;
END ajoute_emp;
END;
BEGIN
Employe ajoute
SELECT VALUE(d) INTO obj
Effectif pour 20 = 3
FROM v_obj_dept_emps d
WHERE d.n_dept = 20;
obj.ajoute_emp(99,'Fred','Brouard',SYSDATE);
DBMS_OUTPUT.PUT_LINE('Employe ajoute');
DBMS_OUTPUT.PUT_LINE('Effectif pour ' ||
obj.n_dept || ' = ' || obj.nbre_emp());
END;
Une fois les mises à jour opérées, les nouvelles données sont visibles dans les tables sources
ou par l’intermédiaire de la vue.
Une méthode peut implémenter une transaction, car tous les mécanismes du langage procé-
dural du SGBD sont disponibles (validation, invalidation, points de sauvegarde, curseurs et
exceptions).
L’option de contrôle (WITH CHECK option) d’une vue n’est pas vérifiée si un déclencheur
INSTEAD OF est programmé sur l’événement en question (ajout, modification ou suppres-
sion). Le corps du déclencheur doit donc explicitement prendre en compte la contrainte.
À l’instar des déclencheurs traditionnels, il n’est permis de programmer qu’un seul déclen-
cheur INSTEAD OF par table.
Considérons les vues relationnelles créées dans le premier paragraphe et qu’il n’était pas pos-
sible de mettre à jour.
Shipping Fripp 45
3618.4
Permettons à cette vue des insertions et modifications (il s’agit de mettre à jour la table
departments). En modification, seuls le nom du département et celui du manager pour-
ront être modifiés. Le déclencheur INSTEAD OF devra se charger de rechercher le code du
manager.
Le scénario suivant illustre deux modifications de la vue qui conduisent à mettre à jour la table
(la vue aussi par conséquent).
Le scénario suivant décrit une insertion dans la vue qui met à jour la table. Les nouvelles
données n’apparaissent pas dans initialement la vue, car le département est pour l’instant non
pourvu d’employés.
SQL> INSERT INTO v_dept_calculs Le nouveau département Eyrolles Prod. est dirigé par l’employé
(departement,manager) Austin (numéro 105).
VALUES ('Eyrolles Prod.',
'Austin');
1 row created.
Pour modifier cette vue en insertion, le déclencheur INSTEAD OF doit insérer des informa-
tions simultanément dans les tables sources employees et departments. Si le département
existe déjà, il ne faut pas le recréer. Le salaire de l’employé doit être estimé puisqu’il n’est pas
présent dans la vue (on prend le salaire moyen pour le type d’emploi concerné).
Le scénario suivant décrit deux insertions dans la vue et la vérification des données dans les
tables au final.
SQL> INSERT INTO v_dept_emps Ajout d’un nouveau département et d’un nouvel
(ndept, departement, id_emp, prenom, nom, employé.
DEPARTMENT_ID DEPARTMENT_NAME
-------------- ------------------------------
99 Eyrolles Design.
Avec Oracle, un déclencheur INSTEAD OF peut être programmé au niveau d’une collection
NESTED TABLE d’une vue objet. Ce type de déclencheur :
●● s’exécute seulement si un élément de la collection NESTED TABLE est modifié par l’ins-
truction TABLE(…) ;
●● ne s’exécute pas pour une mise à jour globale de la collection NESTED TABLE (dans son
Dans le corps du déclencheur, il est possible d’avoir accès aux valeurs des données de la col-
lection mise à jour, mais aussi de l’enregistrement qui contient la collection (parent row). Des
directives permettent de répercuter dans la table les modifications réalisées au niveau de la
collection :
●● ON NESTED TABLE désigne la collection surveillée (ici, emps_nt) ;
Tableau 4-34 : Déclencheur INSTEAD OF pour l’insertion dans une collection d’une vue
Le scénario suivant décrit une insertion dans la collection de la vue et vérifie la présence des
données dans la table source et dans la vue objet.
Il est intéressant d’analyser l’évolution de ces offres cinq ans après. Enterprise Architect n’offre
plus la possibilité de traduire un diagramme de classes, Visual UML a été inclus dans Visual
Paradigm. Peu de nouveaux outils sont apparus et ceux qui sont gratuits ne sont ni fiables, ni
performants. Ma sélection s’est portée sur les outils suivants :
●● MagicDraw UML : http://www.magicdraw.com/
MagicDraw
La version Architect ou Enterprise de MagicDraw présente sur le site Web des fonctionnalités
relatives à la génération de code SQL. La version d’évaluation est plus que restrictive (procé-
dure d’enregistrement et multiples vérifications) : nombre d’objets limités, fichiers en lecture
seule, le tout pour 27 jours ! Au secours !
Le clou de l’essai : l’impossibilité de définir un identifiant de classe. En cinq ans : zéro progrès.
Fermez le ban !
MEGA
L’offre logicielle de la société MEGA regroupe quatre catégories d’outils pour la modélisation,
le contrôle, les transformations et les outils de communication. L’outil de modélisation est ici
brièvement présenté.
Pour débuter, créez un projet, un paquetage et reliez le paquetage à la base de données. Cette
commande n’est pas active par défaut et nécessite une action manuelle (menu Tools>Options,
dossier Compatibility>Others, cochez l’option Data Package dans la partie droite de la
fenêtre).
Identifiants
Un clic droit sur la classe choix Attributes vous permettra de créer des attributs. Sélectionnez
ensuite l’identifiant. Pour le typage, sélectionnez chaque attribut par un clic droit dans l’ex-
plorateur, choix Properties, onglet Characteristics et trouvez le type adéquat dans la liste
Expression Type.
Associations
Pour créer une classe-association, créez la classe du milieu et, à l’aide du bouton Link, reliez
cette classe à l’association.
Un assistant en quatre étapes est alors lancé. Le modèle relationnel est, par la suite, créé dans
le paquetage.
Rétroconception
Créez une base vide de tout diagramme, et renseignez le type du SGBD (Properties), d’un clic
droit Reverse Target Database. Vous avez le choix entre sélectionner une source de données
ODBC préalablement définie ou un script SQL. Pour ce dernier cas, MEGA fournit un outil
qui se connecte à une base par ODBC et génère automatiquement un fichier XML décrivant
les tables et clés.
Afin de générer un modèle conceptuel, vérifiez que vous avez accès au Meta Model en mode
Avanced, dans le menu Tools>Options. Un assistant en quatre étapes se lance et produit un
nouveau modèle de données (Data Model). Dans ce modèle, créez un diagramme de données
(clic droit New>Data Diagram) puis insérez dans ce diagramme par un glisser-déposer les
entités que vous avez obtenues après rétro-ingénierie.
Les schémas obtenus par rétroconception sont de très bonne qualité. Dans l’exemple, seules les
agrégations devraient être notées en tant que compositions. Les points forts de cet outil sont
la robustesse, l’ergonomie de l’outil de synchronisation par étapes et les passerelles possibles
avec d’autres outils.
Modelio
Modelio est distribué par Modeliosoft, filiale de Softeam, société française. Ce produit est
basé sur l’architecture d’Objecteering (présenté plus loin) et présente une interface au look
Eclipse.
Avant tout, installez les modules Persistent Profile et SQL Designer (MDA>Installer un
module…) avant de créer un projet puis, à l’intérieur de celui-ci, un diagramme de classes.
Chaque classe, attribut et association doivent être déclarés persistants (cochez Element Persis-
tant dans la fenêtre en bas à droite dans l’onglet Persistent).
Identifiants
Pour créer des attributs et un identifiant dans une classe, rendez-vous dans la fenêtre Modèle,
d’un clic droit sur la classe et Profil de persistance, choisissez Property ou Identifier puis typez
la colonne dans la fenêtre en annotant l’élément dans l’onglet Element.
Associations
Chaque type d’association (classe-association, composition, etc.) dispose de son icône. L’anno-
tation d’une association vous permet de fixer les multiplicités.
La génération du script SQL s’opère par un clic droit sur le diagramme SQL, puis SQL
Designer>Générateur : Script SQL.
Pour effectuer une rétroconception à partir d’un script SQL, positionnez-vous au niveau du
projet, puis clic droit SQL Designer>Reverse : Script SQL. Vous devrez ensuite choisir le type
du script (SQL92, Oracle, MySQL ou SQL Server) et localiser le fichier contenant la création
des tables et contraintes. Pour remonter dans les niveaux, positionnez-vous sur le diagramme
SQL obtenu (qui est de bonne qualité), puis clic droit SQL Designer>Transformation : Modèle
de tables vers modèle de données. La suite des opérations est bien plus hasardeuse lorsque
vous désirez générer le modèle UML.
La simplicité des menus et l’ergonomie de cet outil sont appréciables de même qu’un forum
réactif. En revanche, il manque un peu de fluidité dans la manipulation graphique des schémas.
L’existence d’un modèle de données intermédiaire et la volonté d’intégrer Hibernate dans le
même contexte entravent, à mon sens, la qualité de génération entre des modèles UML et
SQL et inversement. Un autre point faible concerne l’incapacité à traiter automatiquement les
classes-associations.
Objecteering
Objecteering est un autre produit français de la société Softeam qui est un acteur majeur dans
la communauté des technologies objet et premier membre européen de l’OMG.
Dans cet outil, le terme physical model désigne un schéma relationnel (niveau logique) et
logical model désigne un script SQL.
Avant tout, créez un projet puis configurez l’affichage des tags qui serviront à annoter un
diagramme de classes pour sa transformation (Outils>Options graphiques… Diagramme de
classes, rendez visible les tagged values). Ensuite, déployez le module SQL (Outils>Deployer
un MDAC… choisissez generator>SQLDesigner). Concernant ce module (Outils>Options
MDAC…), configurez l’accès à votre base. Dans l’option Génération de diagramme sur le
modèle physique, cochez la case correspondante.
Vous pouvez créer un paquetage (dans la racine) qui contiendra votre diagramme de classes.
La transformation de modèle nécessite que vous enrichissiez au préalable le diagramme de
classes UML de tagged values. Ainsi, vous devez annoter chaque classe du tag persistence
en adjoignant la propriété persistent.
Identifiants
Pour ajouter des attributs à une classe, cliquez sur l’icône de l’attribut, puis cliquez à
nouveau dans sa classe. Les identifiants sont choisis via un clic droit sur la classe puis
MDA Components>SQL Designer>Primary key… Pendant la saisie du diagramme de
classes, servez-vous plutôt de la fenêtre de gauche (Explorer) pour supprimer les éléments
superflus.
Associations
En double-cliquant sur un lien d’association, vous obtenez une fenêtre avec différents onglets,
vous pouvez nommer l’association, les rôles, les multiplicités, etc. Décochez la case Est navi-
gable qui ne sert à rien.
Pour trouver les liens de classes-associations et de composition, laissez le curseur sur le bas de
l’icône Association (au niveau du tout petit triangle noir).
Un grand nombre de points forts sont à noter : rigueur de la démarche et ergonomie à la fois
sobre et puissante, documentation détaillée du module SQL Designer (principes de transfor-
mations), réactivité et efficacité du support ainsi que l’existence d’un forum dédié. Les points
faibles concernent le nombre réduit de SGBD pris en compte et surtout l’absence de processus
de rétroconception.
PowerAMC
PowerAMC (anciennement AMC*Designor)est la version française de l’outil de modélisation
PowerDesigner de Sybase. Depuis la version 8, la notation UML (appelée MOO : Modèle
Orienté Objet) coexiste avec les notations Merise, entité-relation et IDEF1X.
Débutez avec un nouveau diagramme de classes (Fichier>Nouveau>Modèle Orienté Objet),
en choisissant comme langage objet Analyse. La palette graphique apparaît. Pour visualiser
le nom des associations : clic droit sur le fond puis Préférences d’affichage>Association, et
cochez la case Nom.
Identifiants
Pour chaque classe, vous devez définir un identifiant primaire. Le nom de l’identifiant importe
peu, vous n’avez pas à le modifier. Sélectionnez l’attribut (ou les attributs), cliquez sur la clé et
suivez le guide…
Si l’attribut n’apparaît pas souligné après avoir validé cette étape, retaillez un peu la classe à
la souris, ça devrait fonctionner. Si vous désirez ajouter d’autres identifiants (alternatifs), le
principe est le même, mais vous décocherez la dernière case.
Associations
En double-cliquant sur un lien d’association, vous obtenez plusieurs fenêtres pour inscrire le
nom de l’association, les rôles, les multiplicités et la composition. Décochez la case Navigable
qui ne sert à rien.
Pour créer une classe-association, il suffit de rattacher une classe à une association existante
par un nouveau lien d’association et le tour est joué.
Héritage
La palette contient un symbole relatif aux liens d’héritage ; reliez ensuite la sous-classe à sa
surclasse.
En double-cliquant sur un lien d’héritage, vous obtenez une fenêtre qui permet de choisir la
traduction de l’héritage (distinction : par défaut, push-down : ne pas générer la classe parent,
push-up : ne pas générer la classe enfant).
Le résultat s’affiche en tant que nouveau schéma relationnel, la fenêtre de gauche contient tous
les détails de la composition des tables. À ce niveau, vous pourrez renommer des colonnes et
clés étrangères, mais surtout typer au mieux chaque colonne.
Rétroconception
Le choix Fichier/Reverse Engineering/Base de données… permet de construire un schéma
relationnel à partir d’un script SQL ou par une connexion au SGBD pour extraire des tables
d’un schéma. Des boîtes de dialogue donnent accès à un certain nombre d’options, notamment
le type du SGBD source, les tables à traduire après connexion au SGBD, le nom du script
SQL, etc.
Rational Rose
La société Rational Software, qui a été à l’origine de la standardisation d’UML, est propriété
d’IBM depuis 2003. L’outil de conception qui est au catalogue d’IBM s’appelle toujours
Rational Rose Data Modeler. Cet outil est basé sur le formalisme UML et inclut un profil
convenant aux bases de données. Un profil est une proposition d’une communauté et regroupe
un ensemble d’éléments UML (composants, stéréotypes, icônes, propriétés…) qui s’appliquent
à un contexte particulier et qui conservent le métamodèle d’UML intact. Quand un tel profil
est valide au niveau de la notation, il est dit « bien formé ». Ce profil n’a pas été adopté par les
autres éditeurs de logiciels.
Identifiants
Pour identifier une classe, vous devez marquer l’attribut en tant que Part of Object Iden-
tity. Pour un identifiant composé, il faut répéter ce choix sur chaque attribut. Si aucun attribut
ne vous convient, vous pouvez laisser l’outil ajouter un attribut de type ID-based column. Pour
le SGBD Oracle, le type de cette colonne est NUMBER(10).
Après la transformation, vous devez créer un diagramme pour visualiser le modèle logique
(clic droit sur le schéma puis Data Modeler>New>Data Model Diagram). Vous pouvez
modifier certaines caractéristiques avant de générer le script SQL (noms des contraintes et
colonnes, etc.).
Rétroconception
Vous devrez au préalable créer un paquetage vide. Le processus de rétroconception démarre
du schéma (compartiment Logical View/Schemas) à sélectionner par un clic droit (Data
Modeler>Transform to Object Model). L’assistant permet de sélectionner le nom du paque-
tage en sortie ainsi que d’autres options. Le fait de transformer un modèle de données dans
un paquetage modifie les nouveaux éléments du paquetage, mais ne détruit ni ne modifie les
éléments mis à jour au niveau du modèle de données.
Cet outil n’a pas évolué depuis la première version de cet ouvrage, ce qui prouve sa très grande
robustesse. On peut toutefois regretter qu’il n’inclue pas de pilotes pour les SGBD open source.
Visual Paradigm
L’édition Enterprise de Visual Paradigm déclare des fonctionnalités relatives à SQL.
J’ai donc téléchargé la version d’évaluation qui permet l’enregistrement de diagrammes
pendant dix jours. Une fois le diagramme de classes UML saisi, vous constaterez qu’il n’est
pas possible de générer du code SQL directement. La version évaluée en 2007 ne comportait
pas ni d’identifiant de classes, ni d’associations n-aires. Cette version supporte maintenant
les associations n-aires sans inclure les identifiants de classes. Pile ce qu’il ne fallait pas
faire.
Ce qu’il est possible de faire pour l’heure, c’est générer un diagramme de classe à partir d’un
modèle de type entité-relation. Très pratique… Au suivant !
Win’Design
Win’Design est le produit de la société Cecima basée à Aix-en-Provence. Il est présent sur le
marché français depuis 1995. Développé initialement pour Merise/2, la notation UML arrive
en 2002 avec la version 5. Depuis, l’outil est en évolution constante. En 2011, la version 11 est
disponible.
La gamme comprend trois modules autonomes et complémentaires, qui s’articulent autour d’un
référentiel (Database pour la conception et le reverse des bases de données, Business Process
pour la modélisation des processus métier et Object pour la modélisation UML). Vous devrez
disposer du premier et du troisième module pour traduire des diagrammes de classes en script
SQL. Win’Design est un outil facile à prendre en main et son interface est très intuitive. Le seul
problème de ce produit est qu’il présente encore des lacunes de traduction d’un diagramme UML
vers le modèle logique. Lacunes qui sont absentes si vous utilisez la notation Merise.
Pour débuter avec un nouveau diagramme de classes : Fichier>Nouveau>Module Objet. Cli-
quez sur le diagramme de classes et choisissez le langage cible Analyse. Un modèle vierge
d’attributs, mais contenant tous les types d’associations apparaît, ainsi qu’une palette graphique.
Identifiants
Pour chaque classe, le bouton Details… permet de saisir les attributs et leurs types. L’identi-
fiant est à cocher dans la case associée.
Associations
La fenêtre de gauche contient tous les détails du diagramme de classes. La palette permet de
créer tout type de classe, d’association, de classe-association et de lien d’héritage.
Pour visualiser le nom des associations, cliquez sur le lien, dans l’onglet Affichage, cochez
Nom. Il est possible de créer des associations n-aires, mais il n’est pas possible de relier une
classe-association à une autre classe par une association simple. Cette fonctionnalité n’est
possible qu’au niveau de Merise en utilisant un lien identifiant. Ce qui constitue pour moi le
principal inconvénient de cet outil.
Héritage
Il n’est pas possible de choisir la traduction de l’héritage (distinction, push-down ou push-up).
Par défaut, la méthode push-down est adoptée. Ce choix de décomposition n’est possible qu’au
niveau de Merise.
Le résultat s’affiche en tant que nouveau modèle logique, le référentiel s’enrichit des détails
des tables (clés et index). À ce niveau, vous pourrez renommer des tables, des colonnes ou des
clés étrangères.
Rétroconception
Le choix Fichier>Reverse Engineering>Base de données… permet de construire un modèle
logique à partir d’un script SQL ou par une connexion au SGBD pour extraire des tables d’un
schéma. Des boîtes de dialogue donnent accès à un certain nombre d’options, notamment au
répertoire qui contient le script SQL, aux tables à traduire, etc.
Conclusion
L’évolution d’UML, d’un point de vue normatif, vers les bases de données, ne se concrétise
toujours pas, car la RFP (Request For Proposal) nommée Information Management Meta-
model proposée par l’OMG en 2006 est toujours au point mort. Cette spécification visait à
définir un métamodèle incluant différentes sous-parties : Common Warehouse Metamodel,
UML2 Profile for Relational Data Modeling, UML2 Profile for Logical (Entity Relationship)
Data Modeling, UML2 Profile for XML Data Modeling et UML2 Profile for Record Modeling
COBOL. Cette absence de normalisation n’empêche personne d’utiliser UML pour concevoir
une base de données relationnelle, la preuve, bon nombre d’outils ont implémenté les princi-
paux mécanismes.
En fonction des tests réalisés, des manipulations relatives à l’installation, à la recherche de
documentations, etc. voici le classement qui n’engage que moi bien sûr. Sachez aussi qu’il
existe des forums sur http://www.developpez.net, relatifs à Rational Rose et PowerAMC.
Associations binaires
Les associations binaires les plus conformes aux 6 classes du schéma sont les suivantes.
●● Il est préférable d’utiliser deux associations pour modéliser une rencontre entre 2 équipes
qu’une seule association plusieurs-à-plusieurs.
●● Il est préférable de relier Stade à Ville plutôt que Match à Ville. Cette information est
déduite sans ambiguité par le parcours des associations derouler et lieu.
Classe-association
La classe-association Equipe_Langue permet l’affichage d’une même équipe dans diffé-
rentes langues. Le libellé de l’équipe dépend simultanément du code équipe et du code langue.
Historique
La classe Historique permet d’identifier (d’une manière relative) une équipe et un groupe
par rapport à l’année. Ainsi, l’équipe numéro 34 couplée à l’année 2006 se différencie de la
même équipe (34) en 2010. Il en va de même pour les groupes (A-2006 est différent de A-2010).
Les autres classes reliées à Equipe et Groupe (ici, seulement Match) n’ont pas à subir le
même traitement si elles ne nécessitent pas d’être identifiées d’une manière relative par rap-
port à l’année de la compétition. C’est le cas pour une rencontre dont le numéro n’a pas de
sémantique temporelle et qui est reliée de manière non ambiguë aux deux équipes qui seront
estampillées de l’année de l’événement.
Bien que les associations sites et utiliser ne soient pas minimales (on peut les déduire
à partir de tous les matchs d’une année donnée), elles permettent, d’une part, d’éviter de par-
courir les matchs pour connaître les villes et les stades prévus pour chaque événement. D’autre
part, dans des conditions initiales (aucun match n’est encore joué ou prévu), elles deviennent
indispensables pour définir dans quelles villes et dans quels stades les rencontres auront lieu.
Une fois définies, elles permettent également de vérifier la cohérence du lieu d’un match réa-
lisé.
Inscriptions
Il est préférable de définir une classe pour héberger l’attribut codent qui est un identifiant
potentiel. Le créneau de disponibilité (jsem et hrens) dépend du consultant responsable de
la formation.
Plannings
●● Le créneau de disponibilité (jsem et hrens) dépend désormais de la formation et plus
seulement du consultant responsable.
●● Plusieurs créneaux de disponibilité (jsem et hrens) peuvent être associés à une formation
(et, donc, à son responsable) et un même créneau peut concerner différentes formations.
En conséquence, ces deux attributs ne peuvent se trouver ni dans la classe Formation, ni
dans la classe Employe.
La création de la classe Creneau permet d’héberger ces attributs. Aucun de ces deux attributs
pris isolément ne peut devenir identifiant. En revanche, le couple (jsem , hrens) identifie un
créneau unique et permet de caractériser cette classe sans recourir à l’identification artificielle.
Attention, ne déclarez pas l’association planning entre Employe et Creneau, car vous ne
pourriez pas connaître la formation renseignée pour un créneau et un formateur donnés (erreur
de l’« abîme »).
●● L’historique des visites peut se modéliser à l’aide de la classe Visite identifiée par le
couple (représentant, jour) associé à plusieurs dépôts (en supposant qu’un représentant
puisse réaliser différents déplacements le même jour).
●● En identifiant artificiellement la classe Visite, les associations autour de cette classe sont
simplifiées. En revanche, les éventuelles contraintes de planning d’un représentant (liste
des jours de travail, par exemple) seront plus difficiles à mettre en œuvre.
Stages
Le couple prépondérant est (Stage, Ville), car il est souhaitable de contraindre en premier les
lieux d’un stage donné. Ce couple est ensuite associé à plusieurs périodes. Cette modélisation
n’est valable que pour une année en cours.
Cote automobile
En ajoutant l’année au modèle, on identifie une cote brute. Les autres caractéristiques d’un
véhicule sont associées au modèle.
Identification relative
La classe Calendrier modélise les dates de rendez-vous de chaque conseiller. En asso-
ciant cette classe aux clients, on obtient l’historique de chaque client. La date du dernier
rendez-vous d’un client est modélisée par un attribut de classe (pouvant toutefois être
déduit). Les produits financiers souscrits sont modélisés par une association plusieurs-
à-plusieurs.
Identification artificielle
Sans utiliser une classe Virement (dotée d’un identifiant artificiel), il est difficile d’identifier
un virement. Distinguez les actions de crédit et de débit d’un compte. Le client initiateur du
virement est modélisé par une association.
Exercice 1.6 – Le RIB
Chaque compte est identifié au niveau national par les numéros de banque, d’agence et de
compte. La composition permet de faire migrer les identifiants de classe en classe.
Sessions
La classe Session permet de connecter Formation (nature du cours), Employe (identité du
formateur) et Stagiaire (liste des participants). La note dépend du stagiaire et du cours suivi.
Salles
Le mémo du technicien dépend aussi de la session. Le temps de présence de chaque technicien
dépend du jour et de la session.
Exercice 1.8 – L’héritage
Organisme de formation
L’héritage permet de classifier chaque employé (consultant, formateur ou technicien). La
contrainte {incomplete,overlapping} signifie qu’un consultant peut être formateur, et
réciproquement.
Comptes bancaires
L’héritage suivant permet de spécialiser un client en un éventuel mandataire. Le fait qu’un
mandataire d’un compte ne soit pas le propriétaire dudit compte n’apparaît pas ici ; une
contrainte doit être ajoutée.
Ancien régime
En dissociant le certificat du véhicule, il est aisé de modéliser l’historique des immatricu-
lations successives. Certains attributs de la classe Vehicule semblent être des identifiants
potentiels d’autres classes (genre, type du véhicule, carrosserie et énergie). Il serait intéressant
de définir ces classes et d’y associer des libellés.
Coût du cheval
La taxe fiscale dépend de la région et du nombre de chevaux. La composition permet d’identi-
fier (d’une manière relative) une taxe par rapport à une région.
Nouvelle numérotation
Le nouveau système de numérotation rend le numéro d’immatriculation de tout véhicule
invariable (attribut de la classe Vehicule). L’association fetiche permet de distinguer le
département qui facture (association prefecture) le certificat de celui qui est choisi pour être
accolé à la plaque d’immatriculation.
Contrôles techniques
Chaque contrôle technique est rattaché à un certificat d’immatriculation et se déroule dans
un centre de contrôle (qui dépend d’une enseigne). La classe artificielle Visite_Technique
permet de modéliser facilement l’historique des visites d’un véhicule.
Organisme de formation
●● Un consultant doit proposer entre 2 et 4 créneaux par semaine pour enseigner un cours.
En considérant le rôle quand (sur l’association planning du côté de la classe Creneau) :
context Formation inv plusieurs_creneaux :
Formation.allInstances()−>forAll(f |
f.quand.size() >= 2 and f.quand.size() <4)
●● Un technicien doit rédiger un mémo de ces actions pour toute formation qu’il a en charge.
context Compte-Rendu inv memo_non_nul : self.memo <> null
●● Le nombre de stagiaires ne doit pas dépasser la capacité d’une salle pour toute session.
En considérant les rôles stagiaires (sur l’association participer du côté de la classe
Stagiaire) et local (sur l’association lieu du côté de la classe Salle) :
context Session inv nb_stagiaires :
Session.allInstances()−>forAll(s |
s.stagiaires.size() <= s.local.capacite)
Comptes bancaires
●● Un mandataire d’un compte n’est pas le propriétaire.
En considérant les rôles proprio (sur l’association proprietaire du côté de la classe
Client) et madates (sur l’association comptes_geres du côté de la classe Mandataire) :
context Compte inv mandataire_proprio :
Compte.allInstances()−>forAll(c | c
c.self.proprio.excludesAll(c.mandates))
Exercice 1.13 – La thalasso
La particularité de ce schéma est le positionnement de l’heure (entre le soin et le planning)
pour autoriser qu’un soin puisse être réalisé à différents moments.
Titre suprême
Cette solution distingue le premier du second tour par l’existence de deux associations dis-
tinctes. Les DOM-TOM peuvent être considérés en tant que département.
Exercice 2.5 – La normalisation
Une clé possible de la relation initiale est le couple (tournoi, annee). Dans ce cas, la relation
est en première forme normale, mais ne respecte pas la troisième forme normale car la date de
naissance dépend directement du joueur.
Le fait de déterminer cette dépendance directe permet de déduire la relation Joueurs. Par
ailleurs, le nom du tournoi doit être considéré comme un libellé et donc être identifié d’une
manière particulière. Il est donc nécessaire de créer la relation Tournois qui doit être asso-
ciée à la relation Joueurs par une association plusieurs-à-plusieurs. La relation Gagnants
joue ce rôle.
Script SQL
Le tableau suivant présente le script de création des clés étrangères et de destruction des tables,
index et contraintes.
Script SQL
Le tableau suivant présente le script de création des clés étrangères et de destruction des tables, index et
contraintes.
Carte d’embarquement
Le tableau suivant présente les contraintes à programmer pour implémenter les différentes
règles métier.
Tableau A-5 : Programmation des règles métier (carte d’embarquement)
Exercice 3.4 – La dénormalisation
Carte d’embarquement
Le nombre de vols déjà effectués par tout passager est implémenté par un compteur dans la
table des passagers. Les données additionnelles à prendre en compte (prix de chaque vol, noms
de la compagnie et des aéroports, ainsi que l’indicateur de places disponibles) sont à disposer
dans la table des vols réels. Seules les tables qui sont impactées sont présentées dans la figure
suivante.
●● Aucun contrôle possible de la cohérence de la composition des stations sur une ligne de bus
horaires d’un jour sur une station donnée et pour toutes les lignes).
Rendez-vous
●● La classe Rendez_vous modélise le « Qui est venu la voir et à quelle heure ».
●● La classe Population recense la classification enfant, ado, femme, homme ou couple.
Chaque patient est associé à une classification à un instant donné, mais peut consulter dans
différents contextes au cours de sa vie.
●● La classe Connaissance recense les différents moyens de connaissance (bouche à oreille,
autre patient, docteur, etc.).
●● Le retard du patient dépend de ses rendez-vous.
●● Le nombre maximum de 3 personnes durant la consultation apparaît dans l’association
entre un patient et son rendez-vous.
●● Le mode de réglement de la séance dépend de chaque rendez-vous.
●● L’anxiété est éventuellement notée pour un rendez-vous et un patient donnés.
●● La profession et la liste des prénoms des personnes familières au patient se traduisent par
de simples associations binaires.
●● Les mots-clés, postures affichées et comportements qui sont observés dépendent de chaque
rendez-vous.
Confrères et livres
●● Les confrères et professions donnent lieu à la création de classes associées.
●● Les rendez-vous avec ses confrères et les consultations externes de ses patients utilisent la
même classe : Rendez_vous.
●● Les circonstances de la première rencontre avec chacun des spécialistes donnent lieu à la
création d’une classe.
●● Le prêt de livres est modélisé avec la classe-association Retour qui ne permet pas de gérer
un historique par ailleurs.
Flotte
Il est nécessaire de distinguer les aéronefs en tant qu’objets concrets (l’aéronef réel) et qu’objets
abstraits (type d’avion). La puissance et le prix horaire caractérisent l’objet abstrait. L’immatri-
culation identifie un objet réel qui est caractérisé par un nombre d’heures de vol de la cellule
et du moteur.
Une visite de maintenance peut être identifiée par une date et l’immatriculation de l’appa-
reil visité. Chaque visite concerne un plan de maintenance (nombre d’heures d’utilisation) et
nécessite la commande de plusieurs pièces qui sont achetées à un prix qui peut évoluer dans
le temps.
Acteurs
L’héritage permet de distinguer un élève pilote d’un instructeur. Le prix dépend du type
d’avion utilisé. Chaque séance de vol concerne un élève pilote, un avion et, éventuellement, un
instructeur. Chaque visite médicale est identifiée par la date et le numéro du membre.
Rendez-vous
La classe créneau désigne d’une manière générique soit une réservation concernant un avion,
un élève et, éventuellement, un instructeur, soit un intervalle d’indisponibilités qui ne concerne
qu’un avion.
Ressources
Webographie
Bibliographie
[AUD 09] L. Audibert, UML 2 : de l’apprentissage à la pratique, Ellipses Marketing, 2009.
[ADI 93] M. Adiba, C. Collet, Objets et Bases de données, le SGBD O2, Hermès, 1993.
[ATK 89] M. Atkinson, F. Bancilhon, D. de Witt, K. Dittrich, D. Maier, S. Zdonik,
« The Object-Oriented database manifesto », Proceedings of the Conference Deductive and
Object-Oriented DataBases, 1989.
[BOU 99] N. Boudjilda, Bases de données et systèmes d’informations, le modèle relationnel :
langages, systèmes et méthodes, Dunod, 1999.
[BRO 10] F. Brouard, R. Bruchez, C. Soutou, SQL, 3e édition, Pearson Education, 2010.
[CHE 76] P. P. Chen, « The Entity-Relationship Model: Towards a Unified View of Data »,
ACM Transactions on Database Systems, Vol. 1, N° 1, 1976.
[COD 70] E. F. Codd, « A Relational Model for Large Shared Data Banks », Communications
of the ACM, Vol 13, N° 6, 1970.
[COD 72] E. F. Codd, « Further Normalization of the Data Base Relational Model », Data
Base Systems, Courant Computer Science Symposia Series 6, Prentice Hall, 1972.
[DEL 91] C. Delobel, C. Lécluse, P. Richard, Bases de données : des systèmes relationnels
aux systèmes à objets, InterEditions, 1991.
[DEL 00] P. Delmal, SQL2-SQL3, Applications à Oracle, De Boeck Université, 2000.
[FAG 81] R. Fagin, « A Normal Form for Relational Databases That Is Based on Domains and
Keys », ACM Transactions on Database Systems, Vol 6, N° 3, 1981.
[MAK 08] G. Maksay, Y. Pigneur, Modéliser par l’exemple, Presses polytechniques et uni-
versitaires romandes, 2008.
[MAR 94] C. Maree, G. Ledant, SQL 2 Initiation Programmation, Armand Colin, 1994.
[MOU 76] P. Moulin, J. Randon, S. Savoysky, S. Spaccapietra , H. Tardieu , M. Teboul,
« Conceptual model as database design tool », Proceedings of the IFIP Working conference
on Modelling in Database Management Systems , G.M. Nijssen Ed., North-Holland, 1976.
[MUL 99] R. J. Muller, Database Design for Smarties, Using UML for Data Modeling,
Morgan-Kaufman, 1999.
[MUL 00] P. A. Muller, N. Gaertner, Modélisation objet avec UML, Eyrolles, 2e édition,
2000.
[NAN 01] D. Nanci, B. Espinasse, B. Cohen, Ingénierie des systèmes d’information : Merise
deuxième génération, Vuibert, 4e édition, 2001.
[SOU 08] C. Soutou, Programmer Objet avec Oracle, 2e édition, Vuibert, 2008.
[TAR 79] H. Tardieu, D. Nanci, D. Pascot, « A Method, A Formalism and Tools for Database
Design (three years of Experimental Practice) », Proceedings of the International Conference
on Entity-Relationship Approach to Systems Analysis and Design, 1979.
[VAL 87] P. Valduriez, « Objets complexes dans les systèmes de bases de données relation-
nels », Techniques et science informatique, Vol. 6, N° 5, 1987.
[WAR 03] J.Warmer, A. Kleppe, « The Object Constraint Language: Getting Your Models
Ready for MDA », Addison-Wesley, 2003.
A un-à-un 28
modèle relationnel 118, 119
abîme 69
SQL 158
agrégat 52
attribut 20
agrégation 51
atomique 66
composition 52
modèle relationnel 120 calculé 68
partagée 52 modèle relationnel 112
allInstances 80 monovalué 84
ALTER TABLE 155 multivalué 83
temporel 60
AMC*Designor 257
association 20
agrégation 51 B
binaire 28
bag 76
dérivée 72
héritage 58 base de données
n-aire 41 hiérarchique 2
navigable 72 relationnelle 4
plusieurs-à-plusieurs 29 réseau 4
modèle relationnel 117 BCNF 88
SQL 161 BUILD IMMEDIATE 223
qualifiée 72
réflexive 34
SQL 159
C
un-à-plusieurs 29 cardinalité 30
modèle relationnel 117 cast 229
SQL 157 CHECK 155
Chen 18 E
chronologie 61
ENABLE QUERY REWRITE 223
classe 20, 22
entité 20
classe-association 37 exclusivité 79
modèle relationnel 121
réflexive 40
F
clé étrangère 112
FOREIGN KEY 155
clé primaire 112
forme normale
COBOL 2
Boyce-Codd 88, 139
Codd 18, 112
cinquième 89, 142
collection 227 deuxième 84, 136
composition 52 domaine-clé 89, 141
SQL 161 première 83, 133
contraintes quatrième 89, 142
OCL 76 troisième 86, 138
SQL 154
CREATE TABLE 155 H
héritage 58
D distinction 121
modèle relationnel 121
database 152
push-down 121
déclencheur 166 push-up 121
dénormalisation 180, 218 SQL 165
dépendance historisation 62
directe 87, 133
élémentaire 85, 132 I
fonctionnelle 81
identifiant 23
modèle relationnel 131
alternatif 28
multivaluée 142
artificiel 26
dépendant 131 naturel 25
déterminant 131 identification artificielle 56
disjoint 79 incomplete 79
DKNF 89 intégrité référentielle 214
isEmpty 76 O
isUnique 80
Objecteering 253
OCL 76
K oclIsKindOf 80
key preserved 205 OID 227
OLAP 5
OLTP 5
L
ON NESTED TABLE 240
libellé 23 ordered 76
overlapping 79
M
MagicDraw 244 P
materialized view 221 PARENT 240
materialized view log 224 partition 79
MCD 19 PowerAMC 16, 257
MEGA 245 PowerDesigner 257
Merise/2 19 PRIMARY KEY 155
méthode 231 privilège 208
modèle entité-association 18 proposition incomplète 64
modèle relationnel 112 propriété 20
Modelio 249
Morejon 53
R
multiplicité 30
rafraîchissement 222
multiset 229
RAISE_APPLICATION_ERROR 167
Rational Rose 114, 262
N redefined 76
nested table 228 REFERENCING 240
NIAM 19 réification 54
NO_DATA_FOUND 167 relation 112
normalisation 129 Rochfeld 53
NOT NULL 117, 156 rôle 36
S UNIQUE 155
UPPER 206
schéma 152
user 152
schéma conceptuel 11
SELF 231
sequence 76 V
seq 76
varray 228
snapshot 221
ventilateur 68
SQL 151
Visual Paradigm 265
SQL2 151
volumétrie 144
SQL3 151
vue
subsets 75
complexe 198
SQL 174
matérialisée 221
substantification 54
modifiable 203
monotable 200
T multitable 202
table objet 226
d’association 117 simple 198
de jointure 117
key preserved 205
W
Tardieu 18
totalité 79 Win’Design 53, 266
transitivité 70 WITH CHECK OPTION 198, 204, 233
type 228 WITH OBJECT IDENTIFIER 227
WITH READ ONLY 198
U
UML 5
X
profil 262 xor 75
union 76 SQL 176