Académique Documents
Professionnel Documents
Culture Documents
net/publication/366569633
CITATIONS READS
0 400
1 author:
Joachim Tankoano
University of Ouagadougou
14 PUBLICATIONS 39 CITATIONS
SEE PROFILE
All content following this page was uploaded by Joachim Tankoano on 24 December 2022.
2ème Édition
Copyright © Joachim TANKOANO, 2021
Cet ouvrage en deux tomes est le fruit du travail de cette période de dix
années, au cours desquelles Joachim TANKOANO a dispensé un cours de
bases de données à l’Institut Burkinabè des Arts et Métiers (IBAM) de
l’Université Joseph Ki-Zerbo (ex Université de Ouagadougou), imaginé des
exemples et des exercices pratiques et constamment amélioré son contenu,
pour aboutir à cet ouvrage considérable de qualité, de complétude et de
rigueur : chacun des nombreux exemples proposés a été mis en œuvre sur
machine et validé avec ses étudiants.
Mais c’est loin d’être classique, car l’ensemble est sous-tendu tout au long
de l’ouvrage, par un souci critique d’analyser l’évolution des modèles, des
techniques et surtout des architectures en fonction de l’évolution des
vi
SGBD relationnels – Tome 1, État de l’art
besoins.
On découvrira ainsi, dans ce 2ème tome, une grande attention portée aux
architectures et à leurs évolutions. On notera, en particulier, une
proposition qui permet de garder les qualités de rigueur du modèle
relationnel pur et les avantages conceptuels de l’approche Objet et XML.
Elle s’appuie sur l’approche évolutionnaire, très en vogue dans les organes
de normalisation de SQL et chez les grands éditeurs de SGBD, pourtant
critiquée par Chris Date lui-même, à cause des impacts négatifs sur la
cohérence du modèle relationnel qui en résultent et sur sa capacité à
préserver les acquis du modèle relationnel pur. Elle permet l’évolution par
l’intégration de nouveaux concepts dans le modèle relationnel. En plus de
cette intégration de ces nouveaux concepts dans le modèle relationnel,
l’approche proposée ici s’appuie également sur une mise en
correspondance de la perception que ces concepts permettent de définir par
rapport à la perception définie par une base de données relationnelle pure
utilisée en interne pour garantir l’intégrité et l’indépendance des données.
Cette proposition, détaillée clairement et de façon complète dans cette 2ème
édition de l’ouvrage, tant sur sa logique que sur sa capacité à contribuer à
une évaluation efficace des requêtes SQL, permet de tirer le meilleur de
mondes difficiles à concilier, car visant parfois des objectifs différents, sans
sacrifier les bénéfices du modèle initial.
vii
TABLE DES MATIÈRES
PREFACE ............................................................................................................. V
REMERCIEMENTS ......................................................................................XXV
2.1. Introduction 27
3.1. Introduction 87
3.2.1. Les anomalies possibles dans une extension légale de relation ...................88
3.2.2. Ce que permet la normalisation d’une relation ...............................................90
x
SGBD relationnels – Tome 1, État de l’art
3.5.2. Les approches relationnelles et les approches orientées sémantique ....... 131
3.5.3. Exemples de méthodes relationnelles de conception d’un schéma
relationnel.............................................................................................................................. 134
xi
Joachim TANKOANO
xii
SGBD relationnels – Tome 1, État de l’art
7.3. Les principes de base pour le stockage d’une table sur un disque 351
7.3.1. Un rappel sur la structure logique d’une base de données relationnelle. 351
7.3.2. Le stockage d’une table dans des blocs de disques ...................................... 351
7.3.3. L’organisation des lignes dans un bloc .......................................................... 352
7.3.4. L’organisation des colonnes dans une ligne .................................................. 353
7.3.5. Les conséquences sur le temps d’accès aux lignes d’une table stockées en
vrac dans des blocs ............................................................................................................... 354
7.3.6. Les techniques pour réduire le temps d’accès à une ligne d’une table ..... 356
7.3.7. L’impact des disques SSD sur le temps d’accès à une ligne d’une table . 357
7.4. La réduction du temps d’accès à l’aide d’une stratégie de placement des lignes
de tables 358
7.4.1. Pourquoi gérer le placement des lignes à l’intérieur des blocs .................. 358
7.4.2. Les leçons à tirer .................................................................................................. 359
7.7.1. L’architecture physique d’un SGBD Oracle en termes de fichiers ............ 414
7.7.2. L’organisation logique des données à l’intérieur des fichiers ................... 415
7.7.3. Le langage de définition du schéma physique d’une base de données ... 420
7.7.4. L’architecture interne d’un serveur de bases de données Oracle .............. 429
xiii
Joachim TANKOANO
8.3.1. Les règles de réécriture basées sur des équivalences algébriques .............442
8.3.2. Les règles de réécriture basées sur des équivalences logiques ...................449
9.2.1. Les anomalies liées aux accès simultanés à une base de données..............498
9.2.2. Les caractéristiques des incidents ....................................................................505
9.2.3. Les propriétés attendues de l’environnement d’exécution ..........................506
xiv
SGBD relationnels – Tome 1, État de l’art
9.3.4. Les mécanismes de contrôle basés sur les estampilles ................................ 541
9.3.5. Les mécanismes de contrôle basés sur la certification des transactions ... 546
9.3.6. Les quatre niveaux d’isolation de SQL ........................................................... 547
9.4.1. Les moyens de mise en œuvre des reprises après incident ......................... 550
9.4.2. Les différents types de reprises après incident ............................................. 555
9.5. La gestion des accès concurrents et des reprises sous Oracle 559
9.5.1. La démarcation des transactions à l’intérieur d’une session Oracle ......... 560
9.5.2. La gestion de l’exécution concurrente des transactions sous Oracle ......... 562
9.5.3. La gestion d’une reprise après un incident sous Oracle .............................. 574
xv
AVANT-PROPOS
Le public visé
Cet ouvrage en deux tomes reprend le contenu du cours que j’ai appris à
enseigner à l’Institut Burkinabè des Arts et Métiers (IBAM) de l’Université
Joseph Ki-Zerbo (ex-Université de Ouagadougou) en Licence 2 et 3 et en
Master 1 de la filière MIAGE (Méthodes Informatiques Appliquées à la
Gestion), au cours des dix dernières années de ma carrière d’enseignant.
xviii
SGBD relationnels – Tome 1, État de l’art
La 1ère édition de cet ouvrage a mis en évidence le fait que le modèle objet-
relationnel et le modèle relationnel et XML sacrifient les garanties
d’intégrité et d’indépendance des données. Les conséquences de ce constat
y ont été illustrées à l’aide d’exemples. La principale raison d’être de cette
2ème édition est d’y inclure une explication des causes de ce constat ainsi
qu’une description complète et détaillée de la solution palliative esquissée
dans la 1ère édition. Ces ajouts ont été opérés en veillant à la cohérence du
contenu des deux tomes qui composent l’ouvrage.
Ce tome 1 de l’ouvrage
Issue au début des années 70 des travaux de CODD E.F., le père fondateur
du modèle relationnel pur, la 2ème génération de la technologie des bases de
données est encore très largement utilisée par les entreprises. Cette
résistance au temps, dans un secteur caractérisé par des mutations
effrénées, s’explique en grande partie par le fait que cette 2ème
génération repose nativement sur deux éléments essentiels :
• Elle repose sur un ensemble de concepts volontairement réduit au
minimum nécessaire, non dérivés d’un paradigme de
programmation en particulier, qui induisent une perception sur les
données : (i) dénudée de toute ambiguïté susceptible d’induire des
interprétations différentes, (ii) indépendante des modèles
sémantiques et des modèles de données abstraites qui relèvent du
domaine de la programmation et pouvant servir pour leur
implémentation logique (iii) pouvant servir pour la dérivation d’une
implémentation physique sur les supports de stockage sans avoir à
procéder à une décomposition préalable des informations
modélisées en informations plus élémentaires, (iv) pouvant de ce fait
servir de base commune à toutes les applications devant avoir des
xix
Joachim TANKOANO
xx
SGBD relationnels – Tome 1, État de l’art
xxi
Joachim TANKOANO
xxii
SGBD relationnels – Tome 1, État de l’art
xxiii
Joachim TANKOANO
Le tome 2 de l’ouvrage
Ce tome traite de la prise en compte par les SGBD relationnels des besoins
émergents engendrés par la digitalisation des services que les entreprises
offrent à tous les acteurs de la société, les citoyens y compris. Ces nouveaux
besoins imposent aux SGBD des garanties sur la scalabilité et la
disponibilité sans interruptions de leur offre de services aux applications
ainsi que des garanties pour le stockage de mégadonnées abstraites et
complexes et pour leur manipulation selon des approches non-
relationnelles (orientées objet et XML par exemple). Ce tome est consacré
à la présentation des évolutions des SGBD relationnels dont l’ambition est
d’apporter une réponse satisfaisante à ces nouvelles exigences.
xxiv
SGBD relationnels – Tome 1, État de l’art
Joachim TANKOANO
tankoanoj@gmail.com
REMERCIEMENTS
Je tiens à remercier infiniment Monsieur Jean Claude DERNIAME pour
l’intérêt qu’il a accordé à cet ouvrage et pour m’avoir encouragé à le publier.
xxv
Chapitre 1. : Introduction
1.1. Du fichier aux bases de données
En revanche, s’il s’agit d’une entreprise qui fait intervenir plusieurs acteurs,
la mémoire humaine devient insuffisante et inadaptée pour la
mémorisation des informations dont ces acteurs ont besoin pour accomplir
leurs tâches. Dans ce cas, l’entreprise doit recourir à une mémoire artificielle
gérée manuellement ou à l’aide d’un système informatique.
2
SGBD relationnels – Tome 1, État de l’art
Les premières solutions mises en œuvre à cet effet n’ont toutefois conduit
qu’à une simple transformation des « fichiers papiers » en « fichiers
informatiques » gérés à l‘aide des fonctionnalités offertes par le système de
gestion des fichiers (SGF) du système d’exploitation de l’ordinateur hôte.
3
Joachim TANKOANO
Dans ces méthodes basées sur le principe « diviser pour régner », dans la
phase d’analyse, le concepteur doit :
• Identifier les résultats que l’application doit produire (Exemple :
relevés de comptes, tableau de bord pour le suivi des opérations
journalières du jour J, états journaliers des opérations de caisse à
saisir le jour J+1, …)
• Identifier, en fonction des résultats à produire, les lots de données
que les utilisateurs doivent fournir à l’application (Exemple :
données des fiches de création de compte, des états journaliers des
opérations de caisse à saisir la nuit pour la production des états du
jour J+1, …).
4
SGBD relationnels – Tome 1, État de l’art
5
Joachim TANKOANO
6
SGBD relationnels – Tome 1, État de l’art
peut être présent dans plusieurs de ces fichiers à la fois. Chaque fois
qu’une information est requise dans des programmes différents, ceci
peut avoir comme conséquence l’introduction de données
redondantes dans plusieurs fichiers de l’application. Par exemple,
dans une banque, le « fichier dépôts » utilisé pour la gestion des
dépôts effectués par les clients et le « fichier prêts » utilisé pour la
gestion des prêts accordés aux clients peuvent contenir tous les deux
des informations relatives aux clients concernés. De ce fait, les
informations relatives aux clients qui ont à la fois effectué des dépôts
et contracté des prêts seront présentes dans ces deux fichiers sous
forme de données redondantes.
Des copies multiples d’une donnée peuvent aussi se retrouver dans
le même fichier. Ce cas de figure peut se produire dans le « fichier
des prêts » s’il existe des clients qui ont contracté plusieurs prêts.
Dans ce cas de figure, les informations qui décrivent un client se
retrouveront dans plusieurs lignes du fichier, sous forme de données
redondantes.
Dans les deux situations, la redondance peut engendrer des
incohérences dans l’état du système d’information, dues au fait que,
pour diverses raisons, les valeurs des copies multiples d’une donnée
peuvent à un moment donné être différentes. Les contrôles requis
pour éviter ces incohérences, qui mettent à rude épreuve l’intégrité
des données, peuvent s’avérer complexes et coûteux en temps
d’exécution.
3) L’incapacité du système de gestion des fichiers des systèmes
d’exploitation à gérer le partage des données : Pour qu’une
application puisse apporter une assistance en temps réel
simultanément à plusieurs utilisateurs, il faut en particulier que les
traitements effectués pour le compte de ces utilisateurs puissent, si
cela est nécessaire, accéder simultanément en lecture et/ou en
écriture aux données contenues dans un fichier de l’application sans
altérer l’intégrité de ces données. Pour ce faire, il faut que le système
de gestion des fichiers du système d’exploitation de l’ordinateur
hôte soit en mesure de gérer convenablement les conflits d’accès aux
7
Joachim TANKOANO
8
SGBD relationnels – Tome 1, État de l’art
9
Joachim TANKOANO
Ce qui suit est une présentation introductive de ces exigences. Pour chacune
d’elle cette présentation introductive met en exergue les attentes liées à sa
prise en charge et résume la manière dont les SGBD s’y prennent pour
l’assurer. Cette présentation introductive n’a pas pour finalité d’amener le
lecteur à comprendre tout de suite le comment de cette prise en charge. La
manière dont les SGBD s’y prennent pour prendre en charge ces exigences
notamment en s’appuyant sur le modèle relationnel de E.F. CODD, défini
en 1970, y compris les fondements théoriques des approches mises en
œuvre, est étudiée de façon plus détaillée comme indiqué ci-dessus dans
les autres chapitres de ce tome. En revenant sur cette présentation
introductive chaque fois que de besoin, le lecteur pourra se faire une idée
sur l’évolution de son cheminement vers une bonne compréhension de la
prise en charge de ces exigences par la technologie des bases de données.
10
SGBD relationnels – Tome 1, État de l’art
11
Joachim TANKOANO
choix des algorithmes qui en découlent pour l’accès à ces données, doivent
se faire à l’intérieur des programmes par le développeur. De ce fait, un
changement de ces choix ou une modification de ces descriptions, peut
entraîner une maintenance très lourde d’un très grand nombre de
programmes.
12
SGBD relationnels – Tome 1, État de l’art
NIVEAUX
D’ABSTRACTION Vues logiques individualisées par application
NIVEAU
EXTERNE
Schéma externe …….. Schéma externe
1 . N
<--- Mapping des perceptions --->
13
Joachim TANKOANO
Pour chaque application, le niveau externe vise donc la définition d’une vue
abstraite personnalisée sur les données, qui permet à cette application de
percevoir et de manipuler les données comme si elles étaient stockées dans
la base de données virtuelle qui répond à ses besoins spécifiques.
14
SGBD relationnels – Tome 1, État de l’art
15
Joachim TANKOANO
En d’autres termes, le niveau physique définit une vue des données sur les
supports physiques de stockage. Il vise la définition du « COMMENT », c’est-
à-dire une implémentation sur les supports physiques des données décrites
par le schéma logique de la base de données. Cette implémentation est en
général définie en termes de sites de répartition des données, de fichiers, de
pages ou blocs, d’enregistrements, de chemins d’accès, de pointeurs,
d’algorithmes de recherche, etc., sans s’encombrer ou chercher à tirer
avantage des fonctionnalités des systèmes de gestion des fichiers des
systèmes d’exploitation.
16
SGBD relationnels – Tome 1, État de l’art
données.
Pour que ces données soient considérées comme étant cohérentes, les deux
conditions ci-après doivent être satisfaites à tout instant :
1) Ces données doivent respecter les contraintes d’intégrité qui
découlent des règles de gestion de l’entreprise concernée
2) Ces données ne doivent pas contenir des redondances ou s’il en
existe ces redondances doivent être voulues et contrôlées de façon
automatique afin d’éviter l’accès à des valeurs contradictoires.
À titre d’exemple, les règles de gestion d’une banque peuvent imposer une
contrainte d’intégrité formulée de la façon suivante : « un compte ne doit
appartenir qu’à un et un seul client ». Cette contrainte d’intégrité définit la
dépendance qui doit exister entre les clients et les comptes. On dira que
cette contrainte d’intégrité a été violée si à un moment donné les
informations contenues dans la base de données indiquent qu’un compte
n’appartient à aucun client ou qu’il appartient à plusieurs clients.
Lorsqu’il existe des redondances dans une base de données, les copies des
donnés concernées peuvent contenir des valeurs différentes, donc des
informations contradictoires, c'est-à-dire incohérentes. En outre, l’existence
17
Joachim TANKOANO
1.2.3. La confidentialité
18
SGBD relationnels – Tome 1, État de l’art
différentes liées aux rôles qu’ils jouent au sein de cette entreprise. Les
informations que ces acteurs peuvent manipuler dans le cadre de leurs
activités découlent en général de ces responsabilités.
La prise en compte par les SGBD de cette exigence est donc un besoin qui
découle du fait que la possibilité qu’on donne à plusieurs acteurs de
partager des données doit pouvoir s’accompagner de restrictions qui
tiennent compte des responsabilités de chaque acteur.
Les mécanismes mis en œuvre par les SGBD pour le contrôle de l’intégrité
et des droits d’accès sont comparables sur plusieurs points. Dans les deux
cas, les informations requises sont stockées dans le schéma logique de la
base des données et les mécanismes de contrôle mis en œuvre par le SGBD
lors de chaque demande d’accès aux données, peu importe la logique des
applications à l’origine de ces demandes.
19
Joachim TANKOANO
L’exigence liée à la gestion des accès concurrents aux données impose aux
SGBD la capacité de pouvoir garantir que de telles incohérences liées à
l’entrelacement des opérations effectuées sur une base de données pour le
compte d’acteurs différents ne peuvent jamais survenir.
20
SGBD relationnels – Tome 1, État de l’art
1.2.5. La sécurité
21
Joachim TANKOANO
22
SGBD relationnels – Tome 1, État de l’art
Les SGBD offrent aux entreprises les moyens pouvant leur permettre de
contrôler et d’optimiser l’organisation et le stockage des données ainsi que
l’exécution des requêtes afin de tirer le meilleur parti de ces techniques.
Les schémas qui décrivent les données stockées dans une base de données
sont avantageusement centralisés dans le catalogue de cette base de
données (appelé aussi dictionnaire de données) implémenté lui aussi
comme une base de données, donc comme une méta-base de métadonnées.
23
Joachim TANKOANO
Pour satisfaire cette exigence, les SGBD proposent en règle générale aux
entreprises un langage textuel de définition des données simple à utiliser et
pouvant avoir un équivalent graphique plus facile à appréhender par les
utilisateurs non informaticiens. Ce langage de définition des données offre
en général les instructions requises pour décrire de façon déclarative dans
le catalogue de la base de données :
• Le schéma logique de cette base de données
• Les schémas externes logiques
• Le schéma physique.
24
SGBD relationnels – Tome 1, État de l’art
25
Joachim TANKOANO
BIBLIOGRAPHIE
ANSI/X3/SPARC Study group on data management systems: Interim
report, Bulletin of ACM SIGMOD 7(2),1975
Codd E. F.: The relational model for database management - Second Edition,
Addison-Wesley Publishing Company, Inc., 1990
Date C.J : Introduction aux bases de données - 8è édition, Vuibert, Paris, 2004
Miranda S. & Busta J-M. : L'art des bases de données, Tome 2, Les bases de
données relationnelles - 2è édition, Eyrolles, 1990
Reed P.: The Unified Modeling Language Take Shape – DBMS 11, No 8, Juillet
1988
Silberschatz A., Korth H.F. & Sudarshan S.: Database system concepts, sixth
edition, McGraw-Hill, 2011
26
Chapitre 2. : Concepts et langages formels du
modèle relationnel
2.1. Introduction
Comme indiqué dans la section 1.2.1, le modèle relationnel est le modèle de
données sur lequel s’appuient les SGBD de la 2ème génération. Il dit
comment les données sont présentées au développeur par les SGBD de cette
génération et comment ces données peuvent être manipulées dans un
programme.
Ce chapitre présente dans la section 2.2 les principaux concepts qui sous-
tendent ce modèle, à savoir, les concepts de : « relation »,
« domaine/attribut », « dépendance entre groupes d’attributs », « clé
primaire », « clé candidate », « clé unique » et « clé étrangère ».
Joachim TANKOANO
28
SGBD relationnels – Tome 1, État de l’art
Ces concepts sont utilisés pour définir une base de données relationnelle de
façon abstraite, en termes de relations où chaque relation contient une
partie des données élémentaires qui constituent la mémoire du système
d’information. Ces relations se définissent de diverses manières.
Dans cette définition d’une relation, « n » désigne son degré (ou arité) ,
c'est-à-dire son nombre de domaines ou d’attributs.
La notion de domaine est utilisée par les SGBD pour fournir la garantie de
l’intégrité de domaine en s’assurant que la valeur de chaque donnée
élémentaire dans une base de données relationnelle est légale parce que
29
Joachim TANKOANO
N.B. : Le concept de relation tel que défini n’est pas à confondre avec le
concept de relation du modèle Entité/Association de P-P. CHEN qui est
une forme d’énoncé servant à relier les instances d’une ou de plusieurs
entités. Lorsqu’il s’agira du concept de « relation » du modèle
Entité/Association, nous utiliserons le terme d’« association » entre entités.
30
SGBD relationnels – Tome 1, État de l’art
Pilotes
NoPilote NomPilote AdressePilote
1 Jean BP 1322 OUAGADOUGOU
2 Paul BP 10 BOBO-DIOULASSO
3 Amadou BP 213 LEO
▀
Sous cet angle, une relation d’arité « n » se définit en intention à l’aide d’un
prédicat P à « n » variables prenant leurs valeurs dans les domaines « D1,
…, Dn » de cette relation. Un prédicat P à « n » variables qui sert à définir
une relation est une forme d’énoncé sur ces « n » variables qui devient une
proposition vraie, c’est-à-dire une assertion, quel que soit le n-uplet de
valeurs de cette relation qu’on affecte à ces variables. En se basant sur ce
prédicat, la définition d’une relation peut se faire de la façon suivante :
R = {(aj1, …, ajn) | j P (aj1, …, ajn)}.
31
Joachim TANKOANO
32
SGBD relationnels – Tome 1, État de l’art
Une dépendance fonctionnelle (DF) dans une relation « R » est une forme
particulière de dépendance entre deux attributs ou groupes d’attributs de
cette relation.
33
Joachim TANKOANO
Comme nous le verrons dans le chapitre 3, bien que plus rares, des
dépendances peuvent exister également entre plus de deux attributs (ou
groupes d’attributs).
34
SGBD relationnels – Tome 1, État de l’art
relation, autres que sa clé primaire, sont des clés alternatives (ou clés
uniques).
Exemple 2.2.3.iii : Les deux relations définies par les schémas ci-dessous
sont sémantiquement liées par l’attribut « NoPilote » qui est une clé
35
Joachim TANKOANO
Comme nous le verrons dans le chapitre 3, lorsque les relations sont bien
conçues, les clés primaires, alternatives et étrangères permettent aux SGBD
d’empêcher la violation des contraintes d’intégrité relatives aux
dépendances entre attributs découlant des règles de gestion de l’entreprise,
en garantissant le respect de l’intégrité de relation, de l’intégrité d’unicité et
de l’intégrité référentielle. De ces clés, on peut déduire toutes les
dépendances fonctionnelles qui découlent des règles de gestion de
l’entreprise et inversement.
Comme nous venons de le voir, le modèle relationnel pur tel que défini en
1970 par E.F. CODD est un modèle logique de données relevant du domaine
de la programmation sans être dérivé d’un paradigme de programmation
en particulier, strict sur l’intégrité. Il permet de modéliser une base de
données à l’aide d’un « schéma logique relationnel » comme étant
composée d’un ensemble de relations constituées de n-uplets de valeurs
typées atomiques. Ces relations, soumises à des contraintes d’intégrité, sont
sémantiquement liées par des liens référentiels matérialisés à l’aide de clés
étrangères. Elles sont manipulables à l’aide d’opérateurs algébriques
relationnels abstraits et génériques (voir section 2.3) et implémentables de
diverses manières sur les supports physiques de stockage sans avoir à
procéder à une décomposition préalable des informations modélisées en
informations plus élémentaires (voir chapitres 7 et 8).
36
SGBD relationnels – Tome 1, État de l’art
Ainsi par exemple, pour rendre les données décrites par un schéma
conceptuel propre (c'est-à-dire bien conçu), manipulables dans un
37
Joachim TANKOANO
A 0, n B
1, n R 1, 1 A (a1, …, ai)
a1
0, 1
b1
….. r1, ….., rk ….. B (b1, …, bj, a1#, r1, …, rk)
1, 1
ai r bi
N.B. :
• L’entité « A » devient la relation « A » ayant comme attributs les
propriétés de l’entité « A »
• L’entité « B » devient la relation « B » ayant comme attributs les
propriétés de l’entité « B », l’identifiant « a1 » de l’entité « A » et
les propriétés de l’association « R ».
A B
0, n R 0, 1 A (a1, …, ai)
a1 b1
1, n r1, ….., rk
….. ….. B (b1, …, bj, a1#, r1, …, rk)
0, 1
ai r bi
N.B. :
• L’entité « A » devient la relation « A » ayant comme attributs les
propriétés de l’entité « A »
• L’entité « B » devient la relation « B » ayant comme attributs les
propriétés de l’entité « B », l’identifiant « a1 » de l’entité « A » et
les propriétés de l’association « R ».
• Dans ce cas, les contraintes d’intégrité doivent exprimer en plus le
fait que les attributs « a1 », « r1 », …, « rk » de la relation « B »
doivent pouvoir prendre comme valeur, la valeur indéterminée
« NULL ».
38
SGBD relationnels – Tome 1, État de l’art
A 0, n 0, n B A (a1, …, ai)
1, n R 1, n
a1 b1 B (b1, …, bj)
0, 1 r1, ….., rk 0, 1
….. …..
R (a1#, b1#, r1, …, rk)
ai bi
N.B. :
• L’entité « A » devient la relation « A » ayant comme attributs les
propriétés de l’entité « A »
• L’entité « B » devient la relation « B » ayant comme attributs les
propriétés de l’entité « B »
• L’association « R » devient la relation « R » ayant comme attributs
l’identifiant « a1 » de l’entité « A », l’identifiant « b1 » de l’entité
« B » et les propriétés de l’association « R »
• Cette règle est également applicable aux associations où
participent plus de deux entités.
Exemple 2.2.4.i : Ce qui suit est un exemple de schéma conceptuel basé sur
le formalisme du modèle Entité / Association.
Client Commande
0, n Passe 1, 1 1, n
NoCli NoCmde
NomCli DateCmde
ComposéeDe
Qtée
Taxe Produit
0, n 1, n
TaxéA RefProd
CodeTaxe
TauxTaxe LibelléProd 0, n
PrixProd
39
Joachim TANKOANO
40
SGBD relationnels – Tome 1, État de l’art
1) L’union, notée « »
41
Joachim TANKOANO
2) La différence, notée « - »
4) La projection, notée « »
5) La sélection, notée « ».
Les trois (3) autres opérateurs (qu’on peut définir à partir de ces opérateurs
« primitives ») sont :
1) L’intersection, notée « »
2) La jointure, notée « »
3) La division, notée « ÷ ».
a) L’union (« »)
42
SGBD relationnels – Tome 1, État de l’art
b) La différence (« - »)
c) Le produit cartésien (« * »)
43
Joachim TANKOANO
d) La projection (« »)
N.B. Dans la relation qui résulte d’une projection, les tuples qui se répètent
(c’est-à-dire les doublons) sont supprimés afin de se conformer à la
définition d’un ensemble.
44
SGBD relationnels – Tome 1, État de l’art
e) La sélection « »
f) L’intersection (« »)
45
Joachim TANKOANO
g) La jointure (« »)
46
SGBD relationnels – Tome 1, État de l’art
h) La division (« ÷ »)
47
Joachim TANKOANO
F1 P1 P1 F1
F4 P1 P3 F4
F3 P2
F4 P3
F1 P3
48
SGBD relationnels – Tome 1, État de l’art
pouvant conduire à l’exécution d’une requête SQL. Ces aspects sont étudiés
en détails dans le chapitre 8.
49
Joachim TANKOANO
Exemple 2.3.3.i : Quels sont les numéros des pilotes en service et les villes d’arrivée
de leurs vols ?
La relation « Vols » contient les informations sur les vols, y compris les
numéros des pilotes qui assurent ces vols (c'est-à-dire les numéros des
pilotes en service) ainsi que les villes d’arrivée de ces vols. Cette relation
contient donc toutes les données requises pour construire comme suit le
résultat recherché :
Résultat = (NoPilote, VA) (Vols)
Exemple 2.3.3.ii : Quels sont les numéros des vols au départ de Ouagadougou ?
La 1ère ligne sélectionne tous les vols qui sont au départ de Ouagadougou.
La 2ème ligne restreint cette sélection aux numéros de ces vols.
Exemple 2.3.3.iii : Quels sont les noms des pilotes, autres qu’Amadou, qui
habitent Bobo-Dioulasso ?
50
SGBD relationnels – Tome 1, État de l’art
Cet exemple montre que, comme dans les autres algèbres, des séquences
différentes d’opérations peuvent aboutir au même résultat.
▀
Exemple 2.3.3.iv : Quels sont les numéros des pilotes, qui conduisent l’avion
numéro 104 et l’avion numéro 106 ?
Les deux premières lignes calculent l’ensemble des vols effectués avec
l’avion 104 et l’ensemble des vols effectués avec l’avion 106. La dernière
51
Joachim TANKOANO
ligne calcule d’abord l’ensemble des numéros des pilotes qui assurent un
vol avec l’avion 104 et l’ensemble des numéros des pilotes qui assurent un
vol avec l’avion 106 et effectue ensuite une intersection de ces deux résultats
intermédiaires pour obtenir le résultat recherché.
Exemple 2.3.3.v : Pour chaque pilote en service, quels sont les numéros des avions
conduits, le numéro et l’adresse du pilote ?
52
SGBD relationnels – Tome 1, État de l’art
Exemple 2.3.3.vi : Quels sont les noms des pilotes qui conduisent un vol au départ
de Ouagadougou ?
Exemple 2.3.3.vii : Quels sont les noms des pilotes qui conduisent un AIRBUS ?
Les données requises pour construire le résultat recherché dans cet exemple
se trouvent dans trois relations : (1) « Vols » où se trouvent les numéros des
pilotes qui assurent des vols et les numéros des avions qu’ils conduisent,
53
Joachim TANKOANO
Exemple 2.3.3.viii : Quels sont les numéros des pilotes qui conduisent tous les
avions de la compagnie ?
Les données requises pour calculer le résultat recherché dans cet exemple
se trouvent dans deux relations : (1) « Vols » où se trouvent les numéros
des pilotes qui assurent des vols et les numéros des avions qu’ils
conduisent, (2) « Avions » où se trouvent les numéros de tous les avions de
la compagnie. Pour qu’un pilote soit dans le résultat recherché, il faut qu’il
conduise chacun des avions de la compagnie. En d’autres termes le produit
54
SGBD relationnels – Tome 1, État de l’art
Exemple 2.3.3.ix : Quels sont les numéros des pilotes qui conduisent au moins
tous les AIRBUS de la compagnie ?
Exemple 2.3.3.x : Quels sont les noms des pilotes qui n’effectuent pas de vol au
départ de Ouagadougou ?
55
Joachim TANKOANO
Les quatre premières lignes calculent les numéros des pilotes qui
n’effectuent pas des vols au départ de Ouagadougou en ôtant de l’ensemble
des numéros des pilotes, l’ensemble des pilotes qui effectuent un vol au
départ de Ouagadougou. Quant aux deux dernières lignes, elles calculent
le résultat recherché à partir du résultat des quatre premières lignes.
Exemple 2.3.3.xi : Quels sont les numéros des pilotes qui conduisent un avion
conduit par le pilote n° 32 ?
56
SGBD relationnels – Tome 1, État de l’art
Exemple 2.3.3.xii : Quelles sont les villes desservies par les pilotes dont le numéro
est plus grand que celui de Pierre et Paul ?
Les données requises pour calculer le résultat recherché dans cet exemple
se trouvent dans deux relations : (1) « Vols » où se trouvent les numéros
des pilotes qui assurent des vols et les villes desservies par ces vols, (2)
« Pilotes » où se trouvent les noms de ces pilotes. Le calcul du résultat
recherché dans cet exemple peut se faire comme suit :
Pilotesx = (NomPilote = 'Pierre') (Pilotes)
Pilotesy = (NoPilote) (Pilotesx)
Volsx = Vols (Vols.NoPilote Pilotesy.Nopilote) Pilotesy
Pilotesu = (NomPilote = 'Paul') (Pilotes)
Pilotesv = (NoPilote) (Pilotesu)
Volsy = Volsx (Volsx.NoPilote Pilotesv.Nopilote) Pilotesv
Résultat = (VA) (Volsy)
57
Joachim TANKOANO
Cette requête peut être traitée à l’aide de l’opération d’union comme ci-
dessous :
Avions = Avions {4, 'AIRBUS', 200, 'Ouagadougou'}
▀
2.3.4. Exercice
58
SGBD relationnels – Tome 1, État de l’art
Dans ce schéma relationnel, les attributs prennent leurs valeurs dans les
domaines ci-après :
nom : noms de salles de projection
horaire : heures de la journée
titre : titres de films
acteur, producteur, spectateur : noms de personnes
59
Joachim TANKOANO
Exemple 2.4.1.i : La signature « = ({0, 1}, {+, -}, {=, }) » permet de formuler
des énoncés sur l’ensemble « ℕ » des objets, correspondants aux entiers
naturels. Le symbole des constantes « 0 » doit être interprété comme étant
l’entier « 0 », le symbole des constantes « 1 » comme étant l’entier « 1 », le
60
SGBD relationnels – Tome 1, État de l’art
Un prédicat « P (x1, x2, …, xn) » est une forme d’énoncée sur « x1, x2, …,
xn » qui devient une proposition, c'est-à-dire, une affirmation, lorsque des
valeurs sont affectées à « x1 », « x2 », …, « xn ». En fonction de la
signification du prédicat « P » et des valeurs affectées à « x1 », « x2 », …,
« xn », cette affirmation peut être, soit « vraie », soit « fausse ».
61
Joachim TANKOANO
Les énoncés (ou phrases) de la logique du 1er ordre sont des formules bien
formées, construites par induction de la façon suivante :
• Si « P » est le symbole d’un prédicat d’arité « n » et « t1, …, tn » des
termes, alors « P (t1, …, tn) » est une formule atomique
• Une formule atomique est une formule
• Si « F1 » et « F2 » sont des formules, alors « F1 F2 », « F1 F2 »,
« F1 F2 » et « F1 » sont aussi des formules
• Si « F1 » est une formule et « x1, …, xn » des variables, alors « x1,
…, xn F1 » et « x1, …, xn F1 » sont aussi des formules
• Si « F1 » est une formule, alors « (F1) » est une formule.
62
SGBD relationnels – Tome 1, État de l’art
• F1 F2 F1 F2 (F1 F2)
• x1, …, xn F1 ( x1, x2, …, xn F1)
• x1, x2, …, xn F1 ( x1, x2, …, xn F1)
Lorsque dans une formule une variable « x » n’est pas liée, elle est dite libre.
Lorsque dans une formule toutes les variables sont liées, on dit que cette
formule est close ou fermée.
Lorsque dans une formule il existe des variables libres, cette formule est
dite ouverte et est considérée comme étant un prédicat sur ces variables
libres.
63
Joachim TANKOANO
Les langages prédicatifs ont pour finalité d’offrir cette possibilité. Ces
langages permettent, pour chaque requête, de construire une formule de la
logique du 1er ordre, contenant des variables libres, de sorte que cette
formule puisse être interprétée comme étant le prédicat que chaque tuple
de la relation, correspondant au résultat recherché, doit vérifier, par
déduction en partant des assertions des relations existantes. Cette formule
64
SGBD relationnels – Tome 1, État de l’art
Tenant compte du fait que l’énoncé d’une requête peut être formulé sur des
symboles de constantes qui sont, soient des tuples de relations, soient des
valeurs d’attributs, on distingue les requêtes en calcul relationnel à
variables n-uplets et les requêtes en calcul relationnel à variables domaines.
65
Joachim TANKOANO
66
SGBD relationnels – Tome 1, État de l’art
67
Joachim TANKOANO
68
SGBD relationnels – Tome 1, État de l’art
la partie droite, qui spécifie le prédicat que chaque tuple du résultat doit
vérifier, se fait selon des règles qui amènent à combiner des formules
atomiques à l‘aide des connecteurs logiques et des quantificateurs (, , ,
). Chaque formule atomique pouvant être utilisée est : (i) soit un
prédicat de la forme Ri(t) évalué à vraie si « t » est un tuple de la relation
« Ri », (ii) soit un prédicat de comparaison de la forme « P(t) » où les termes
comparés ne désignent que des attributs d’un même tuple « t », (iii) soit un
prédicat de comparaison de la forme « P(t1, t2) » où les termes comparés
désignent des attributs de deux tuples différents « t1 » et « t2 ».
L’expression définie par une sous-formule formée à l’aide de ces formules
atomiques peut correspondre ou ne pas correspondre à un prédicat que doit
satisfaire les tuples d’une relation correspondant à un résultat
intermédiaire. Les sous-formules correspondant à un prédicat que doit
satisfaire les tuples d’une relation sont considérées comme étant saines et
les autres comme étant non saines.
69
Joachim TANKOANO
70
SGBD relationnels – Tome 1, État de l’art
Pour ces raisons, on peut être tenté de dire que les langages prédicatifs
relationnels sont de bons candidats pour la formulation des requêtes par les
humains et les langages algébriques relationnels de bons candidats pour la
dérivation par les SGBD d’un calcul abstrait pour la construction du résultat
recherché. Comme présenté de façon plus détaillée dans le chapitre 4, ce
sont ces deux types de langages qui ont fourni en grande partie les bases
conceptuelles qui ont servi à la définition de SQL, le langage de requête des
71
Joachim TANKOANO
Les bases conceptuelles de SQL qui reposent sur les langages prédicatifs
relationnels ont la particularité qu’elles permettent son enrichissement
continuel à l’aide de nouvelles fonctions de composition et de nouveaux
prédicats.
72
SGBD relationnels – Tome 1, État de l’art
Pour décrire dans ce qui suit ce processus de façon plus détaillée, nous nous
appuyons sur l’énoncé informel suivant : déduire de la base de données
« tous les numéros de vols au départ de Bobo-Dioulasso ».
73
Joachim TANKOANO
cible : déduire à partir des assertions de la relation « Vols » tous les tuples
« v » de « Vols » dont la valeur de l’attribut « NoVol » vérifie le prédicat
« le vol NoVol effectue un trajet allant de Bobo-Dioulasso ». Ceci peut aussi
se dire « rechercher tous les numéros de vols au départ de Bobo-
Dioulasso ».
74
SGBD relationnels – Tome 1, État de l’art
Pour chacun des énoncés informels des requêtes qui suivent, nous
proposons une traduction en langage prédicatif en calcul relationnel à
variables n-uplets et une autre en langage prédicatif en calcul relationnel à
variables domaines.
Exemple 2.4.5.i : Quels sont les numéros des pilotes en service et les villes d’arrivée
de leurs vols ?
75
Joachim TANKOANO
Exemple 2.4.5.iii : Quels sont les noms des pilotes, autres que « Amadou », qui
habitent « Bobo-Dioulasso » ?
Exemple 2.4.5.iv : Quels sont les numéros des pilotes, qui conduisent l’avion
numéro « 104 » et l’avion numéro « 106 » ?
76
SGBD relationnels – Tome 1, État de l’art
Exemple 2.4.5.v : Pour chaque pilote en service, quels sont les numéros des avions
conduits, le numéro et le nom du pilote ?
77
Joachim TANKOANO
Exemple 2.4.5.vi : Quels sont les noms des pilotes qui conduisent un vol au départ
de « Ouagadougou » ?
Exemple 2.4.5.vii : Quels sont les noms des pilotes qui conduisent un AIRBUS ?
78
SGBD relationnels – Tome 1, État de l’art
Exemple 2.4.5.viii : Quels sont les numéros des pilotes qui conduisent tous les
avions de la compagnie ?
79
Joachim TANKOANO
Exemple 2.4.5.ix : Quels sont les numéros des pilotes qui conduisent au moins
tous les AIRBUS de la compagnie ?
80
SGBD relationnels – Tome 1, État de l’art
Exemple 2.4.5.x : Quels sont les numéros d’avions qui sont supérieurs à tous les
numéros des avions conduits par le pilote n° 2 ?
81
Joachim TANKOANO
tuple de « Vols ».
{(a.NoAvion) |Avions (a) v (Vols(v) v.Nopilote = 2)
a.NoAvion v.NoAvion}
Exemple 2.4.5.xi : Quels sont les noms des pilotes qui n’effectuent pas de vol au
départ de « Ouagadougou » ?
82
SGBD relationnels – Tome 1, État de l’art
Exemple 2.4.5.xii : Quels sont les numéros des pilotes qui conduisent un avion
conduit par le pilote n° 32 ?
83
Joachim TANKOANO
de même nom dans le 1er tuple de « Vols », peu importe la valeur des attributs
« NoVol », « VD » et « VA » des deux tuples de « Vols » :
{(NoPilote) | NoVol1, VD1, VA1
(Vols (NoVol1, NoPilote, NoAvion1, VD1, VA1))
(NoPilote 32))
NoVol2, VD2, VA2
(Vols (NoVol2, NoPilote, NoAvion2, VD2, VA2)
(NoPilote = 32)
(NoAvion2 = NoAvion1))}
▀
Exemple 2.4.5.xiii : Quelles sont les villes desservies par les pilotes dont le numéro
est plus grand que celui de Pierre et Paul ?
84
SGBD relationnels – Tome 1, État de l’art
2.4.6. Exercice
Pour chacune des requêtes informelles ci-après, traitées dans cet exercice
précédent, proposez une formulation en langage prédicatif en calcul
relationnel à variables n-uplets et une autre en langage prédicatif en calcul
relationnel à variables domaines :
1) Où peut-on voir un film où joue « Idrissa OUEDRAOGO » ?
2) Quels sont les acteurs qui jouent dans tous les films produits par
« Idrissa OUEDRAOGO » ?
3) Quels sont les spectateurs qui aiment un film qu’ils n’ont pas vus ?
4) Quels sont les spectateurs qui aiment tous les films qu’ils ont vus ?
5) Quels sont les producteurs qui n’ont vu que les films qu’ils ont
produits ?
85
Joachim TANKOANO
BIBLIOGRAPHIE
Codd E. F.: A relational model of data for large shared data banks - CACM 13,
No 6 juin 1970
Codd E. F.: The relational model for database management - Second Edition,
Addison-Wesley Publishing Company, Inc., 1990
Date C.J. : Introduction aux bases de données - 8è édition, Vuibert, Paris, 2004
Maier D.: The Theory of Relational Databases, 1st edition - Computer Science
Press, (March 1983)
Minker J.: Logic and Databases, Past, Present, and Future - AI Magazine
Volume 18 Number 3 (1997) p 21 à 48
Miranda S. & Busta J-M. : L'art des bases de données, Tome 2, Les bases de
données relationnelles - 2è édition, Eyrolles, 1990
Silberschatz A., Korth H.F. & Sudarshan S.: Database system concepts, sixth
edition - McGraw-Hill, 2011
86
Chapitre 3. : Conception des schémas logiques
relationnels (dépendances et normalisation)
3.1. Introduction
Nous avons vu dans le paragraphe 1.2.2 que pour pouvoir servir de support
pour le stockage des données d’une entreprise, la technologie des bases de
données doit fournir des garanties parmi lesquelles celles relatives aux
exigences relatives à la non-redondance et à l’intégrité des données figurent
en très bonne place.
Supposons que le prédicat qui définit cette relation s’énonce comme suit :
« L’avion NoAvion est un NomAvion qui possède CapAvion places et qui
est localisé à LocAvion ».
a) La redondance logique
88
SGBD relationnels – Tome 1, État de l’art
b) L’anomalie d’insertion
c) L’anomalie de suppression
d) L‘anomalie de modification
Si la capacité des avions AIRBUS A310 passe de 200 à 175 places à la suite
d’une transformation des appareils, la prise en compte de cette
transformation dans cette extension entraînera :
• Soit une incohérence, si on se contente de la répercuter sur un seul
des tuples de l’extension
• Soit un coût élevé de mise à jour, si cette mise à jour doit s’effectuer
sur tous les tuples qui concernent un avion AIRBUS A310.
89
Joachim TANKOANO
e) Le problème de la reconnexion
NoAvion NomAvion
10 AIRBUS A310
20 AIRBUS A310
30 AIRBUS A340
40 BOING 707
50 BOING 707
90
SGBD relationnels – Tome 1, État de l’art
91
Joachim TANKOANO
NomAvion CapAvion
92
SGBD relationnels – Tome 1, État de l’art
a) Définitions
Soient :
• « R (A) » une relation où « A » désigne l’ensemble de ses attributs
• « X1, X2, X3 » une partition de « A »
93
Joachim TANKOANO
• « a » un attribut de « A ».
Clé candidate
Surclé
Attribut clé
94
SGBD relationnels – Tome 1, État de l’art
Soient :
• « R (A) » une relation où « A » désigne l’ensemble de ses attributs,
• « X1, X2, X3, X4 » des sous-ensembles de « A ».
95
Joachim TANKOANO
La réflexivité
Si « X2 X1 » alors « X1 → X2 ».
L’augmentation
La transitivité
De ces trois règles, on peut inférer les autres règles de déduction ci-après :
La pseudo-transitivité
En effet :
(i) X1 → X2 étant donné
(ii) X2, X3 → X4 étant donné
(iii) X1, X3 → X2, X3 par augmentation de (i)
(iv) X1, X3 → X4 par transitivité de (iii) et (ii)
L’union
Si « X1 → X2 » et « X1 → X3 » alors « X1 → X2, X3 ».
En effet :
(i) X1 → X2 étant donné
(ii) X1 → X3 étant donné
(iii) X1 → X1, X2 par augmentation de (i)
(iv) X1, X2 → X2, X3 par augmentation de (ii)
(v) X1 → X2, X3 par transitivité de (iii) et (iv)
96
SGBD relationnels – Tome 1, État de l’art
La décomposition
Si « X1 → X2, X3 » alors « X1 → X2 » et « X1 → X3 ».
En effet :
(i) X1 → X2, X3 étant donné
(ii) X2, X3 → X2 par réflexivité
(iii) X2, X3 → X3 par réflexivité
(iv) X1 → X2 par transitivité de (i) et (ii)
(v) X1 → X3 par transitivité (1) et (iii)
La composition
En effet :
(i) X1 → X2 étant donné
(ii) X3 → X4 étant donné
(iii) X1, X3 → X2, X3 par augmentation de (i)
(iv) X2, X3 → X2, X4 par augmentation de (ii)
(v) X1, X3 → X2, X4 par transitivité de (iii) et (iv)
Par transitivité :
{NoVol} → {NoAvion} et {NoAvion} → {CapAvion} {NoVol} → {CapAvion}.
▀
97
Joachim TANKOANO
Par ailleurs, il n’est pas possible de déduire à l’aide de ces axiomes, une
dépendance fonctionnelle qui n’appartient pas à « F+ ». On dit de ce fait que
cet ensemble d’axiomes constituent également un système de déduction
fermé.
DF20 : E, M → P DF21 : P → M
98
SGBD relationnels – Tome 1, État de l’art
DF28 : E, P → M
DF29 : E, P → M, P
▀
99
Joachim TANKOANO
X+ X ;
DFNU S ; /* DF non encore utilisés */
Tant que il existe une DF « G → D » dans DFNU telle que G X+ faire
X+ X+ {D} ;
DFNU DFNU – {G → D} ;
Fin faire ;
On peut de la même façon montrer que {A, D}+ = {A, B, C, D, E, F}, ce qui
permet de conclure que {A, D} est une clé candidate de cette relation.
▀
100
SGBD relationnels – Tome 1, État de l’art
101
Joachim TANKOANO
• Effectuer le calcul de {A, B}+, {A, C}+, {A, D}+, {A, E}+, {A, G}+, {B, C}+,
{B, D}+, {B, E}+, {B, G}+, {C, D}+, {C, E}+, {C, G}+, {D, E}+, {DG}+ et
{EG}+, ce qui montre que {A, B}, {B, C}, {B, D}, {B, E}, {C, D}, {C, E},
{C, G} sont des clés candidates.
• Procéder de la même manière pour les triplets qui ne sont pas des
surclés (à savoir {A, D, E}, {A, D, G}, {A, E, G}, {D, E, G}), ce qui
permet de dire qu’aucun de ces triplets ne peut être une clé
candidate.
• Montrer de la même manière que les quadruplets et quintuplets qui
ne sont pas des surclés ne sont pas non plus des clés candidates.
▀
102
SGBD relationnels – Tome 1, État de l’art
de cohérence.
2ème étape :
103
Joachim TANKOANO
3ème étape :
1ère étape :
2ème étape :
En répétant la même chose pour les autres DF (DF03, DF04, DF07, DF08,
DF09, DF10 et DF11), on trouve que « DF04 : A, C, D → B » peut être
remplacée par « DF04’ : C, D → B » et que « DF10 : C, E → A » peut être
remplacée par « DF02 : C → A ».
104
SGBD relationnels – Tome 1, État de l’art
3ème étape :
En répétant la même chose pour les autres DF tout en tenant compte chaque
fois des DF déjà supprimées, on arrive à la conclusion que « DF04’ : C, D →
B », et « DF09 : C, G → D » peuvent être supprimées.
Pour ce faire, cette décomposition doit se faire, soit en s’appuyant sur une
dépendance fonctionnelle et sur le théorème de la décomposition, soit en
s’appuyant sur la règle pour la préservation des dépendances
fonctionnelles ci-après :
105
Joachim TANKOANO
Le théorème de la décomposition
106
SGBD relationnels – Tome 1, État de l’art
d’attributs.
a) Définition
Si « (xi, yi, zi) » désigne les valeurs d’un tuple « ti » de « R (X, Y, Z) », on dit
de façon équivalente que « X » multi-détermine « Y » si :
{(x1, y1, z1), (x1, y2, z2)} R (X, Y, Z)
{(x1, y1, z2), (x1, y2, z1)} R (X, Y, Z)).
107
Joachim TANKOANO
NoPilote NoAvion VD VA
10 100 Ouagadougou Paris
10 101 Ouagadougou Paris
11 102 Ouagadougou Dakar
12 103 Cotonou Paris
11 100 Ouagadougou Dakar
10 100 Paris Lomé
10 101 Paris Lomé
11 100 Dakar Ouagadougou
11 102 Dakar Ouagadougou
11 100 Dakar Abidjan
11 102 Dakar Abidjan
108
SGBD relationnels – Tome 1, État de l’art
S’il faut supprimer le tuple « (10, 100, Ouagadougou, Paris) » parce que le
pilote « 10 » n’effectue plus le trajet « (Ouagadougou, Paris) » avec l’avion
« 100 », il faut aussi supprimer le tuple « (10, 101, Ouagadougou, Paris) »
pour que la contrainte d’intégrité soit maintenue. Ce qui correspond à une
anomalie de suppression.
Soient :
• « R (A) » une relation où « A » désigne l’ensemble de ses attributs,
• « W, X, Y, Z » des sous-ensembles de « A ».
La réflexivité
Si « Y X » alors X - Y.
La complémentarité
L’augmentation
X - Y et V W X, W - Y, V.
La transitivité
109
Joachim TANKOANO
d) Le théorème de la décomposition
110
SGBD relationnels – Tome 1, État de l’art
a) Définition
On dit qu’il existe dans « R (A) » une dépendance de jointure (DJ) notée «
(X1, X2, …, Xk) », où « » désigne l’opérateur de jointure naturelle, si « R
111
Joachim TANKOANO
112
SGBD relationnels – Tome 1, État de l’art
c) Le théorème de la décomposition
113
Joachim TANKOANO
10 Ouagadougou Paris
TrajetsAvions = (NoAvion, VD, VA) (Vols)
NoAvion VD VA
100 Ouagadougou Paris
100 Paris Ouagadougou
101 Ouagadougou Paris
▀
a) Définition
Une relation est dite normalisée ou en 1ère forme normale, si aucun de ses
attributs n’est ni un agrégat (c'est-à-dire un attribut à valeurs composées),
114
SGBD relationnels – Tome 1, État de l’art
Une relation en 1ère forme normale est une relation pour laquelle la seule
restriction qu’on lui impose est d’être conforme à la définition formelle
d’une relation, c'est-à-dire, être un sous-ensemble du produit cartésien de « n »
ensembles de valeurs atomiques. Une relation en 1ère forme normale peut
comporter tous les types de situations pouvant engendrer des redondances
et des anomalies de stockage.
115
Joachim TANKOANO
Une relation non normalisée peut être mise en 1ère forme normale :
• En remplaçant récursivement, dans chaque tuple de relation, chaque
valeur d’attribut à valeurs composées par les valeurs plus
élémentaires qui résultent de sa décomposition
• En répliquant récursivement chaque tuple de relation contenant une
relation imbriquée en autant de tuples qu’il y a de tuples dans cette
relation imbriquée, et en désimbriquant cette relation imbriquée
dans les tuples qui résultent de la réplication.
Dans les deux cas, la relation obtenue après mise en 1ère forme normale
contient les mêmes informations que la relation initiale.
116
SGBD relationnels – Tome 1, État de l’art
a) Définition
Une relation est en 2ème forme normale si elle est en 1ère forme normale et si
tous les attributs non-clés dépendent de sa clé primaire par une dépendance
fonctionnelle élémentaire, ce qui revient à dire que tous les attributs non-
clés dépendent de cette clé primaire par une dépendance fonctionnelle
irréductible à gauche ou totale.
On ne peut pas ajouter des informations sur un nouveau produit sans les
117
Joachim TANKOANO
La mise en 2ème forme normale d’une relation « R (a, b, c, d) », qui est en 1ère
forme normale et qui est contrainte par une dépendance fonctionnelle « b
→ d » qui fait que cette relation n’est pas en 2ème forme normale, s’effectue
en décomposant « R (a, b, c, d) » en « R’ (b, d) = (b, d) (R) » et « R’’ (a, b,
c) = (a, b, c) (R) » par application du théorème de la décomposition.
Cette mise en 2ème forme normale permet d’éviter les redondances et les
anomalies de stockage qui caractérisent les relations qui sont en 1ère forme
normale sans être en 2ème forme normale.
118
SGBD relationnels – Tome 1, État de l’art
a) Définition
Une relation est en 3ème forme normale si elle est en 2ème forme normale et
si tous les attributs qui ne sont pas dans sa clé primaire sont directement
dépendants de cette clé primaire, ce qui revient à dire que dans cette
relation aucun attribut non-clé ne dépend d’un autre attribut non-clé, ou
qu’il n’existe pas dans cette relation une dépendance transitive.
119
Joachim TANKOANO
NoAvion » qui fait que dans cette relation, un attribut non-clé dépend d’un
autre attribut non-clé. Comme pour toutes les autres relations qui sont en
2ème forme normale sans être en 3ème forme normale, on peut constater que
l’extension légale ci-après de cette relation comporte toutes les anomalies
parce que le déterminant de la dépendance fonctionnelle « NoPilote →
NoAvion » qui fait que cette relation n’est pas en 3ème forme normale n’est
pas une clé candidate.
On ne peut pas ajouter des informations sur un nouveau pilote sans créer
un nouveau vol.
La mise en 3ème forme normale d’une relation « R (a, b, c) », qui est en 2ème
forme normale et qui est contrainte par la dépendance fonctionnelle « b →
c » qui fait que cette relation n’est pas en 3ème forme normale, s’effectue en
décomposant « R (a, b, c) » en « R’ (b, c) = (b, c) (R) » et « R’’ (a, b) = (a, b)
(R) » par application du théorème de la décomposition.
Cette mise en 3ème forme normale permet d’éviter les redondances et les
120
SGBD relationnels – Tome 1, État de l’art
anomalies de stockage qui caractérisent les relations qui sont en 2ème forme
normale sans être en 3ème forme normale.
a) Définition
121
Joachim TANKOANO
pour toutes les autres relations qui sont en 3ème forme normale sans être en
forme normale de BOYCE-CODD, on peut constater que l’extension légale
ci-après de cette relation comporte toutes les anomalies parce que la
dépendance fonctionnelle « NoPilote → JourVol » qui fait que cette
relation n’est pas en forme normale de BOYCE-CODD a un déterminant
qui n’est pas une clé candidate :
On ne peut pas ajouter des informations sur un nouveau pilote sans créer
un nouveau vol.
122
SGBD relationnels – Tome 1, État de l’art
Par ailleurs, lorsqu’une relation en 3ème forme normale n’est pas en forme
normale de BOYCE-CODD, sa mise en forme normale de BOYCE-CODD a
comme conséquence la perte d’une dépendance fonctionnelle, ce qui ne
permet plus de garantir le respect de la règle de gestion que cette
123
Joachim TANKOANO
Nous sommes donc ici face à un dilemme, car conserver la relation « Vols
(NoVol, JourVol, NoPilote) » en 3ème forme normale tout comme la mettre
en forme normale de BOYCE-CODD a une conséquence indésirable sur
l’intégrité des données.
124
SGBD relationnels – Tome 1, État de l’art
a) Définition
NoPilote NoAvion VD VA
125
Joachim TANKOANO
Comme pour toutes les autres relations qui sont en forme normale de
BOYCE-CODD sans être en 4ème forme normale, on peut constater que
l’extension légale ci-dessus de cette relation comporte toutes les anomalies
parce que le déterminant de la dépendance multivaluée « NoPilote - VD,
VA » qui fait que cette relation n’est pas en 4ème forme normale n’est pas
une clé candidate.
La mise en 4ème forme normale d’une relation « R (a, b, c) », qui est en forme
normale de BOYCE-CODD et qui est contrainte par la dépendance
multivaluée « a - b » qui fait que cette relation n’est pas en 4ème forme
normale, s’effectue en décomposant « R (a, b, c) » en « R’ (a, b) = (a, b) (R)
» et « R’’ (a, c) = (a, c) (R) » par application du théorème de la
décomposition.
Cette mise en 4ème forme normale permet d’éviter les redondances et les
anomalies de stockage qui caractérisent les relations qui sont en forme
normale de BOYCE-CODD sans être en 4ème forme normale.
126
SGBD relationnels – Tome 1, État de l’art
a) Définition
Une relation en 4ème forme normale est en 5ème forme normale si pour
chaque dépendance de jointure « (X1, X2, …, Xk) » dans cette relation,
chacun des « Xi » est une surclé d’une clé candidate de la relation.
127
Joachim TANKOANO
NoPilote NoAvion VD VA
La mise en 5ème forme normale d’une relation « R (a, b, c) », qui est en 4ème
forme normale et qui est contrainte par la dépendance de jointure « ({a,
b}, {a, c}, {b, c}) » qui fait que cette relation n’est pas en 5ème forme normale,
s’effectue en décomposant « R (a, b, c) » en « R’ (a, b) = (a, b) (R) », « R’’ (a,
c) = (a, c) (R) » et « R’’’ (b, c) = (b, c) (R) » par application du théorème de
la décomposition.
Cette mise en 5ème forme normale permet d’éviter toute redondance et toute
anomalie de stockage.
128
SGBD relationnels – Tome 1, État de l’art
11 100
10 100
10 101
TrajetsPilotes = (NoPilote, VD, VA) (Vols)
NoPilote VD VA
11 Ouagadougou Paris
10 Paris Ouagadougou
10 Ouagadougou Paris
TrajetsAvions = (NoAvion, VD, VA) (Vols)
NoAvion VD VA
129
Joachim TANKOANO
Un bon schéma logique relationnel est celui qui possède les propriétés ci-
après :
• Les relations qui le composent ne peuvent pas contenir de données
redondantes
• Ces relations n’ont pas été excessivement décomposées et sont de ce
fait pertinentes par rapport aux problèmes à résoudre. En général,
chaque relation doit regrouper des informations sur des entités du
monde réel de même nature ou sur des associations de même nature
entre ces entités
• La décomposition en plusieurs relations a été sans perte
d’information parce qu’elle a été effectuée par projection en
s’appuyant sur des dépendances entre attributs
• La décomposition en plusieurs relations n’a pas non plus induit des
pertes de dépendances fonctionnelles, multivaluées ou de jointure,
130
SGBD relationnels – Tome 1, État de l’art
Dans ces approches, les concepts proposés par le modèle relationnel sont
utilisés pour conduire l’analyse des besoins qui doit précéder la mise en
place de la base de données. L’analyse à l’aide de ces concepts doit conduire
à l’identification des attributs de ce système d’information qui découlent
des besoins des utilisateurs et à l’identification des dépendances qui
doivent exister entre ces attributs qui elles doivent découler des règles de
gestion de l’entreprise concernée. Ces concepts sont ensuite utilisés pour
déterminer, sur cette base, le meilleur schéma logique relationnel à même
de garantir le respect des dépendances identifiées tout en évitant les
redondances et les anomalies de stockage associées.
Ces concepts sont de très bas niveau pour la conduite de la première phase
de ce processus, visant l’identification des attributs et des dépendances
entre attributs, car ils amènent le concepteur à se focaliser beaucoup plus
131
Joachim TANKOANO
sur les propriétés formelles des dépendances identifiées entre attributs que
sur la perception des utilisateurs et la sémantique des attributs et des
dépendances. De ce fait, ces concepts ne permettent pas, lors d’une analyse,
un haut niveau d’abstraction. Il n’est pas aisé, de ce fait, de faire lors de cette
analyse l’inventaire des attributs et des dépendances sans en oublier.
En contrepartie, ces concepts sont très bien adaptés pour la deuxième phase
du processus, visant la détermination du meilleur schéma relationnel à
même de garantir le respect des dépendances identifiées tout en évitant les
redondances et les anomalies de stockage associées. Ces concepts
permettent des analyses fines et rigoureuses des propriétés du système
d’information et du schéma logique relationnel de sa base de données,
basées sur des raisonnements formels. Certains aspects difficiles à
déterminer de façon intuitive peuvent être déduits de façon formelle grâce
à ces analyses. Par exemple, étant donné un ensemble de dépendances
auxquelles les extensions des relations d’une base de données sont
contraintes, il est possible de déterminer formellement les dépendances
élémentaires, la couverture minimale de cet ensemble de dépendances, les
clés candidates des relations, les redondances possibles dans les extensions
de ces relations, la forme normale de chaque relation, etc. En somme, pour
la phase de conception, ces concepts permettent de définir de véritables
techniques d’ingénierie du schéma logique relationnel d’une base de
données basées sur des procédés automatisables.
132
SGBD relationnels – Tome 1, État de l’art
133
Joachim TANKOANO
Les deux méthodes présentées ici prennent en entrée une relation et les
dépendances qui doivent être maintenues entre les attributs dans toute
extension légale de cette relation. Cette relation peut être une abstraction
d’un système d’information. Dans ce cas, on parle de relation universelle.
Cette relation peut aussi être qu’une abstraction d’un sous-ensemble
cohérent du système d’information ou d’un objet complexe dans l’univers
étudié.
134
SGBD relationnels – Tome 1, État de l’art
Cette méthode n’est donc pas recommandable pour une application réelle.
135
Joachim TANKOANO
136
SGBD relationnels – Tome 1, État de l’art
137
Joachim TANKOANO
R2 (A, C, D)
▀
Nous avons aussi montré que sur cette base, cette relation « R (A, B, C, D,
E, F, G) » a comme clé primaire « B, G ».
138
SGBD relationnels – Tome 1, État de l’art
À partir de ces résultats, on peut déduire que dans une extension légale de
la relation « Pièces (NoPièce, PrixUnit, TVA, Libellé, Catégorie) », un
couple de valeurs de « {Catégorie, TVA} » peut se répéter plusieurs fois et
engendrer ainsi des redondances, parce que dans la dépendance
fonctionnelle « Catégorie → TVA », l’attribut « Catégorie » n’est pas une
clé candidate.
139
Joachim TANKOANO
140
SGBD relationnels – Tome 1, État de l’art
141
Joachim TANKOANO
142
SGBD relationnels – Tome 1, État de l’art
143
Joachim TANKOANO
144
SGBD relationnels – Tome 1, État de l’art
145
Joachim TANKOANO
On peut noter que dans le schéma logique relationnel qui en résulte, les
contraintes d’intégrité exprimées par les dépendances fonctionnelles
identifiées dans le système d’information sont garanties à l’aide de clés
primaires et de clés étrangères.
▀
146
SGBD relationnels – Tome 1, État de l’art
BIBLIOGRAPHIE
Amstrong W.W.: Dependency Structures of Database Relationships -
IFIP World Congress, North-Holland Ed., p. 580-583, 1974.
Beeri C., Fagin R., & Howard J. H.: A Complete Axiomatization for
Functional and Multi-Valued Dependencies in Database Relations
- Proc. A CM SIGMOD 1977 Int. Conf. on Management of Data (Los
Angeles, 1977).
147
Joachim TANKOANO
415.
MIRANDA S. & BUSTA J-M. : L'art des bases de données, Tome 2, Les
bases de données relationnelles - 2è édition, Eyrolles, 1990
148
Chapitre 4. : Présentation du langage SQL
4.1. Introduction
Le rôle, les origines et les évolutions successives du langage SQL
150
SGBD relationnels – Tome 1, État de l’art
Toutefois, en tant que langage prédicatif relationnel, SQL n’inclut pas les
symboles de prédicats du type « R (t) » dont la valeur de vérité est « vraie »
si « t » est un tuple de la relation « R », pouvant servir à définir une relation
comme étant constituée de propositions qui vérifient ce prédicat. Ceci a
comme conséquence que SQL ne permet pas, sous sa forme prédicative,
d’effectuer l’union de deux relations. Pour effectuer cette opération à l’aide
de SQL, il faut obligatoirement utiliser l’opérateur algébrique « UNION »
qu’il propose.
Tout ceci, ajouté aux écarts par rapport au modèle relationnel de E.F. CODD
151
Joachim TANKOANO
La prise en compte par SQL des contraintes d’intégrité découlant des règles
de gestion de l’entreprise
Comme nous l’avons déjà indiqué, les contraintes d’intégrité d’une base de
données relationnelle, découlant des règles de gestion de l’entreprise,
concernent principalement :
• Le domaine de définition des valeurs légales de chaque attribut
• La non-nullité de ces attributs
• Les dépendances entre attributs
• Les autres invariants, définis par un prédicat, qui lient les valeurs de
groupes d’attributs ou des dépendances entre attributs.
152
SGBD relationnels – Tome 1, État de l’art
153
Joachim TANKOANO
Le contenu du chapitre
154
SGBD relationnels – Tome 1, État de l’art
Comme les relations, une table peut être définie par une « clé primaire »,
des « clés uniques » et des « clés étrangères », sur la base desquelles des
contraintes d’intégrité peuvent être déduites et garanties par le SGBD.
155
Joachim TANKOANO
a) Syntaxe de l’ordre
156
SGBD relationnels – Tome 1, État de l’art
(1) Cette syntaxe indique qu’un ordre SELECT peut être constitué de
plusieurs clauses, les deux premières étant obligatoires et les autres
facultatives.
Exemple 4.3.1.i : En considérant les trois tables relatives aux vols d’une
compagnie aérienne introduites dans la section 2.3.3, si le raisonnement se
fait dans la logique du 1er ordre, l’ordre SQL ci-après peut s’interpréter
comme voulant dire que « chaque ligne du résultat doit être une valeur de la
colonne « NoPilote » d’une ligne « v » de la table « Vols » ».
157
Joachim TANKOANO
SELECT v.NoPilote
FROM Vols v ;
Cet ordre peut aussi s’interpréter comme voulant dire : « faire une projection
de la table « Vols » sur la colonne « NoPilote » ».
Exemple 4.3.1.ii : De même, l’ordre SQL qui suit peut s’interpréter dans la
logique du 1er ordre comme voulant dire que « chaque ligne du résultat doit
être constituée d’une valeur de la colonne « NomPilote » d’une ligne « p » de la
table « Pilotes » et d’une valeur de la colonne « VA » d’une ligne « v » de la table
« Vols » qui vérifient le prédicat suivant : la valeur de la colonne « NoPilote » de
la ligne « v » de la table « Vols » et la valeur de la colonne « NoPilote » de la ligne
« p » de la table « Pilotes » doivent être identiques » et la valeur de la colonne
« VD » de la ligne « v » de la table « Vols » doit être « OUGADOUGOU ». » :
158
SGBD relationnels – Tome 1, État de l’art
(6) Enfin, la syntaxe d’un ordre SELECT indique qu’il est aussi possible
d’effectuer l’union, l’intersection ou la différence du résultat de deux ordres
SELECT en utilisant les opérateurs algébriques relationnels « UNION »,
« INTERSECT » et « MINUS ».
Ce qui suit présente de façon plus détaillée les possibilités offertes par ces
différentes clauses.
b) La clause FROM
Les tables qui doivent être utilisées comme sources pour l’exécution d’un
ordre SELECT doivent être mentionnées dans sa clause « FROM » en
159
Joachim TANKOANO
Exemple 4.3.1.iii : On peut écrire ce qui suit, pour dire que les tables qui
doivent être utilisées pour l’exécution d’un ordre SELECT sont, la table
« Avions » et la table « Vols » restreinte aux lignes où la valeur de la
colonne « VA » est « OUAGADOUGOU » :
FROM Avions, (SELECT * FROM Vols WHERE VA = 'OUAGADOUGOU')
▀
(2) En outre, il est possible comme dans l’exemple qui suit, d’associer à
chaque source un alias de table, qui est en général un pseudonyme plus
court qu’on peut utiliser en lieu et place du nom de la source.
Exemple 4.3.1.iv :
FROM Avions a,
(SELECT * FROM Vols WHERE VA = 'OUAGADOUGOU') v
▀
c) La clause SELECT
160
SGBD relationnels – Tome 1, État de l’art
Exemple 4.3.1.v : L’ordre qui suit produit ainsi un tableau où les colonnes
sont les mêmes que celles de la table « Avions ».
SELECT *
FROM Avions ;
▀
SELECT v.*
FROM Avions a, Vols v ;
▀
161
Joachim TANKOANO
Exemple 4.3.1.vii : L’ordre qui suit produit un tableau à deux colonnes où,
pour chaque ligne, la valeur de la 1ère colonne provient de la colonne
« NoAvion » d’une ligne de la table « Avions » alors que la valeur de la 2ème
colonne est le produit de la colonne « CapAvion » de cette ligne de la table
« Avions » avec la valeur 300000. En outre, le titre de la 1ère colonne de ce
tableau sera « NoAvion » et le titre de la 2ème colonne « Chiffre d’affaire ».
N.B. : Pour ce cas de figure et les autres cas qui précèdent, on peut dire que
les colonnes d’une ligne du résultat sont des « termes » tels que définis dans
la logique du 1er ordre. Chacun de ses termes est, soit une constante, soit un
symbole de variable qui désigne une valeur de la base de données, soit un
symbole de fonction définie par une expression qui calcule une nouvelle
valeur par composition de valeurs qui existent dans la base. Les SGBD
proposent un très grand nombre d’opérateurs et de fonctions prédéfinis,
applicables aux colonnes qui contiennent des nombres, des chaînes de
caractères ou des dates. Ces opérateurs et fonctions peuvent aussi s’utiliser
dans la clause « WHERE ». Leur existence, qui répond à l’une des dix
exigences définies par E.F. CODD, contribue grandement à la puissance du
langage et simplifie le travail des développeurs. Ces fonctions existent en
général pour différents domaines d’application (fonctions financières,
fonctions statistiques, fonctions trigonométriques, etc.). Les tableaux qui
suivent présentent succinctement quelques exemples d’opérateurs et de
fonctions ORACLE applicables aux nombres, aux chaines de caractères et
aux dates.
162
SGBD relationnels – Tome 1, État de l’art
163
Joachim TANKOANO
164
SGBD relationnels – Tome 1, État de l’art
Bien entendu, le résultat d’un ordre SELECT ne peut pas être constitué à la
fois de colonnes agrégées et de colonnes non agrégées.
Exemple 4.3.1.viii : L’ordre qui suit produit un tableau qui contient dans
chaque ligne, la valeur de la colonne « CapAvion » d’une ligne de la table
« Avions ».
SELECT a.CapAvion
FROM Avions a ;
L’ordre qui suit produit quant à lui un tableau qui contient une seule ligne
ayant une seule colonne qui contient la moyenne des valeurs contenues
dans la colonne « CapAvion » de la table « Avions ».
Enfin, on peut noter que les fonctions de groupe n’existent pas, de base,
dans le formalisme de la logique du 1er ordre, tel que présenté dans le
paragraphe 2.4.1. Elles reçoivent en paramètre un ensemble alors que les
fonctions n-aires de la logique du 1er ordre reçoivent en paramètre des
165
Joachim TANKOANO
valeurs atomiques.
Exemple 4.3.1.ix : L’ordre qui suit produit un tableau qui contient, pour
chaque ligne de la table « Avions », une ligne constituée de la valeur de la
colonne « NomAvion » et de la valeur de la colonne « CapAvion », en
faisant en sorte qu’il n’y ait pas de lignes identiques dans ce tableau.
d) La clause WHERE
166
SGBD relationnels – Tome 1, État de l’art
167
Joachim TANKOANO
Exemple 4.3.1.x : L’ordre qui suit produit un tableau qui contient toutes les
lignes de la table « Avions » où la colonne « NoAvion » contient 10, 20 ou
30. Le prédicat de comparaison ensembliste utilisé n’est vrai que si la valeur
de la colonne « NoAvion » dans une ligne de la table « Avions » est incluse
dans un ensemble donné de valeurs. Ce prédicat définit un critère de
sélection de lignes dans la table « Avions ».
SELECT *
FROM Avions
WHERE NoAvion IN (10, 20, 30) ;
▀
Exemple 4.3.1.xi : L’ordre qui suit produit un tableau qui contient toutes les
lignes de la table « Avions » où la colonne « CapAvion » contient la valeur
« NULL ». Le prédicat de comparaison utilisé compare la valeur de la
colonne « CapAvion » dans une ligne de la table « Avions » à la valeur
« NULL ». Ce prédicat définit un critère de sélection de lignes dans la table
« Avions ».
SELECT *
FROM Avions
WHERE CapAvion IS NULL ;
▀
Exemple 4.3.1.xii : L’ordre qui suit produit un tableau qui contient la liste
des avions dont le nom commence par 'AIRBUS' :
SELECT *
FROM Avions
WHERE NomAvion LIKE 'AIRBUS%' ;
168
SGBD relationnels – Tome 1, État de l’art
Exemple 4.3.1.xiii : L’ordre qui suit produit un tableau qui contient pour
chaque vol de la table « Vols », son numéro et le nom de l’avion utilisé pour
effectuer ce vol :
SELECT v.NoVol, a.NomAvion
FROM Vols v, Avions a
WHERE v.NoAvion = a.NoAvion ;
169
Joachim TANKOANO
Exemple 4.3.1.xv : L’ordre qui suit produit un tableau qui contient la liste
des avions conduits par le pilote n°2 :
SELECT a.*
FROM Avions a
WHERE a.NoAvion IN (SELECT v.NoAvion
FROM Vols v
WHERE v.NoPilote = 2) ;
Exemple 4.3.1.xvi : L’ordre qui suit produit un tableau qui contient la liste
des avions dont le numéro est supérieur à tous les numéros des avions
conduits par le pilote n°2 :
170
SGBD relationnels – Tome 1, État de l’art
SELECT a.*
FROM Avions a
WHERE a.NoAvion ALL (SELECT v.NoAvion
FROM Vols v
WHERE v.NoPilote = 2) ;
Exemple 4.3.1.xvii : L’ordre qui suit produit un tableau qui contient la liste
des numéros des pilotes qui conduisent plus d’un avion :
SELECT DISTINCT NoPilote
FROM Vols Vols_x
WHERE NoPilote IN (SELECT NoPilote
FROM Vols Vols_y
WHERE Vols_x.NoAvion Vols_y.NoAvion) ;
171
Joachim TANKOANO
Exemple 4.3.1.xviii : L’ordre qui suit produit un tableau qui contient la liste
des noms des pilotes qui sont en service.
SELECT NomPilote FROM Pilotes P
WHERE EXISTS (SELECT *
FROM Vols V
WHERE V.NoPilote = P.NoPilote) ;
172
SGBD relationnels – Tome 1, État de l’art
(3) Les jointures internes sont considérées comme étant les jointures par
défaut. Chaque ligne du résultat d’une jointure interne doit contenir les
colonnes de deux lignes qui vérifient cette condition de jointure.
(4) Les jointures naturelles sont des cas particuliers de jointures internes
où le prédicat de jointure est le test d’égalité sur les colonnes de même nom
qui existent dans les deux tables à joindre.
173
Joachim TANKOANO
Exemple 4.3.1.xix : Les deux requêtes qui suivent sont équivalentes. La 1ère
effectue une jointure interne et la 2ème une jointure naturelle. Les deux
requêtes spécifient explicitement une jointure (entre « Vols », « Pilotes » et
« Avions »), une sélection de lignes (sur « Vols ») et une projection (sur
« NoVol », « NomPilote » et « NomAvion »).
SELECT v.NoVol, p.NomPilote, a.NomAvion
FROM Vols v INNER JOIN Pilotes p ON v.NoPilote = p.NoPilote
JOIN Avions a ON v.Avion = a.NoAvion
WHERE v.VD = 'OUAGADOUGOU' ;
SELECT v.NoVol, p.NomPilote, a.NomAvion
FROM Vols v NATURAL JOIN Pilotes p
NATURAL JOIN Avions a
WHERE v.VD = 'OUAGADOUGOU' ;
▀
SQL offre la possibilité d’agréger les lignes du résultat d’un ordre SELECT,
au niveau de granularité souhaité, en utilisant conjointement les fonctions
de groupe, présentées dans le paragraphe c) de cette section, et les clauses
« GROUP BY » et « HAVING ».
174
SGBD relationnels – Tome 1, État de l’art
une seule ligne. Ensuite, la clause « HAVING » est appliquée aux lignes
agrégées, afin de sélectionner celles qui doivent être incluses dans le
résultat final.
Ainsi, la liste des colonnes du résultat spécifiée dans une clause « SELECT »
peut faire référence à des fonctions de groupe à appliquer à des colonnes
non citées dans la clause « GROUP BY ». Elle peut aussi faire référence à
toute ou partie des colonnes citées dans la clause « GROUP BY ».
Exemple 4.3.1.xx : L’ordre qui suit produit un tableau qui contient la liste
des types d’avions dans la table « Avions » en fournissant pour chaque type
d’avions la moyenne de la capacité des avions de ce type :
SELECT NomAvion, AVG (CapAvion) FROM Avions
GROUP BY NomAvion ;
▀
175
Joachim TANKOANO
Quant à l’ordre qui suit, il produit un tableau qui contient, les départements
où le salaire maximum est supérieur à 300 000, et pour chacun de ces
départements le salaire maximum :
SELECT DeptEmpl, MAX (SalEmpl)
FROM Personnel
GROUP BY DeptEmpl
HAVING MAX (SalEmpl) 300000 ;
▀
Telle que définie, il existe entre les lignes de cette table une relation
hiérarchique. Comme on peut le voir dans l’extension ci-dessous, cette
relation hiérarchique correspond à la relation hiérarchique qui existe entre
les employés de l’entreprise.
1 Jean Programmeur 7
2 Amadou Programmeur 6
3 Fati Programmeur 6
4 Francis Programmeur 7
5 Francine Programmeur 7
6 André Chef de projet 8
7 Marie Chef de projet 8
8 Bill Chef d’entreprise -
176
SGBD relationnels – Tome 1, État de l’art
Bill
André Marie
177
Joachim TANKOANO
178
SGBD relationnels – Tome 1, État de l’art
179
Joachim TANKOANO
Lorsque la clause « ORDER BY » est absente d’un ordre SELECT, les lignes
apparaissent dans le résultat dans un ordre quelconque qui peut changer
d’une exécution à une autre.
Cette clause entraine le tri des lignes du résultat par rapport à la 1ère colonne
spécifiée et en cas d’égalité par rapport à la 2ème colonne spécifiée, ainsi de
suite. Par défaut, les lignes sont triées selon un ordre croissant, en plaçant
les valeurs NULL en dernier et en commençant par :
• Les valeurs les plus petites, pour ce qui concerne les valeurs
numériques
• Les dates les plus anciennes, pour ce qui concerne les dates
• Les caractères ou les chaînes de caractères les plus petits dans l’ordre
alphabétique, pour ce qui concerne les caractères et les chaînes de
caractères.
N.B. Lorsque la clause « ORDER BY » est utilisée, elle doit être la dernière
clause de l’ordre SELECT.
180
SGBD relationnels – Tome 1, État de l’art
Exemple 4.3.1.xxvi : Soit la table définie par la relation Personnel (No, Nom,
Fonction, Salaire). L’ordre SELECT qui suit produit un résultat où les
lignes sont triées dans un ordre descendant selon la fonction et le salaire :
SELECT No, Nom, Fonction, Salaire
FROM Personnel
ORDER BY Fonction DESC, Salaire DESC ;
▀
181
Joachim TANKOANO
P(R1.a1, …, R1.an)(R1)
≡ SELECT R1.*
FROM R1
WHERE P(R1.a1, …, R1.an);
R1P(R1.a1, …, R1.an, R2.b1, …, R2.bn)R2
≡ SELECT R1.*, R2.*
FROM R1, R2
WHERE P(R1.a1, …, R1.an, R2.b1, …, R2.bn);
≡ SELECT R1.*, R2.*
FROM R1 INNER JOIN R2 ON P(R1.a1, …, R1.an, R2.b1, …,
R2.bn) ;
R1(a1, ...ai, b1, …, bj) ÷ R2(b1, …, bj)
≡ SELECT DISTINCT t1.a1, …, t1.ai
FROM R1 t1
WHERE NOT EXISTS
(SELECT t2.b1, …, t2.bj
FROM R2 t2
WHERE NOT EXISTS
(SELECT R1.*
FROM R1
WHERE (t1.a1, …, t1.ai, t2.b1, …, t2.bj)
IN (SELECT * FROM R1)));
Ceci montre que, tel que présenté dans cette section, l’ordre SELECT a le
pouvoir d’expression du langage algébrique relationnel. Bien entendu,
l’inverse n’est pas vrai, notamment à cause des extensions apportées au
langage SQL, telles les prédicats ensemblistes incluant des requêtes
imbriquées synchronisées, les fonctions de groupe et les clauses « GROUP
BY », « HAVING », « START WITH », « CONNECT BY ».
Cette section propose à titre d’exemples une formulation SQL des requêtes
formulées dans la section 2.4.5 en langage prédicatif en calcul relationnel à
variables n-uplets. Pour les requêtes prédicatives formulées en utilisant le
quantificateur « », les requêtes SQL équivalentes ont été formulées à
l’aide du quantificateur « EXISTS » en tenant compte de l’équivalence « x
182
SGBD relationnels – Tome 1, État de l’art
Exemple 4.3.2.i : Quels sont les numéros des pilotes en service et les villes d’arrivée
de leurs vols ?
{(v.NoPilote, v.VA) | Vols (v)}
SELECT v.NoPilote, v.VA
FROM Vols v ;
▀
Exemple 4.3.2.ii : Quels sont les numéros des vols au départ de Ouagadougou ?
{(v.NoVol) | Vols (v) (v.VD = 'Ouagadougou')}
SELECT v.NoVol
FROM Vols v
WHERE v.VD = 'Ouagadougou' ;
▀
Exemple 4.3.2.iii : Quels sont les noms des pilotes, autres qu’Amadou, qui
habitent Bobo-Dioulasso ?
{(p.NomPilote) | Pilotes (p) (p.NomPilote 'Amadou')
(p.AdrPilote = 'Bobo-Dioulasso')}
SELECT p.NomPilote
FROM Pilotes p
WHERE p.NomPilote 'Amadou' AND p.AdrPilote = 'Bobo-Dioulasso';
▀
Exemple 4.3.2.iv : Quels sont les numéros des pilotes, qui conduisent l’avion
numéro 104 et l’avion numéro 106 ?
{(v1.NoPilote) | Vols (v1) (v1.NoAvion = 104)
( v2 (Vols (v2) (v2.NoAvion = 106)
(v1.NoPilote = v2.NoPilote)))}
183
Joachim TANKOANO
SELECT v1.NoPilote
FROM Vols v1
WHERE v1.NoAvion = 104
AND EXISTS (SELECT * FROM Vols v2
WHERE v2.NoAvion = 106
AND v1.NoPilote = v2.NoPilote);
▀
Exemple 4.3.2.v : Pour chaque pilote en service, quels sont les numéros des avions
conduits, le numéro et le nom du pilote ?
{(p.NoPilote, p.NomPilote, v.NoAvion) | Vols (v) Pilotes (p)
(p.NoPilote = v.NoPilote)}
184
SGBD relationnels – Tome 1, État de l’art
Exemple 4.3.2.viii : Quels sont les numéros des pilotes qui conduisent tous les
avions de la compagnie ?
{(p.NoPilote) | Pilotes (p)
( a (Avions (a) ( v (Vols (v)
(v.NoPilote = p.NoPilote)
(v.Novion = a.NoAvion))))}
SELECT p.NoPilote
FROM Pilotes p
WHERE NOT EXISTS
(SELECT *
FROM Avions a
WHERE NOT EXISTS
(SELECT *
FROM Vols v
WHERE v.NoPilote = p.NoPilote
AND v.NoAvion = a.NoAvion));
185
Joachim TANKOANO
SELECT p.NoPilote
FROM Pilotes p
WHERE NOT EXISTS
(SELECT *
FROM Avions a
WHERE a.NomAvion = 'AIRBUS A310'
AND NOT EXISTS
(SELECT *
FROM Vols v
WHERE v.NoPilote = p.NoPilote
AND v.NoAvion = a.NoAvion));
▀
Exemple 4.3.2.x : Quels sont les numéros d’avions qui sont supérieurs à tous les
numéros des avions conduits par le pilote n° 2 ?
SELECT a.NoAvion
FROM Avions a
WHERE NOT EXISTS
(SELECT v.* FROM Vols v
WHERE v.NoPilote = 2 AND v.NoAvion = a.NoAvion) ;
186
SGBD relationnels – Tome 1, État de l’art
SELECT p.NomPilote
FROM Pilotes p
WHERE NOT EXISTS
(SELECT *
FROM Vols v
WHERE v.NoPilote = p.NoPilote
AND v.VD = 'Ouagadougou'));
▀
Exemple 4.3.2.xii : Quels sont les numéros des pilotes qui conduisent un avion
conduit par le pilote n° 32 ?
{(v1.NoPilote) | Vols (v1) (v1.NoPilote 32)
( v2 (Vols (v2) (v2.NoPilote = 32)
(v2.NoAvion = v1.NoAvion))}
187
Joachim TANKOANO
Exemple 4.3.2.xiv : Quelle est la capacité moyenne des avions par ville ainsi que
par type ?
SELECT a.LocAvion, a.NomAvion, AVG (a.CapAvion)
FROM Avions a
GROUP BY a.LocAvion, a.NomAvion ;
▀
Exemple 4.3.2.xv : Quels sont les avions dont la capacité est supérieure à toutes
les moyennes de capacité d’avion par ville ?
SELECT * FROM Avions a1
WHERE a1.CapAvion ALL (SELECT AVG(a2.CapAvion)
FROM Avions a2
GROUP BY a2.LocAvion) ;
▀
Exemple 4.3.2.xvi : Quels sont les vols (NoVol, VD, VA) en correspondance
directe ou indirecte au départ de Bobo-Dioulasso ?
SELECT v.NoVol, v.VD, v.VA FROM Vols v
START WITH v.VD = 'Bobo-Dioulasso'
CONNECT BY NOCYCLE PRIOR v.VA = v.VD;
▀
4.3.3. Exercice
188
SGBD relationnels – Tome 1, État de l’art
2) Quels sont les acteurs qui jouent dans tous les films produits par
« Idrissa OUEDRAOGO » ?
3) Quels sont les spectateurs qui aiment un film qu’ils n’ont pas vu ?
4) Quels sont les spectateurs qui aiment tous les films qu’ils ont vus ?
5) Quels sont les producteurs qui n’ont vu que les films qu’ils ont
produits ?
Dans la clause « INSERT INTO » d’un ordre INSERT, on peut, soit ne pas
citer, soit citer dans un ordre quelconque, les noms des colonnes des lignes
à insérer.
Lorsqu’on cite les noms des colonnes des lignes à insérer, on peut omettre
les noms des colonnes qui peuvent recevoir une valeur NULL ou une valeur
par défaut, au regard de la définition de la table de destination, si la valeur
de ces colonnes doit être la valeur NULL ou leur valeur par défaut.
Si les noms des colonnes de la ligne à insérer ne sont pas cités explicitement
dans la clause « INSERT INTO », la valeur de chaque colonne de cette ligne
doit être fournie explicitement dans le bon ordre dans la clause
« VALUES ».
189
Joachim TANKOANO
Les sous-requêtes qui retournent une seule ligne sont aussi autorisées dans
la clause « VALUES ».
Exemple 4.3.4.ii : L’ordre INSERT qui suit insert un avion qui a la même
localisation que l’avion dont le numéro est 20.
INSERT INTO Avions (NoAvion, NomAvion, LocAvion)
VALUES (50, 'BOING 707', (SELECT a.LocAvion FROM Avions a
WHERE a.NoAvion = 20)) ;
▀
190
SGBD relationnels – Tome 1, État de l’art
des lignes dans la table où les lignes doivent être insérées doivent être de
types compatibles.
Les valeurs utilisées pour modifier les colonnes des lignes concernées
peuvent être, soient données, soient calculées dynamiquement par une
expression, soient calculées dynamiquement par une sous-requête basée
sur d’autres tables.
Sur la base de cette syntaxe, on peut distinguer les deux grandes variantes
ci-après pour l’utilisation de cet ordre :
191
Joachim TANKOANO
a) La première variante
Exemple 4.3.5.i : L’ordre UPDATE qui suit affecte la valeur 500 à la colonne
« CapAvion » de la ligne de la table « Avions » où la colonne « NoAvion »
contient la valeur 40. En d’autres termes, elle affecte la valeur 500 à la
capacité de l’avion dont le numéro est 40.
UPDATE Avions
SET CapAvion = 500 WHERE NoAvion = 40 ;
▀
b) La deuxième variante
La syntaxe simplifiée de cette variante est schématisée par les deux sous-
variantes ci-après :
UPDATE Nom_table
SET (Nom_colonne, Nom_colonne, …) = (Sous_requête)
[WHERE Prédicat]
UPDATE Nom_table
SET Nom_colonne = (Sous_requête) [, Nom_colonne = (Sous_requête)] …
[WHERE Prédicat]
Dans cette variante, les valeurs utilisées pour modifier les colonnes sont
calculées dynamiquement par des sous-requêtes. Chaque sous-requête ne
doit retourner qu’une seule ligne.
192
SGBD relationnels – Tome 1, État de l’art
L’ordre DELETE supprime d’une table les lignes sélectionnées par sa clause
« WHERE ». Sa syntaxe simplifiée est la suivante :
DELETE [FROM] Nom_table [WHERE Prédicat] ;
193
Joachim TANKOANO
N.B. : L’ordre DELETE n’effectue pas une suppression physique des lignes
mais plutôt une suppression logique. Pour libérer l’espace occupé par les
lignes logiquement supprimées, il faut utiliser l’ordre TRUNCATE
présentée dans la section 4.4.
194
SGBD relationnels – Tome 1, État de l’art
Les métadonnées qui décrivent les objets définis dans les schémas
appartenant aux différents utilisateurs, sont centralisées dans un catalogue
appelé aussi dictionnaire de données, implémenté à l’aide d’une méta-
base, c'est-à-dire, d’une base de données de métadonnées. Cette méta-base
est un composant essentiel du SGBD. Elle est indispensable pour la gestion
des accès à ces objets qui se font sous le contrôle du SGBD et de façon plus
générale pour son fonctionnement. Les utilisateurs qui ont les droits requis
peuvent accéder à cette méta-base à l’aide de l’ordre SELECT, étant entendu
que cette méta-base est aussi une base de données relationnelle. En outre,
les outils et environnements d’aide au développement et les progiciels
peuvent eux aussi agir sur le contenu de cette méta-base en utilisant les
ordres du langage de définition des données, ce qui fait de cette méta-base
un élément structurant et central de ces produits.
195
Joachim TANKOANO
196
SGBD relationnels – Tome 1, État de l’art
Ce qui suit présente l’ordre CREATE TABLE pour la création d’une table
et de sa description logique, l’ordre ALTER TABLE pour la modification
de cette description, l’ordre TRUNCATE TABLE pour la suppression
physique des lignes d’une table et l’ordre DROP TABLE pour la
suppression de cette table et de sa description. Ces ordres, limités aux
fonctionnalités présentées, permettent de définir et de gérer la structure
logique d’une table ainsi que les contraintes d’intégrité associées à cette
table. Elles participent donc à la création et à la gestion du schéma logique
relationnel d’une base de données. Les ordres SQL qui permettent de
définir et de gérer les contraintes de confidentialité sont présentés dans le
paragraphe 4.4.5.
197
Joachim TANKOANO
(2) Chaque colonne de cette table doit être définie obligatoirement par
son nom et son type, et optionnellement par la valeur qu’elle prend par
défaut et par la contrainte d’intégrité de colonne qu’elle doit respecter. Des
contraintes d’intégrité de ligne, qui concernent en général plusieurs
colonnes d’une ligne, peuvent être définies en plus, indépendamment de
toute colonne.
198
SGBD relationnels – Tome 1, État de l’art
Type Signification
199
Joachim TANKOANO
200
SGBD relationnels – Tome 1, État de l’art
Les tables qui servent à stocker ces relations peuvent être créées à l’aide des
ordres ci-après :
CREATE TABLE Avions
(NoAvion NUMBER (5) PRIMARY KEY,
NomAvion VARCHAR2 (15) NOT NULL,
CapAvion NUMBER (4) DEFAULT NULL,
LocAvion VARCHAR2 (30) DEFAULT NULL) ;
201
Joachim TANKOANO
202
SGBD relationnels – Tome 1, État de l’art
203
Joachim TANKOANO
204
SGBD relationnels – Tome 1, État de l’art
Une vue est une table virtuelle (on dit aussi dérivée) qui n’a pas
d’existence réelle. Elle n’existe qu’à travers l’ordre « SELECT » qui lui est
associé pour le calcul de son contenu, chaque fois que de besoin, à l’aide de
tables qui ont une existence réelle. SQL donne la possibilité d’utiliser dans
un ordre « SELECT », « INSERT », « UPDATE » ou « DELETE » ces tables
virtuelles, comme s’il s’agissait de tables réelles, pour consulter ou pour
205
Joachim TANKOANO
modifier le contenu des tables réelles qui servent au calcul de leur contenu.
Le traitement d’une requête SQL sur une vue s’effectue en substituant tout
simplement le nom de cette vue par la sous-requête qui sert au calcul de
son contenu.
206
SGBD relationnels – Tome 1, État de l’art
Ce qui suit présente les ordres SQL qui permettent de créer, modifier et
supprimer une vue, les règles auxquelles sont soumises la manipulation
d’une vue à l’aide des ordres « DELETE », « UPDATE » et « INSERT »
ainsi que l’utilisation des vues pour la prise en compte des contraintes
d’intégrité qui ne peuvent pas être prises en compte dans la définition d’une
table réelle.
207
Joachim TANKOANO
(1) L’utilisation d’une vue dans une requête SQL est traitée comme s’il
s’agissait d’une table qui a comme contenu le résultat de l’exécution de la
sous-requête qui la définit.
(2) Lorsque des alias de colonnes sont spécifiés, leur nombre doit être
égal au nombre de colonnes du résultat de la sous-requête. Dans ce cas,
chaque nom d’alias définit le nom d’une colonne de la vue. Lorsque les
colonnes de la sous-requête sont spécifiées en utilisant l’option « * », la vue
doit être recréée chaque fois qu’une nouvelle colonne est ajoutée à l‘une des
tables à partir desquelles la vue est dérivée. Lorsque des noms d’alias ne
sont pas spécifiés, le SGBD déduit de la sous-requête, le nom de chaque
colonne de la vue.
(4) L’option « FORCE » permet de créer une vue même si les tables à
partir desquelles elle doit être dérivée n’existent pas encore, alors qu’avec
l’option « NO FORCE », la vue n’est créée que si ces tables existent déjà.
(6) Quant à la clause « WITH READ ONLY », elle rend non modifiables
les lignes visibles à travers une vue.
Exemple 4.4..3.i : Les deux ordres SQL ci-dessous sont équivalents. Ils créent
une vue qui ne contient que les avions AIRBUS. Le 1er ordre amène le SGBD
à déduire le nom de chaque colonne de cette vue à partir de la sous-requête
qui sert au calcul de son contenu. Dans le 2ème ordre, les noms des colonnes
208
SGBD relationnels – Tome 1, État de l’art
L’ordre « SELECT » qui suit affiche les numéros des avions « AIRBUS »
localisés à « OUAGADOUGOU » en s’appuyant sur la vue ainsi définie.
SELECT NoAvion
FROM AvionsAIRBUS
WHERE LocAvion = 'OUAGADOUGOU';
SELECT NoAvion
FROM Avions
WHERE NomAvion LIKE 'AIRBUS%' AND LocAvion = 'OUAGADOUGOU';
▀
La suppression d’une vue et des droits accordés sur cette vue se fait à l’aide
209
Joachim TANKOANO
Pour ce qui concerne les deux premières restrictions, on peut en effet noter
que les lignes qui existent dans cette table ne sont pas visibles dans la vue
qui ne contient que des lignes agrégées. Pour ce qui concerne la troisième
restriction, on peut aussi noter qu’aucune des lignes visibles dans la vue ne
peut se répéter, même si la table à partir de laquelle cette vue est dérivée
contient des lignes qui se répètent. De ce fait, la ligne qu’on veut supprimer
de la table peut ne pas être visible dans la vue.
210
SGBD relationnels – Tome 1, État de l’art
Règle n°3 : on ne peut ajouter aucune ligne dans la table à partir de laquelle
une vue est dérivée, si la définition de cette vue qui est utilisée pour accéder
à cette table :
1) Contient une des conditions restrictives des règles n° 1 et 2
2) Ne contient pas toutes les colonnes de la table définies avec la
contrainte d’intégrité « NOT NULL ».
La justification de la première restriction est la même que dans la règle n°2.
Pour ce qui concerne la deuxième restriction, on peut en effet noter que
dans la nouvelle ligne à insérer, la valeur d’une colonne non incluse dans la
vue qui a une contrainte d’intégrité « NOT NULL » ne peut pas être
déterminée.
N.B. : Il est aussi possible de manipuler une vue dérivée de plusieurs tables
(à l’aide des ordres « DELETE », « UPDATE » et « INSERT »). Dans ce cas,
la mise à jour de ces tables doit se faire à l’aide d’algorithmes spécifiques
conçus pour ce type de vues modifiables ou dans un déclencheur en
utilisant la clause « INSTEAD OF » comme expliqué dans la section 5.5.
211
Joachim TANKOANO
n’est pas une clé. En outre, le SGBD ne peut pas maintenir de façon
automatique la contrainte d’intégrité découlant de la dépendance
fonctionnelle « NoPilote → JourVol », parce que « NoPilote » n’est pas une
clé candidate.
Avions (NoAvion, NomAvion, CapAvion, LocAvion)
Pilotes (NoPilote, NomPilote, AdrPilote)
Vols (NoVol, JourVol, #NoPilote, #NoAvion, VD, VA)
L’utilisation des vues peut permettre dans les deux cas, de maintenir la
dépendance fonctionnelle qui ne peut pas l’être de façon automatique, afin
de garantir l’intégrité des données.
Pour ce faire, pour ce qui concerne le 1er schéma relationnel, pour garantir
de façon automatique le maintien de la dépendance fonctionnelle
« NoPilote → JourVol », sans toutefois éviter les redondances et les
anomalies de stockage, l’accès à la table « Vols » ne doit se faire qu’à travers
la vue « Vw_Vols_FNBC » définie comme ci-dessous.
212
SGBD relationnels – Tome 1, État de l’art
213
Joachim TANKOANO
Quant à la vue « Vw_ Pilotes_FNBC », elle doit être définie comme suit :
CREATE OR REPLACE VIEW Vw_Pilotes_FNBC
(NoPilote, JourVol, NomPilote, AdrPilote)
AS SELECT p1.NoPilote, p1.JourVol, p1.NomPilote, p1.AdrPilote
FROM Pilotes p1
WHERE NOT EXISTS
(SELECT *
FROM Vols v1
WHERE v1.NoPilote = p1.NoPilote
AND EXISTS
(SELECT *
FROM Vols v2, Pilotes p2
WHERE v2.NoPilote = p2.NoPilote
AND v1.NoPilote v2.NoPilote
AND v1.NoVol = v2.NoVol
AND p1.JourVol = p2.JourVol))
WITH CHECK OPTION ;
214
SGBD relationnels – Tome 1, État de l’art
Exemple 4.4.4.i : L’ordre qui suit crée un générateur des numéros d’avions,
qui commence par 1, incrémente les numéros générés par pas de 1, arrête la
génération des numéros à 100 sans la recommencer à 1 et n’effectue pas de
génération par anticipation dans la mémoire cache.
CREATE SEQUENCE Avions_NoAvion_Seq
INCREMENT BY 1
START WITH 1
MAXVALUE 100
NOCYCLE
NOCACHE;
▀
215
Joachim TANKOANO
[{CYCLE | NOCYCLE}]
[{CACHE n | NOCACH}]
[{ORDER | NOORDER}] ;
Comme nous l’avons vu dans ce qui précède, SQL est le seul langage
d’interface que l’utilisateur peut utiliser pour ses interactions avec un
SGBD relationnel. À travers ces interactions, l’utilisateur peut agir sur les
216
SGBD relationnels – Tome 1, État de l’art
La finalité de la gestion des droits d’accès est de fournir une garantie sur la
confidentialité des données en garantissant que les utilisateurs qui
exécutent ces opérations sont des utilisateurs légitimes, munis des
autorisations requises pour le faire. La gestion des droits d’accès rend aussi
possible la traçabilité des accès à une base de données.
Pour gérer les droits d’accès, les éditeurs des SGBD relationnels s’appuient
principalement sur quatre concepts :
• Le concept d’UTILISATEUR, pour désigner tout acteur pouvant
interagir avec le SGBD. Cet utilisateur peut être une application, un
acteur de l’entreprise, un objet connecté, ou tout autre acteur
• Le concept de SCHEMA, utilisé pour regrouper l’ensemble des
objets gérés par le SGBD qui appartiennent à un utilisateur donné
(tables, vues, index, procédures stockées, etc.)
• Le concept de PRIVILEGE, utilisé pour désigner un droit :
o Soit pour l’exécution d’un ordre SQL
o Soit pour l’exécution d’une opération métier implémentée
par une procédure ou par une fonction stockée
• Le concept de ROLE, utilisé pour définir un groupe nommé de
privilèges.
(1) Pour interagir avec le SGBD, l’utilisateur qui le fait doit avoir été créé
préalablement. Il doit donc être connu du SGBD et doit avoir un nom
217
Joachim TANKOANO
d’utilisateur et une clé d’accès au SGBD. Il doit aussi et surtout avoir tous
les privilèges dont il a besoin pour ses interactions avec le SGBD.
(2) Par défaut, chaque utilisateur possède tous les privilèges sur chacun
des objets qu’il a créés dans son schéma et peut donc exécuter toute
opération (ordre SQL ou appel d’une procédure ou d’une fonction stockée)
qui concerne ces objets. En revanche, un utilisateur « u1 » ne peut exécuter
une opération qui concerne un objet qui appartient à un autre utilisateur
« u2 » que si l’utilisateur « u2 », en fonction de ses exigences en matière de
confidentialité, a octroyé à cet utilisateur « u1 » le privilège dont il a besoin
pour exécuter cette opération.
218
SGBD relationnels – Tome 1, État de l’art
219
Joachim TANKOANO
(2) L’ordre ALTER USER permet en outre de spécifier, parmi les rôles
octroyés à un utilisateur, ceux qui doivent être activés lors de sa connexion
à la base de données (clause « DEFAULT ROLE »).
L’ordre DROP USER permet de supprimer un utilisateur ainsi que tous les
objets de son schéma. Sa syntaxe simplifiée est la suivante :
DROP USER Nom_utilisateur [CASCADE] ;
220
SGBD relationnels – Tome 1, État de l’art
• Les privilèges systèmes (ou globaux), associés aux ordres SQL qui ne
concernent pas un objet en particulier comme, « CREATE USER »,
« CREATE TABLE », « DROP ANY TABLE », etc. Il en existe une
centaine
• Les privilèges objets, associés aux opérations qui concernent un objet
en particulier d’un schéma. Le tableau ci-dessous liste quelques
exemples de privilèges objets relatifs aux tables, aux vues, aux
séquences et aux procédures et fonctions stockées.
ALTER X X
SELECT X X
INSERT X X
UPDATE X X
DELETE X X
REFRENCES X
INDEX X
EXECUTE X
Les ordres SQL qui servent à la gestion des autorisations d’accès à l’aide de
ces privilèges sont : CREATE ROLE, ALTER ROLE, DROP ROLE, SET
ROLE, GRANT et REVOKE. Ce qui suit présente ces ordres SQL.
221
Joachim TANKOANO
L’ordre GRANT permet d’octroyer des privilèges et/ou des rôles, à des
rôles ou à des utilisateurs. La syntaxe simplifiée de cet ordre est la suivante
lorsqu’il s’agit d’octroyer des privilèges systèmes ou des rôles :
GRANT {Privilège_système |Nom_rôle | ALL PRIVILEGES}[,..n]
TO {Nom_utilisateur |Nom_rôle |PUBLIC}[,..n] [WITH ADMIN OPTION] ;
222
SGBD relationnels – Tome 1, État de l’art
223
Joachim TANKOANO
pour activer de nouveaux rôles ou pour désactiver des rôles associés à cet
utilisateur. La syntaxe de cet ordre est la suivante :
SET ROLE {{Nom_rôle IDENTIFIED BY Mot_de_passe}[,..n]
| {ALL [EXCEPT {Nom_rôle}[,..n]
| NONE} ;
(2) Ne peuvent être activés ou réactivés à l’aide de cet ordre que les rôles
activables par mots de passe.
(3) L’option « ALL » permet d’activer les rôles accordés pour une
session.
224
SGBD relationnels – Tome 1, État de l’art
BD utilisateurs
225
Joachim TANKOANO
prédéfinies.
226
SGBD relationnels – Tome 1, État de l’art
BIBLIOGRAPHIE
ANSI-ISO: American National Standard for Information Systems: Database
Language SQL - American National Standards Institute (1986).
Bancilhon F. & Spyratos N.: Update Semantics and Relational Views - ACM
TODS, V4, N6, Dec. 1981, p. 557-575.
Date C.J.: A Critique of the SQL Database Language - ACM SIGMOD Record,
vol. 14, n° 3, novembre 1984.
Date C.J. & Darwen G.: A Guide to the SQL Standard, 4th edition - Addison
Wesley (1997).
Codd E. F.: The relational model for database management, Second Edition -
Addison-Wesley Publishing Company, Inc., 1990
Melton J. & Simon A. R.: Understanding the New SQL: A Complete Guide -
Morgan Kaufmann (1993).
ORACLE: Oracle® Database SQL Language Reference 12c Release 1 (12.1) - July
2017
227
Joachim TANKOANO
Shaw Ph.: Database Language Standards: Past, Present, and Future - Lecture
Notes in Computer Science, n° 466, Database Systems of the 90s, A.
Blaser Ed., Springer Verlag, novembre 1990.
Silberschatz A., Korth H.F. & Sudarshan S.: Database system concepts, sixth
edition - McGraw-Hill, 2011
228
Chapitre 5. : Extension de SQL en langage
complet de programmation (PL/SQL)
5.1 Introduction
Le développement de l’Internet a fortement influencé les traits
caractéristiques des applications d’entreprise qui manipulent une base de
données ainsi que leurs modèles de conception et de développement. Ces
applications sont devenues pour l’essentiel des applications réparties,
déployées dans des architectures multi-tiers constituées :
• De tiers clients où s’exécutent, éventuellement dans des
navigateurs, une partie plus ou moins importante du code de
l’application
• De tiers serveurs d’application où est réparti le code du cœur de
l’application
• De tiers serveurs de ressources où sont réparties les autres ressources
du système d’information de l’entreprise (serveurs de bases de
données, autres serveurs d’application, serveur de messagerie
d’entreprise, etc.).
230
SGBD relationnels – Tome 1, État de l’art
Des standards ont été définis pour ces trois types de composants mais aussi
pour leur environnement d’exécution. Ces standards amènent le
développeur à se concentrer sur les exigences fonctionnelles de
l’application et à laisser à l’environnement d’exécution la prise en charge
des exigences techniques (contrôle des autorisations d’accès, de l’exécution
des transactions, etc.).
231
Joachim TANKOANO
232
SGBD relationnels – Tome 1, État de l’art
233
Joachim TANKOANO
Ces blocs ont une structure générale identique qui est la suivante :
[DECLARE
Déclarations]
BEGIN
CorpsBloc
[EXCEPTION
CodeGestionDesErreurs]
END ;
(1) Un bloc est ainsi constitué de trois parties : une partie déclarative
(facultative) précédée dans la plupart des cas du mot clé « DECLARE », une
partie corps (obligatoire) précédée du mot clé « BEGIN » et une partie
gestion des erreurs (facultative) précédée du mot clé « EXCEPTION », le
tout se terminant par le mot clé « END ».
(2) La partie déclarative d’un bloc est réservée aux définitions et aux
déclarations de types, de constantes, de variables, de curseurs, de
procédures et de fonctions. La portée de ces définitions et déclarations est
le bloc. Elles sont visibles dans les procédures et fonctions du bloc, dans sa
partie corps et dans sa partie gestion des erreurs.
(3) La partie corps d’un bloc est réservée aux traitements assignés à ce
bloc. Ces traitements se définissent comme dans les autres langages de
programmation à l’aide d’instructions de contrôle de la logique
234
SGBD relationnels – Tome 1, État de l’art
(4) La partie corps d’un bloc peut contenir d’autres blocs appelés « blocs
imbriqués ». Dans un bloc, un bloc imbriqué est traité comme une macro-
instruction et peut apparaître partout où une instruction est autorisée. Les
déclarations d’un bloc sont visibles dans ses blocs imbriqués. En revanche,
les déclarations d’un bloc imbriqué sont invisibles dans son bloc parent et
dans les blocs imbriqués adjacents.
(5) La partie gestion des erreurs d’un bloc définit, quant à elle, le
traitement à effectuer pour chaque type d’erreur pouvant survenir au cours
de l’exécution des traitements définis dans sa partie corps.
235
Joachim TANKOANO
(2) Tous les types PL/SQL sont autorisés dans la déclaration d’une
constante ou d’une variable, à savoir, les types prédéfinis de SQL, les types
« BOOLEAN » et « BINARY_INTEGER » (aussi appelé
« PLS_INTEGER ») pour les entiers compris entre -2 147 483 648 et + 2 147
483 647, et les types définis par l’utilisateur stockés ou non dans le schéma
de la base de données, ce qui permet d’éviter les conflits d’impédance.
Exemple 5.2.1.i : Convenons pour plus de clarté que les noms de variables
commencent par le caractère « V », les noms de constantes par le caractère
« C » et les noms de tables par « Tab ». Dans ces exemples de déclarations,
la variable « V_Empl_ID » a le même type que la colonne « matricule » de
la table « Tab_Employes ». De même, la variable « V_Montant_min » a le
même type que la variable « V_Montant ».
DECLARE
V_Genre CHAR;
V_Compteur BINARY_INTEGER DEFAULT 0;
236
SGBD relationnels – Tome 1, État de l’art
V_Empl_ID Tab_Employes.matricule%TYPE ;
V_Montant NUMBER (12,2) ;
V_Montant_min V_Montant%TYPE;
C_TauxRemise CONSTANT NUMBER (3,2) := 0.06 ;
BEGIN
NULL;
END;
▀
237
Joachim TANKOANO
a) Le type « RECORD »
238
SGBD relationnels – Tome 1, État de l’art
V_Employe Tab_Employes%ROWTYPE ;
BEGIN
NULL ;
END ;
▀
(3) Lorsqu’une variable de ce type n’a pas encore été initialisée, elle a
comme valeur « EMPTY ».
Exemple 5.2.2.ii : Dans cet exemple, nous avons ajouté dans le type
« T_PERSONNE » un champ « Couleurs_preferees » de type tableau
associatif dynamique indexé par un entier.
DECLARE
TYPE T_COULEURS IS TABLE OF VARCHAR2 (15)
INDEX BY BINARY_INTEGER;
TYPE T_NOM IS RECORD (
Prenom VARCHAR2 (15),
Patronyme VARCHAR2 (15)
);
TYPE T_PERSONNE IS RECORD (
Nom T_NOM,
Adresse VARCHAR2 (50),
Sexe CHAR,
Couleurs_preferees T_COULEURS
239
Joachim TANKOANO
);
V_Personne T_PERSONNE ;
BEGIN
NULL ;
END ;
▀
c) Le type « VARRAY »
(3) Lorsqu’une variable de ce type n’a pas encore été initialisée, elle a
comme valeur « EMPTY ».
(1) Tout comme pour le type « VARRAY », il est aussi possible de créer
un type « NESTED TABLE » dans le schéma d’une base de données objet-
relationnelle et de l’utiliser pour typer l’attribut d’un objet ou la colonne
d’une table qui devient une colonne à valeurs relationnelles. Dans une ligne
240
SGBD relationnels – Tome 1, État de l’art
241
Joachim TANKOANO
242
SGBD relationnels – Tome 1, État de l’art
a) L’instruction « IF »
2ème variante
IF ExpressionBooléenne THEN
SéquenceInstructions
ELSE
SéquenceInstructions
END IF;
243
Joachim TANKOANO
3ème variante
IF ExpressionBooléenne THEN
SéquenceInstructions
ELSIF ExpressionBooléenne THEN
SéquenceInstructions
[ELSIF ExpressionBooléenne THEN
SéquenceInstructions] …
ELSE
SéquenceInstructions
END IF;
b) L’instruction « CASE »
2ème variante
CASE
WHEN ExpressionBooléenne1 THEN SéquenceInstructions1
WHEN ExpressionBooléenne2 THEN SéquenceInstructions2
……..
WHEN ExpressionBooléenneN THEN SéquenceInstructionsN
[ELSE
SéquenceInstructions]
END CASE ;
244
SGBD relationnels – Tome 1, État de l’art
c) L’instruction « LOOP »
Pour éviter une boucle infinie, l’arrêt et la sortie de la boucle peut être
provoquée par une instruction « EXIT [WHEN ExpressionBooléennen] » ou
« RAISE Exception », contenue dans « SéquenceInstructions ».
d) L’instruction « WHILE/LOOP »
e) L’instruction « FOR/LOOP »
Ces instructions font partie de celles qui sont spécifiques aux langages qui
étendent SQL en langage complet de programmation.
245
Joachim TANKOANO
Ce qui suit présente les extensions apportées de façon plus spécifique aux
ordres « SELECT », « INSERT » et « UPDATE » intégrés dans PL/SQL.
Des extensions additionnelles relatives aux ordres « UPDATE » et
« DELETE » sont présentées dans le paragraphe 5.2.7.b.
a) L’instruction « SELECT/INTO/FROM/WHERE »
246
SGBD relationnels – Tome 1, État de l’art
247
Joachim TANKOANO
« V_Matricule » et « V_Email ».
DECLARE
V_Matricule Tab_Employes.Matricule%TYPE;
V_Email Tab_Employes.Email%TYPE;
BEGIN
………..
SELECT e.Matricule, e.Email
INTO V_Matricule, V_Email
FROM T_Employes e
WHERE e.Matricule = 105 ;
………
END ;
▀
b) L’instruction « INSERT »
248
SGBD relationnels – Tome 1, État de l’art
Exemple 5.2.6.iv :
DECLARE
V_Employe Tab_Employes%ROWTYPE;
BEGIN
………..
INSERT INTO Tab_Employes VALUES V_Employe;
………
END;
▀
Exemple 5.2.6.v:
DECLARE
V_Employe Tab_Employes%ROWTYPE;
BEGIN
………..
UPDATE Tab_Employes e
SET ROW = V_Employe
WHERE e.Matricule = 105;
………
END;
▀
Un curseur est une zone privée utilisée sous forme de ressource par
PL/SQL pour stocker les informations relatives à l’exécution d’un ordre
SQL.
249
Joachim TANKOANO
250
SGBD relationnels – Tome 1, État de l’art
251
Joachim TANKOANO
Pour chaque session, PL/SQL crée tous les curseurs définis explicitement
par le développeur. Chaque fois que PL/SQL exécute dans une session une
requête du développeur (« OPEN », « CLOSE », « FETCH » ou « FETCH
BULK COLLECT ») relative à un curseur explicite, il le fait en utilisant la
zone privée créée pour ce curseur explicite pour le compte de cette session.
252
SGBD relationnels – Tome 1, État de l’art
NON
253
Joachim TANKOANO
1ère étape :
CURSOR NomCurseur [({NomParamètre}[,..n])]
RETURN TypeLignesRésultat ;
2ème étape :
CURSOR NomCurseur [({NomParamètre}[,..n])]
[RETURN TypeLignesRésultat]
IS OrdreSELECT [FOR UPDATE] ;
254
SGBD relationnels – Tome 1, État de l’art
255
Joachim TANKOANO
nouveau ;
256
SGBD relationnels – Tome 1, État de l’art
my_job_id Tab_Employes.job_id%TYPE;
my_sal Tab_Employes.salaire%TYPE;
BEGIN
OPEN c1;
LOOP
FETCH c1 INTO my_emp_id, my_job_id, my_sal ;
EXIT WHEN c1%NOTFOUND;
IF my_job_id = 'INFORMATICIEN' THEN
UPDATE Tab_employes e SET e.salaire = my_sal * 1.02
WHERE CURRENT OF c1;
END IF;
END LOOP;
END;
▀
Exemple 5.2.7.iv : Cet exemple fait la même chose que l’exemple précédent
en utilisant un curseur paramétré.
DECLARE
CURSOR c1 (job Tab_Employes.job_id%TYPE)
IS SELECT e.matricule, e.job_id, e.salaire
FROM Tab_Employes e
WHERE e.job_id = job
FOR UPDATE;
my_emp_id Tab_Employes.matricule%TYPE;
my_job_id Tab_Employes.job_id%TYPE;
my_sal Tab_Employes.salaire%TYPE;
BEGIN
OPEN c1 ('INFORMATICIEN');
LOOP
FETCH c1 INTO my_emp_id, my_job_id, my_sal;
EXIT WHEN c1%NOTFOUND;
UPDATE Tab_employes e
SET e.salaire = my_sal * 1.02
WHERE CURRENT OF c1;
END LOOP;
END;
▀
257
Joachim TANKOANO
Cette instruction dont l’objectif est de simplifier le traitement ligne par ligne
du résultat d’un ordre « SELECT », basé sur l’utilisation d’un curseur, a
comme effet la déclaration implicite de la variable
« NomVariableDeParcourt » qui doit avoir le même type que les lignes
retournées par l’ordre « SELECT » concernée, l’ouverture du curseur
spécifié, l’exécution à chaque itération d’un ordre « FETCH » qui place la
ligne suivante du résultat de l’ordre « SELECT » dans la variable
« NomVariableDeParcourt » et la fermeture du curseur à la fin de l’itération.
Une variable curseur est une variable qu’on peut faire pointer vers un
curseur explicite défini dynamiquement.
Les variables curseurs diversifient les possibilités offertes par les curseurs
explicites :
• Une variable curseur ne sert pas, comme dans le cas d’un curseur
explicite, qu’à l’exécution d’un seul ordre « SELECT ». Elle peut
servir à différents endroits et à différentes étapes d’un traitement, à
l’exécution d’ordres « SELECT » différents.
• Comme toute autre variable et contrairement à un curseur explicite,
une variable curseur peut faire l’objet d’une affectation de valeur.
Elle peut être utilisée dans une expression ou comme paramètre de
sous-programme. Elle peut être aussi une variable hôte.
258
SGBD relationnels – Tome 1, État de l’art
Une variable curseur faible est une variable curseur qui peut être utilisée
pour traiter des requêtes « SELECT » dont le type des lignes retournées
n’est pas fixé à l’avance et peut de ce fait être quelconque.
Une variable curseur faible peut être déclarée soit en utilisant le type
prédéfini « SYS_REFCURSOR », soit en utilisant un type « REF
CURSOR » faible, défini par le développeur.
La définition d’un type « REF CURSOR » faible définit son nom. La syntaxe
pour définir un type « REF CURSOR » faible est la suivante :
TYPE NomTypeCurseurFaible [IS] REF CURSOR ;
Exemple 5.2.8.i : Cet exemple explicite les deux approches qui en découlent
pour la déclaration d’une variable curseur faible « V_c1 » qui peut être
utilisée pour traiter des requêtes « SELECT » dont le type des lignes
retournées peut être quelconque.
259
Joachim TANKOANO
1ère approche :
DECLARE
V_c1 SYS_REFCURSOR;
BEGIN
NULL;
END;
2ème approche :
DECLARE
TYPE T_vc1 IS REF CURSOR;
V_c1 T_vc1 ;
BEGIN
NULL ;
END ;
▀
Une variable curseur forte est une variable curseur qui ne peut être utilisée
que pour traiter des requêtes « SELECT » dont le type des lignes retournées
correspond au type spécifié dans sa déclaration.
Une variable curseur forte ne peut être déclarée qu’en utilisant un type
« REF CURSOR » fort, défini par le développeur.
La définition d’un type « REF CURSOR » fort définit son nom ainsi que le
type des lignes qu’un ordre « SELECT » associé à une variable de ce type
doit retourner. La syntaxe pour définir un type « REF CURSOR » fort est
la suivante :
TYPE NomTypeCurseurFort
[IS] REF CURSOR RETURN NomTypeLignesRetournées ;
Exemple 5.2.8.ii : Cet exemple déclare une variable curseur « V_c1 » forte
qu’on ne peut utiliser que pour traiter les requêtes « SELECT » qui
retournent des lignes de type « Tab_Employes%ROWTYPE ».
260
SGBD relationnels – Tome 1, État de l’art
DECLARE
TYPE T_vc1 IS REF CURSOR RETURN Tab_Employes%ROWTYPE;
V_c1 T_vc1;
BEGIN
NULL ;
END;
▀
261
Joachim TANKOANO
On notera que dans les deux cas, les mises à jour sont effectuées à l’aide
d’un ordre « UPDATE » qui n’utilise pas la clause « WHERE CURRENT
OF » qui requiert la spécification d’un curseur et non d’une variable
curseur.
DECLARE
TYPE T_CurseurEmp IS REF CURSOR
RETURN Tab_Employes%ROWTYPE;
V_CurseurEmp T_CurseurEmp;
V_Employe Tab_Employes%ROWTYPE;
V_Req VARCHAR2 (100) :=
'SELECT *
FROM Tab_Employes e
WHERE e.job_id = "COMPTABLE"
FOR UPDATE';
BEGIN
OPEN V_CurseurEmp FOR
SELECT * FROM Tab_Employes FOR UPDATE;
LOOP
FETCH V_CurseurEmp INTO V_Employe;
EXIT WHEN V_CurseurEmp %NOTFOUND;
IF V_Employe. job_id = 'INFORMATICIEN' THEN
UPDATE Tab_employes e
SET e.salaire = V_Employe.salaire * 1.02
WHERE e.matricule = V_Employe.matricule;
END IF;
END LOOP;
CLOSE V_CurseurEmp;
OPEN V_CurseurEmp FOR V_Req;
LOOP
FETCH V_CurseurEmp INTO V_Employe;
EXIT WHEN V_CurseurEmp %NOTFOUND;
UPDATE Tab_employes e
SET e.salaire = V_Employe.salaire * 1.03
WHERE e.matricule = V_Employe.matricule;
262
SGBD relationnels – Tome 1, État de l’art
END LOOP;
CLOSE V_CurseurEmp;
COMMIT;
END;
▀
263
Joachim TANKOANO
264
SGBD relationnels – Tome 1, État de l’art
Lorsqu’il s’agit d’une exception sans nom concernant une anomalie interne,
le développeur doit en plus, dans la partie déclarative du bloc, associer ce
nom au numéro d’erreur de l’exception, attribué par PL/SQL, à l’aide de
l’instruction ci-après :
PRAGMA EXCEPTION_INIT (NomException, CodeErreur) ;
265
Joachim TANKOANO
266
SGBD relationnels – Tome 1, État de l’art
267
Joachim TANKOANO
EXCEPTION
……
WHEN NomException THEN CodeDeGestionAnomalie;
……
END;
DECLARE
……..
NomException EXCEPTION;
PRAGMA EXCEPTION_INIT (NomException, CodeErreur);
…….
BEGIN
…….
RAISE_APPLICATION_ERROR (CodeErreur, Message [,{TRUE
| FALSE}]);
……..
268
SGBD relationnels – Tome 1, État de l’art
EXCEPTION
……
WHEN NomException THEN CodeDeGestionAnomalie;
……
END;
269
Joachim TANKOANO
270
SGBD relationnels – Tome 1, État de l’art
271
Joachim TANKOANO
Ce qui suit aborde dans les grandes lignes quelques aspects relatifs à la
déclaration, à la définition et à l’appel des procédures et fonctions.
Quant à l’ordre SQL qui permet de créer une procédure stockée dans le
catalogue d’une base de données, sa syntaxe simplifiée est la suivante :
CREATE [OR REPLACE] PROCEDURE [NomSchéma.]CodePL_SQLProcédure ;
Dans les deux cas, la syntaxe simplifiée du code de la procédure est la même
et peut être définie comme suit :
CodePL_SQLProcédure ::= DéclarationProcédure | DéfinitionProcédure ;
DéclarationProcédure ::= NomProcédure
[({DéclarationParamètreProcédure}[,..n])]
[ACCESSIBLE BY
({[TypeUnitéTrait] NomUnitéTrait}[,..n])]
[AUTHID {{CURRENT USER} | DEFINER}]
272
SGBD relationnels – Tome 1, État de l’art
6) Comme pour les blocs anonymes, le bloc qui définit une procédure
est constitué d’une partie déclarative (facultative), d’une partie corps
(obligatoire) et d’une partie code de traitement des anomalies (facultative).
Alternativement, la définition du bloc d’une procédure stockée peut être
273
Joachim TANKOANO
constituée d’une spécification qui publie une procédure stockée Java ou une
procédure externe C, en fournissant les informations requises pour l’appel.
Exemple 5.3.1.i : Cet exemple déclare et définit dans un bloc anonyme une
procédure « augmenter_salaire () » qui permet d’augmenter le salaire de
l’employé dont le matricule est passé en paramètre d’un montant et d’une
prime passés également en paramètres. L’appel de cette procédure ne peut
se faire que dans le corps du bloc anonyme.
DECLARE
PROCEDURE augmenter_salaire (
P_matricule IN Tab_Employes.matricule%TYPE,
P_montant IN Tab_Employes.salaire%TYPE,
P_prime IN Tab_Employes.salaire%TYPE
)
IS
BEGIN
UPDATE Tab_employes e
SET e.salaire = e.salaire + P_montant + P_prime
WHERE e.matricule = P_matricule ;
END ;
BEGIN
NULL ;
END ;
▀
Exemple 5.3.1.ii : Cet exemple crée la procédure « augmenter_salaire () » de
l’exemple précédant sous forme de procédure stockée dans le schéma de
l’utilisateur courant. Cette procédure peut être appelée par des applications
qui s’exécutent au niveau d’un poste client, au niveau du serveur
d’application ou au niveau du serveur de la base de données, auxquelles le
privilège « EXECUTE » de la procédure a été accordé. Au cours d’une
exécution de cette procédure, le propriétaire sera considéré comme étant
l’utilisateur courant et son schéma comme étant le schéma courant.
274
SGBD relationnels – Tome 1, État de l’art
Quant à l’ordre SQL qui permet de créer une fonction stockée dans le
catalogue d’une base de données, sa syntaxe simplifiée est la suivante :
CREATE [OR REPLACE] FUNCTION [NomSchéma.]CodePL_SQLFonction ;
Dans les deux cas, la syntaxe simplifiée du code de la fonction est la même
et peut être définie comme suit :
CodePL_SQLFonction ::= DéclarationFonction | DéfinitionFonction;
DéclarationFonction ::= NomFonction
[({DéclarationParamètreFonction}[,..n])]
RETURN TypeRésutatFonction
[ACCESSIBLE BY
({[TypeUnitéTrait] NomUnitéTrait}[,..n])]
[AUTHID {{CURRENT USER} | DEFINER}]
DéclarationParamètreFonction ::= NomParamètre [IN | OUT | IN OUT]
TypeParamètre [ := Expression]
TypeUnitéTrait ::= {FUNCTION | PROCEDURE | PACKAGE | TRIGGER}
275
Joachim TANKOANO
Exemple 5.3.2.i : Cet exemple déclare et définit dans un bloc anonyme une
procédure « augmenter_salaire () » qui, en rappel, permet d’augmenter le
salaire de l’employé dont le matricule est passé en paramètre d’un montant
et d’une prime passés également en paramètres. Cette procédure est ensuite
276
SGBD relationnels – Tome 1, État de l’art
277
Joachim TANKOANO
RETURN V_nb_agents ;
END;
BEGIN
DBMS_OUTPUT.PUT_LINE
('Nombre agents chef 100 = ' || nb_agents_chef (100));
SELECT e.matricule, e.nom
FROM Tab_employes e
WHERE nb_agents_chef (e.matricule) > 5
END ;
▀
278
SGBD relationnels – Tome 1, État de l’art
BEGIN
-- Calcul du nombre total d’employés
SELECT COUNT (*) INTO v_nb_total_employes
FROM Tab_employes e ;
-- Calcul des primes dans la table Tab_primes_encadrement
INSERT INTO Tab_primes_encadrement
SELECT e.matricule_chef,
(P_budget_prime / (v_nb_total_employes – 1)) * COUNT (*)
FROM Tab_employes e
WHERE e.matricule_chef IS NOT NULL
GROUP BY e.matricule_chef;
END;
279
Joachim TANKOANO
END;
BEGIN
calculer_Top_Salaire (10);
END;
▀
La passerelle PL/SQL est un « listener HTTP ». Son rôle est de recevoir les
requêtes du navigateur, de transformer l’URL de chaque requête reçue en
instruction d’appel de la procédure ou de la fonction stockée spécifiée,
d’appeler cette procédure ou cette fonction et de retourner au navigateur le
résultat produit par cet appel.
280
SGBD relationnels – Tome 1, État de l’art
packages qui offrent des APIs que le développeur peut utiliser dans une
procédure ou fonction stockée pour traiter une requête « HTTP ».
281
Joachim TANKOANO
N.B. : Le module « mod_plsql » n’a pas été inclus par Oracle dans la version
12.1.3 et les versions suivantes du « serveur HTTP Oracle ». Pour ces
versions, Oracle recommande l’utilisation des services « Oracle REST
Data ».
282
SGBD relationnels – Tome 1, État de l’art
283
Joachim TANKOANO
« PSP » est un langage de script que le développeur peut utiliser pour coder
la génération dynamique, côté serveur, d’une page web en format
« HTML » à transmettre en retour à un navigateur. Comme pour les autres
langages de scripts côté serveur, les pages « PSP » peuvent s’écrire en
combinant « PL/SQL » (pour les parties dynamiques de la page) et d’autres
langages de script côté client comme « HTML », « CSS » et « JavaScript »
(pour les parties statiques de la page). Les pages « PSP » sont comparables
aux pages « JSP » où les scripts de génération dynamique de code sont
écrits en Java.
284
SGBD relationnels – Tome 1, État de l’art
285
Joachim TANKOANO
<head>
<meta http-equiv="Content-Type" content="text/html">
<title>Liste des employés</title>
</head>
<body TEXT="#000000" BGCOLOR="#FFFFFF">
<h1>Liste des employés</h1>
<table width="40%" border="1">
<tr>
<th align="left">Nom de famille</th>
<th align="left">Prénom</th>
</tr>
<% FOR V_Employe IN c1 LOOP %>
<tr>
<td> <%=V_Employe.patronyme%> </td>
<td> <%= V_Employe.prenom%> </td>
</tr>
<% END LOOP; %>
</table>
</body>
</html>
▀
Les packages sont compilés avant leur stockage dans une base de données
d’où plusieurs applications peuvent partager leur contenu.
286
SGBD relationnels – Tome 1, État de l’art
Les instances d’un package sont des instances de session. Chaque session
qui utilise un package possède sa propre instance de ce package. Cette
instance est créée et initialisée au cours d’une session par le moteur PL/SQL
pour la durée de la session lors de la première rencontre d’une référence à
un item de ce package.
287
Joachim TANKOANO
Ce qui suit présente la syntaxe des instructions proposées par Oracle pour
la création des packages ainsi qu’un exemple de création de package avant
d’aborder succinctement les packages offerts par Oracle.
288
SGBD relationnels – Tome 1, État de l’art
289
Joachim TANKOANO
Supposons par ailleurs que l’analyse des besoins des utilisateurs a fait
ressortir que l’application qui permettra l’exploitation de cette base de
données sera mise en œuvre par deux grands services : le service
exploitation et le service maintenance.
290
SGBD relationnels – Tome 1, État de l’art
291
Joachim TANKOANO
292
SGBD relationnels – Tome 1, État de l’art
-- du service exploitation
CREATE OR REPLACE PACKAGE BODY pkg_service_expl
AS
PROCEDURE CreerVol (
P_NoP NUMBER,
P_NoAvion NUMBER,
P_VD VARCHAR2,
P_VA VARCHAR2,
P_HD DATE,
P_HA DATE)
IS
BEGIN
INSERT INTO V_Vols
VALUES (SEQ_NoVol.NEXTVAL, P_NoP, P_NoAvion, P_VD, P_VA,
P_HD, P_HA);
END;
PROCEDURE SupprimerVol (P_NoV NUMBER)
IS
BEGIN
DELETE FROM V_Vols v WHERE v.NoVol = P_NoV;
END;
PROCEDURE ChangerPilote (P_NoV NUMBER, P_NoP NUMBER)
IS
BEGIN
UPDATE V_Vols v SET v.NoPilote = P_NoP
WHERE v.NoVol = P_NoV;
END;
PROCEDURE ModifierTrajet (
P_NoV NUMBER,
P_VD VARCHAR2,
P_VA VARCHAR2)
IS
BEGIN
UPDATE V_Vols v SET v.VD = P_VD, v.VA = P_VA
WHERE v.NoVol = P_NoV;
END;
293
Joachim TANKOANO
PROCEDURE ModifierHoraire (
P_NoV NUMBER,
P_HD VARCHAR2,
P_HA VARCHAR2)
IS
BEGIN
UPDATE V_Vols v SET v.HD = P_HD, v.HA = P_HA
WHERE v.NoVol = P_NoV;
END;
END pkg_service_expl;
294
SGBD relationnels – Tome 1, État de l’art
Ces packages PL/SQL sont livrés soit avec « Oracle Database Server », soit
avec « Oracle Developer », soit avec « Oracle Application server ».
295
Joachim TANKOANO
À titre d’exemples, on peut citer les quelques packages qui suivent qui
visent à faciliter le développement d’applications web :
• « APEX_CUSTOM_AUTH » : pour l’authentification et la gestion
des sessions ;
• « APEX_APPLICATION » : pour l’accès aux variables globales ;
• « APEX_ITEM » : pour la création de composants de formulaires ;
• « APEX_UTIL » : pour l’accès à l’état d’une session, aux
autorisations accordées à un utilisateur, …
• « HTF et HTP » : pour la génération d’un document HTML ;
• « DBMS_OUTPUT » : pour l’affichage de messages notamment lors
de la mise au point d’une unité de traitement.
296
SGBD relationnels – Tome 1, État de l’art
297
Joachim TANKOANO
• Le nombre de fois que le traitement doit être exécuté : une seule fois
pour chaque exécution de l’ordre déclencheur ou une fois pour
chaque ligne traitée par l’ordre déclencheur
• La condition qui doit éventuellement être vérifiée pour que le
déclenchement de l’exécution du traitement ait lieu.
298
SGBD relationnels – Tome 1, État de l’art
299
Joachim TANKOANO
300
SGBD relationnels – Tome 1, État de l’art
BIBLIOGRAPHIE
ANSI-ISO: ISO/IEC JTC 1/SC 32 Data management and interchange: ISO/IEC
9075:1992 Information technology — Database languages — SQL - Nov.
1992
Cocherane R., Pirahesh H. & Mattos N.: Integrating triggers and Declarative
Constraints in SQL Database Systems - Proc. 16th Intl. Conf. on Very
Large Data Bases, Brisbane, Australia, Morgan Kaufman Ed., p. 566-
577,
Date C.J. & Darwen G.: A Guide to the SQL Standard, 4th edition - Addison
Wesley (1997).
Melton J. & Simon A. R.: Understanding the New SQL: A Complete Guide -
Morgan Kaufmann (1993).
ORACLE: Oracle® Database PL/SQL Packages and Types Reference 12c Release
1 (12.1) - September 2016
Silberschatz A., Korth H.F. & Sudarshan S.: Database system concepts, sixth
edition - McGraw-Hill, 2011
301
Chapitre 6. : Connecteurs des bases de
données
6.1. Introduction
Comme nous venons de le voir dans le chapitre 5, la principale finalité de
l’approche qui consiste à étendre le langage SQL pour en faire un langage
complet de programmation est : aboutir à un langage qui permet l’écriture
d’unités de traitement pouvant s’intégrer dans une base de données où le
développeur peut la manipuler de la façon la plus simple et directe possible
à l’aide d’instructions intégrées nativement dans ce langage (soumission de
l’exécution de requêtes SQL au moteur SQL et récupération du résultat
pour traitement). Comme nous l’avons vu, ceci permet de répondre à de
multiples besoins spécifiques essentiels.
Par rapport à celle que nous avons étudiée dans le chapitre 5, cette approche
à l’avantage d’offrir au développeur d’une application à la fois une liberté
dans le choix du langage de programmation, une indépendance de ses
programmes par rapport à l’offre technologique utilisée pour
l’implémentation de la base de données et une transparence par rapport à
la localisation de cette base de données qui peut être locale ou distante. En
somme, il s’agit d’une approche qui facilite la portabilité des applications.
En contrepartie, cette approche rend plus complexe la manipulation d’une
base de données à l’intérieur d’un programme.
La très grande diversité des fonctions ou méthodes de l’API offert par les
connecteurs de base de données, induit une très grande complexité dans la
manipulation d’une base de données à l’intérieur d’un programme. Les
fournisseurs de technologies parviennent à réduire cette complexité grâce
aux approches ci-après :
• L’encapsulation de l’API du connecteur à l’aide d’une API de plus
haut niveau, offrant au développeur une interface plus simple pour
la manipulation d’une base de données, y compris la possibilité de
manipuler une base de données relationnelle comme s’il s’agissait
d’une base de données objets
303
Joachim TANKOANO
304
SGBD relationnels – Tome 1, État de l’art
305
Joachim TANKOANO
APPLICATION
API ODBC
306
SGBD relationnels – Tome 1, État de l’art
Le tableau qui suit donne à titre d’exemples quelques équivalences entre les
types ODBC et les types du langage C.
307
Joachim TANKOANO
Sur certains points, ces zones de travail sont comparables aux curseurs
PL/SQL.
308
SGBD relationnels – Tome 1, État de l’art
309
Joachim TANKOANO
310
SGBD relationnels – Tome 1, État de l’art
311
Joachim TANKOANO
Exemple 6.2.2.vii : L’appel de fonction qui suit indique que lors d’un appel
de la fonction « SQLFETCH », la 1ère colonne de la ligne courante du
résultat est une chaîne de caractères qui doit être placée dans la variable
« V_buffer » de 20 caractères de long.
V_err = SQLBindCol (V_hstmt, 1, SQL_C_CHAR, &V_buffer, 20, &V_errx);
▀
312
SGBD relationnels – Tome 1, État de l’art
313
Joachim TANKOANO
314
SGBD relationnels – Tome 1, État de l’art
Le connecteur JDBC offre une API orientée objet définie par les packages
« java.sql » et « javax.sql ». Ce connecteur est facile d’utilisation dans un
programme. Contrairement à ODBC, il ne nécessite aucune installation
préalable sur les postes clients. Le code requis est téléchargé
dynamiquement au moment de l’exécution à partir d’une source
centralisée. Il ne nécessite en outre aucune configuration préalable des
postes clients.
315
Joachim TANKOANO
Application
API JDBC
316
SGBD relationnels – Tome 1, État de l’art
• Les pilotes de type 3 : ces pilotes permettent l’accès à une source par
l’intermédiaire d’un serveur middleware de pilotes qui implémente
différents types de connecteurs
• Les pilotes de type 4 : ces pilotes permettent l’accès à une source en
exécutant directement les appels de l’API JDBC.
317
Joachim TANKOANO
318
SGBD relationnels – Tome 1, État de l’art
319
Joachim TANKOANO
vds.setDatabaseName ("ma_BD") ;
vds.setDescription (« Source de données stock produits ») ;
// Utilisation de l’API JNDI pour enregistrer l’objet pilote VendorDataSource
// en le liant au nom logique « jdbc/BDStock »
Context ctx = new InitialContext ();
ctx.bind ("jdbc/BDStock", vds);
▀
320
SGBD relationnels – Tome 1, État de l’art
321
Joachim TANKOANO
322
SGBD relationnels – Tome 1, État de l’art
323
Joachim TANKOANO
324
SGBD relationnels – Tome 1, État de l’art
Exemple 6.3.3.i : Le code Java qui suit crée un objet « Statement » dans la
variable « stmt » et appelle ensuite sa méthode « executeUpdate () » pour
325
Joachim TANKOANO
Exemple 6.3.3.ii : Le code Java qui suit crée un objet « Statement » dans la
variable « stmt » et appelle ensuite sa méthode « executeUpdate () » pour
soumettre à la source concernée l’exécution d’un ordre « UPDATE » qui
modifie à « 175 » la valeur de la colonne « CapAvion » de toutes les lignes
326
SGBD relationnels – Tome 1, État de l’art
327
Joachim TANKOANO
328
SGBD relationnels – Tome 1, État de l’art
Exemple 6.3.3.iii : Le code Java qui suit crée un objet « Statement » dans la
variable « stmt » et appelle ensuite sa méthode « executeQuery () » pour
soumettre l’exécution d’un ordre « SELECT » qui retourne le numéro et le
nom de chaque avion contenu dans la table « AirBurkina.Avions ». L’objet
« ResultSet », produit par cet appel avec les caractéristiques par défaut
dans la variable « rs », est ensuite utilisé pour parcourir le résultat qu’il
contient afin de l’afficher sur la console système.
// Création d’une connexion à une source et d’un objet « Connection »
// dans la variable « maConn » pour la gestion de cette connexion
Context ctx = new InitialContext ();
DataSource ds = (DataSource) ctx.lookup ("jdbc/BDAirBurkina");
Connection maConn = ds.getConnection ("user", "pwd") ;
// Création d’un objet « Statement » dans la variable « stmt » pour la soumission de
// l’exécution des ordres SQL non paramétrés à cette source
Statement stmt = maConn.createStatement () ;
// Soumission de l’exécution d’un ordre « SELECT » qui retourne toutes les lignes
329
Joachim TANKOANO
// de la table « AirBurkina.Avions »
rs = stmt.executeQuery ("SELECT NoAvion, NomAvion "
+ "FROM AirBurkina.Avions") ;
// Récupération et affichage du résultat de l’exécution de l’ordre « SELECT » à l’aide
// de l’API de l’objet « ResultSet » retourné dans la variable « rs »
int NoAvion ;
String NomAvion ;
StringWriter sw = new StringWriter ();
PrintWriter writer = new PrintWriter (sw);
while (rs.next ()) {
NoAvion = rs.getInt ("NoAvion");
NomAvion = rs.getString ("NomAvion");
writer.println ();
writer.println ("No avion = " + NoAvion +" Nom = " + NomAvion );
writer.flush ();
System.out.println (sw.getBuffer().toString());
}
rs.close () ;
stmt.close ();
maConn.commit ();
maConn.close ();
▀
L’API d’un objet « ResultSet » offre à cet effet des mutateurs qui permettent
de mettre à jour individuellement chaque colonne de la ligne courante du
résultat de l’exécution d’un ordre « SELECT ». Chacun de ces mutateurs est
préfixé par « update » et est défini, tout comme pour les accesseurs offerts
par cette API, pour un type de valeur Java (« Byte », « Short », « Integer »,
« Long », « Float », « Double », « Boolean », « Date », « Array », « Class »,
etc.). Chaque mutateur prend en paramètre d’une part, soit le nom de la
colonne, soit le rang de la colonne en considérant que les colonnes sont
330
SGBD relationnels – Tome 1, État de l’art
Toutefois, pour que la mise à jour des lignes du résultat de l’exécution d’un
ordre « SELECT » puisse se faire à l’aide de l’API de l’objet « ResultSet »,
l’objet « Statement » utilisé pour l’exécution de l’ordre « SELECT » par
appel de sa méthode « executeQuery () » doit être créé préalablement par
appel de la méthode « createStatement » d’un objet « Connection » en
passant le paramètre « CONCUR_UPDATABLE ».
Exemple 6.3.3.iv : Le code Java qui suit crée un objet « Connection » dans la
variable « maConn ». Un objet « Statement » est ensuite créé dans la
variable « stmt » par appel de la méthode « createStatement » de cet objet
« Connection » en fournissant « ResultSet.TYPE_FORWARD_ONLY » et
« ResultSet.CONCUR_UPDATABLE » comme paramètres. L’appel de la
méthode « executeQuery » de cet objet « Statement » exécute un ordre
« SELECT » qui retourne le numéro, le nom et la capacité de chaque avion
« AIRBUS » de la table « AirBurkina.Avions » et crée dans la variable
« rs » un objet « ResultSet ». Cet objet « ResultSet » est ensuite utilisé pour
modifier à « 175 » la valeur de la colonne « CapAvion » de toutes les lignes
de la table « AirBurkina.Avions » qui concerne un « AIRBUS ».
// Création d’une connexion à une source et d’un objet « Connection »
// dans la variable « maConn » pour la gestion de cette connexion
Context ctx = new InitialContext ();
DataSource ds = (DataSource) ctx.lookup ("jdbc/BDAirBurkina");
Connection maConn = ds.getConnection ("user", "pwd") ;
331
Joachim TANKOANO
Comme le montre l’exemple qui suit, il est aussi possible, lors du parcours
des lignes du résultat de l’exécution d’un ordre « SELECT », de supprimer
une ligne par appel de la méthode « deleteRow () » de l’objet « ResultSet ».
Exemple 6.3.3.v : Le code Java qui suit exécute un ordre « SELECT » qui
retourne la ligne de chaque avion « AIRBUS » contenu dans la table
« AirBurkina.Avions » et utilise ensuite l’objet « ResultSet » pour
supprimer ces lignes de la base de données.
// Création d’une connexion à une source et d’un objet « Connection »
// dans la variable « maConn » pour la gestion de cette connexion
332
SGBD relationnels – Tome 1, État de l’art
333
Joachim TANKOANO
Exemple 6.3.3.vi : Le code Java qui suit utilise l’objet « ResultSet » pour
insérer une nouvelle ligne dans la table « AirBurkina.Avions ».
// Création d’une connexion à une source et d’un objet « Connection »
// dans la variable « maConn » pour la gestion de cette connexion
Context ctx = new InitialContext ();
DataSource ds = (DataSource) ctx.lookup ("jdbc/BDAirBurkina");
Connection maConn = ds.getConnection ("user", "pwd") ;
// Création d’un objet « Statement » dans la variable « stmt » pour la soumission de
// l’exécution des ordres « SELECT » non paramétrés à cette source en
// spécifiant les caractéristiques de l’objet « ResultSet » qui doit être retourné
Statement stmt = maConn.createStatement
(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE,
ResulSet.CLOSE_CURSORS_AT_COMMIT) ;
// Soumission de l’exécution d’un ordre « SELECT » qui retourne tous les avions
// contenus dans la table «AirBurkina.Avions »
ResultSet rs = stmt.executeQuery ("SELECT * FROM AirBurkina.Avions "
+ "WHERE NomAvion LIKE 'AIRBUS%' ");
// Insertion d’un nouvel avion dans la table «AirBurkina.Avions » à l’aide de l’objet
// « ResultSet » retourné dans la variable « rs »
rs.moveToInsertRow() ;
rs.updateInt ("NoAvion", 100);
rs.updateString ("NomAvion", "BONING 747");
rs.updateInt ("CapAvion", 600) ;
rs.updateString ("LocAvion", "OUAGADOUGOU") ;
rs.insertRow () ;
rs.close () ;
stmt.close ();
maConn.commit ();
maConn.close () ;
▀
334
SGBD relationnels – Tome 1, État de l’art
Exemple 6.3.3.vii : Le code Java qui suit crée un objet « Statement » dans la
variable « stmt » et appelle sa méthode « addBatch () » à plusieurs reprises
pour constituer un lot d’ordres « INSERT » dans la table « Avions ». La
méthode « executeBatch () » de cet objet « Statement » est ensuite appelée
pour l’exécution en différé de ce lot.
// Création d’une connexion à une source et d’un objet « Connection »
// dans la variable « maConn » pour la gestion de cette connexion
Context ctx = new InitialContext ();
DataSource ds = (DataSource) ctx.lookup ("jdbc/BDAirBurkina");
Connection maConn = ds.getConnection ("user", "pwd") ;
// Création d’un objet « Statement » dans la variable « stmt » pour la constitution et
// la soumission de l’exécution d’un lot d’ordres SQL non paramétrés à cette source
Statement stmt = maConn.createStatement () ;
// Constitution d’un lot d’ordres « INSERT » dans la table «Avions »
// par appesl de « stmt.addBatch () »
stmt.addBatch
("INSERT INTO Avions (NoAvion, NomAvion, CapAvion, LocAvion) "
+ "VALUES (10, 'AIRBUS A310', 200, 'BOBO-DIOULASSO') ");
stmt.addBatch
("INSERT INTO Avions (NoAvion, NomAvion, CapAvion, LocAvion) "
+ "VALUES (20, 'AIRBUS A340', 200, 'OUAGADOUGOU')");
335
Joachim TANKOANO
stmt.addBatch
("INSERT INTO Avions (NoAvion, NomAvion, CapAvion, LocAvion) "
+ "VALUES (20, 'BOING 707', 150, 'OUAGADOUGOU')") ;
// Soumission en différé de l’exécution du lot d’ordres constitué
int [] NbLignes = stmt.executeBatch ();
stmt.close ();
maConn.commit ();
maConn.close () ;
▀
336
SGBD relationnels – Tome 1, État de l’art
337
Joachim TANKOANO
338
SGBD relationnels – Tome 1, État de l’art
339
Joachim TANKOANO
340
SGBD relationnels – Tome 1, État de l’art
341
Joachim TANKOANO
342
SGBD relationnels – Tome 1, État de l’art
343
Joachim TANKOANO
344
SGBD relationnels – Tome 1, État de l’art
BIBLIOGRAPHIE
ORACLE: Oracle® Database JDBC Developer's Guide, 12c Release 2 (12.2) –
May 2017
Melton J. & Eisenberg A.: Understanding SQL and Java Together: A Guide to
SQLJ, JDBC, and Related Technologies - Morgan Kaufmann (2000).
Silberschatz A., Korth H.F. & Sudarshan S.: Database system concepts, sixth
edition - McGraw-Hill, 2011
345
Chapitre 7. : Gestion de la mémoire
relationnelle
7.1. Introduction
Dans la section 1.2, nous avons vu que pour pouvoir servir de support pour
le stockage des données d’une entreprise, les performances constituent une
exigence essentielle que la technologie des bases de données doit satisfaire.
Les techniques utilisées par les SGBD relationnels pour la gestion d’un
volume important de données et pour garantir un temps d’accès
raisonnable et indépendant de la volumétrie de ces données sont fortement
dictées par les caractéristiques intrinsèques des moyens qui servent de
support pour le stockage de ces données, à savoir, les disques. De ce fait,
nous allons commencer dans ce chapitre par un rappel sur l’architecture et
SGBD relationnels – Tome 1, État de l’art
Secteur Tête de
lecture/écriture
Bras
Contrôleur
Plateaux
347
Joachim TANKOANO
Pour lire ou pour écrire une information sur un disque, l’unité centrale doit
soumettre une requête au contrôleur de ce disque dont la fonction
principale est de coordonner les opérations nécessaires pour l’exécution de
cette requête.
Pour être utilisable, un disque magnétique doit être formaté. L’une des
finalités du formatage d’un disque est de diviser l’espace disponible sur ce
disque en blocs de même taille, multiple de la taille des secteurs (512 octets,
1024 octets, 2048 octets, 4096 octets, etc.).
Chaque disque contient en générale une table qui fait le lien entre le numéro
séquentiel d’un bloc et son adresse physique.
348
SGBD relationnels – Tome 1, État de l’art
De ce fait, dans l’état actuel de l’art, le rôle d’un disque dans un ordinateur
est de servir de support pour le stockage des données du système
d’information, tandis que le rôle de la mémoire centrale est de servir de
support pour l’exécution des programmes qui manipulent ces données.
349
Joachim TANKOANO
350
SGBD relationnels – Tome 1, État de l’art
Comme nous l’avons vu dans le chapitre 4, d’un point de vue logique, une
base de données relationnelle est composée de tables qui contiennent des
extensions de relations.
Les lignes d’une table sont des enregistrements de même type dont les
champs correspondent aux colonnes de cette table.
De ce fait, bien que les lignes d’une table soient de même type, elles ne sont
pas nécessairement de même longueur.
Dans un disque, les lignes qui composent une table sont stockées à
l’intérieur de ses blocs avec comme corollaires que :
• Un bloc peut contenir une ou plusieurs lignes si la taille des blocs est
plus grande que la taille de ces lignes
• Une ligne peut aussi s’étendre sur plusieurs blocs si la taille des blocs
est plus petite que la taille de cette ligne.
351
Joachim TANKOANO
Par ailleurs, un bloc ne peut contenir que les lignes d’une même table (sauf
lorsque le mécanisme de clustérisassion est utilisé (voir les paragraphes
7.4.2 et 7.7.3.f)).
Les blocs qui sont alloués à une table ne sont pas nécessairement contigus.
De ce fait, ces blocs sont toujours chaînés entre eux, ce qui permet d’allouer
les blocs requis pour le stockage d’une table au fur et à mesure des besoins
sans contrainte particulière sur le nombre de blocs pouvant être alloués à
cette table.
L’accès direct à une ligne d’une table se fait au moyen de son adresse
physique définie par le couple :
n° du bloc, clé de recherche dans la ligne.
Cela nécessite de pouvoir accéder à chaque bloc par son numéro et à chaque
ligne dans un bloc par sa clé de recherche.
Les lignes sont en général stockées à l’intérieur d’un bloc l’une avant l’autre
en commençant par la fin du bloc.
Dans tous les cas, il reste très souvent de l’espace inutilisé dans chaque bloc,
situé entre le catalogue et la dernière ligne du bloc. Cet espace inutilisé peut
être volontairement prévu pour faciliter les insertions futures de lignes à
l’intérieur des blocs où sont stockées une table ou le remplacement de la
valeur d’une colonne par une autre de plus grande taille.
352
SGBD relationnels – Tome 1, État de l’art
Pointeur
vers le
bloc
Catalogue suivant
Espace non-utilisé 3ème 2ème 1ère
ligne ligne ligne
Chaque ligne stockée à l’intérieur d’un bloc est en général constituée dans
l’ordre des trois (3) parties ci-après :
• Un groupe de champs réservés pour la gestion de la ligne comme,
par exemple : un code indiquant si la ligne est logiquement
supprimée ou non, un code indiquant si la ligne est verrouillée ou
non (utilisé pour la gestion des accès concurrents), la taille de la ligne,
etc…
• Les colonnes de taille fixe
• Les colonnes de taille variable.
Pour ce qui concerne les colonnes de taille variable, deux options sont
possibles :
• La taille d’une colonne peut être indiquée au début de cette colonne,
ce qui ne permet pas un accès direct à chaque colonne
• L’adresse de début de chaque colonne peut être indiquée dans un
tableau inclus au début de la ligne dans le groupe des champs
réservés.
353
Joachim TANKOANO
Taille
des
colonnes
de taille
Champs 5 colonnes de 3 colonnes de variable
réservés taille fixe taille variable
Si une table contient « n » lignes de taille fixe et si chaque bloc d’un disque
peut contenir « m » lignes de cette table, pour stocker cette table sur ce
disque de la façon la plus simple possible, en se conformant aux principes
définis dans le paragraphe 7.3.2, il suffit de stocker chaque groupe de « m »
lignes de cette table dans un bloc de ce disque (en respectant les principes
définis dans les paragraphes 7.3.3 et 7.3.4) et de chaîner ces blocs entre eux,
sans se préoccuper de l’ordre dans lequel ses lignes sont rangées.
Après avoir stocké en vrac les lignes d’une table sur un disque de cette
façon, pour y rechercher une ligne en particulier où la valeur du groupe de
colonnes qui constitue la clé de recherche dans cette table a une certaine
valeur donnée, il n’existe pas d’autre solution plus rapide que de transférer
en mémoire centrale, bloc après bloc, les blocs chaînés qui contiennent les
lignes de cette table et de procéder dans chaque bloc transféré en mémoire
centrale à une recherche de cette ligne.
Dans le meilleur des cas, la ligne recherchée peut être retrouvée après la
lecture en mémoire centrale du premier bloc de cette table et dans le pire
des cas, qu’après la lecture en mémoire centrale de son dernier bloc. En
354
SGBD relationnels – Tome 1, État de l’art
Exemple 7.3.5.i : Si nous considérons que notre table contient « 1 000 000 »
de lignes de « 120 » octets, que la taille d’un bloc est de « 1024 » octets et que
le temps d’accès moyen à un bloc de « 8,25 ms », on peut calculer comme
suit le temps maximum et moyen requis pour la recherche d’une ligne dans
cette table, si on considère comme marginal le temps requis pour les
recherches effectuées en mémoire centrale :
Sur la base de cet exemple, on ne peut que conclure que le stockage d’une
table en procédant comme décrit plus haut amène à violer l’exigence
imposée à la technologie des bases de données relative aux performances
qui veut d’une part, que la quantité de données qui peut être stockée sur les
supports physiques de mémorisation ne soit pas techniquement limitée et
d’autre part, que le temps d’accès à ces données soit raisonnable du point
de vue du temps de réponse attendu par l’entreprise et indépendant de
cette quantité. En procédant comme décrit plus haut, la quantité de données
que peut contenir une table n’est pas techniquement limitée, dès lors que
les blocs requis peuvent être alloués sur les disques disponibles. En
revanche, le temps moyen d’accès à une ligne qui est estimé à 8mm 43 est
très largement au-dessus du temps de réponse attendu qui doit être
inférieur à la seconde.
355
Joachim TANKOANO
356
SGBD relationnels – Tome 1, État de l’art
Les sections qui suivent (7.4, 7.5 et 7.6) sont consacrées à l’étude de ces trois
techniques.
Les disques « SSD (Solid State Drive) » sont des nouveaux types de disques
apparus ces dernières années. Ces disques n’ont ni plateaux, ni têtes de
lectures, ce qui élimine dans leur fonctionnement les délais de
positionnement et de latence. Comme les clés USB, les données sont
stockées dans des composants électroniques, ce qui permet des taux de
transfert de plusieurs milliers de mégaoctets par seconde.
357
Joachim TANKOANO
Dans le schéma de gauche, chaque ligne est placée dans un bloc différent et
les 4 blocs sont dans des pistes différentes. Le temps de lecture de ces 4 blocs
sera dans ce cas :
4 * (5,2 ms + 3 ms + 0,04 ms) = 33 ms.
Dans le schéma de droite, les 4 lignes sont placées dans 2 blocs contigus. Le
temps de lecture de ces 2 blocs sera dans ce cas :
5,2 ms + 3 ms + (2 * 0,04 ms) = 8,3 ms.
358
SGBD relationnels – Tome 1, État de l’art
Pour que la gestion du placement des lignes d’une table à l’intérieur des
blocs puisse être assurée efficacement par le SGBD, l’espace requis pour le
359
Joachim TANKOANO
stockage de la base de données sur les disques doit être alloué au SGBD
pour qu’il en assure l’organisation et la gestion.
C’est l’option retenue par certains SGBD comme ORACLE qui stockent les
bases de données dans un ou plusieurs fichiers alloués par le système
d’exploitation hôte dont la gestion de l’espace est placée sous la seule
responsabilité du SGBD. Les concepts proposés notamment par le SGBD
Oracle pour permettre la maîtrise du regroupement et du placement des
données sont :
• Les « EXTENTS », qui sont des blocs contigus, alloués pour le
stockage d’une table et dont la taille peut être fixée par l’usager.
L’« EXTENT » constitue l’unité d’allocation à une table d’un espace
sur un disque
• Les « SEGMENTS », qui correspondent à des tables et qui sont
constitués d’un ou de plusieurs EXTENTS
• Les « CLUSTERS », où chaque bloc regroupe les lignes d’une table
ou de plusieurs tables qui possèdent la même valeur au niveau des
colonnes définies comme étant la clé du cluster. Ceci permet par
exemple de regrouper physiquement dans un même bloc chaque
ligne de la table des commandes avec les lignes de la table des
articles commandés qui lui correspondent
• Les « TABLESPACES », qui constituent l’espace logique pour le
stockage des segments et des clusters. Un « TABLESPACES » est
constitué d’un (au moins) ou de plusieurs fichiers du système hôte,
pouvant être répartis sur plusieurs disques.
360
SGBD relationnels – Tome 1, État de l’art
Cette technique est mise en œuvre par la plupart des fournisseurs de SGBD.
Elle consiste à réserver, en mémoire centrale, une zone tampon entre les
applications et la base de données où est copiée une partie des blocs qui
contiennent cette base de données.
Chaque fois que le SGBD veut accéder à un bloc d’une table, ce bloc est
d’abord recherché dans la zone tampon :
• Si ce bloc s’y trouve, l’accès au disque est évité
• Si ce bloc ne s’y trouve pas, le SGBD le récupère dans la base de
données et le recopie dans la zone tampon (éventuellement en
remplacement d’un autre bloc) avant d’exploiter son contenu.
Demande
d’accès à un
bloc d’une table Base de
Résultat de la données
demande
Zone tampon en
mémoire centrale
Plus la taille de la zone tampon est importante, plus les chances d’y
retrouver le bloc recherché sont grandes et plus le gain escompté est
significatif. De ce fait, il est essentiel que la mémoire centrale du serveur qui
héberge une base de données soit importante et qu’une bonne partie de
cette mémoire soit allouée au SGBD pour la création et la gestion de cette
zone tampon.
361
Joachim TANKOANO
L’index d’une table est comparable à la table des matières d’un livre qui
permet de retrouver le numéro de la page où commence un chapitre, une
section ou un paragraphe, sans avoir à feuilleter ce livre page par page. Il
est aussi comparable à l’index des mots clés qui permet de retrouver en un
clin d’œil les numéros des pages où ces mots clés sont utilisés.
Dans la technologie des bases de données, l’indexation d’une table sur une
clé de recherche, constituée d’une colonne ou d’un groupe de colonnes, crée
une mise en correspondance qui permet, pour chaque valeur que cette clé
de recherche peut prendre, de déterminer les adresses des blocs où sont
stockées les lignes qui contiennent cette valeur.
362
SGBD relationnels – Tome 1, État de l’art
L’indexation d’une table peut se définir sur sa clé primaire, sur une clé
alternative, mais aussi sur n’importe quelle colonne ou groupe de colonnes.
L’indexation d’une table peut toutefois être sans intérêt, si la recherche doit
s’effectuer sur une clé de recherche à très faible cardinalité pour laquelle les
lignes qui contiennent chaque valeur qu’elle peut prendre existent dans la
presque totalité des blocs qui servent au stockage de cette table du fait de la
technique utilisée. Dans de telles situations, le parcourt séquentiel de ces
blocs reste la meilleure solution. C’est le cas, par exemple, s’il faut
rechercher dans une table des étudiants tous les étudiants originaires de la
région du centre lorsque du fait de la technique d’indexation utilisée les
lignes de cette table sont stockées en vrac sur le disque.
Dans les paragraphes qui suivent, chaque fois qu’il sera nécessaire
d’évaluer les performances d’une technique d’indexation nous nous
appuierons sur le fichier présenté dans l’exemple 7.3.5.i en supposant qu’il
s’agit d’une table de films : « Films (Titre, Année, Producteur, Pays, …) ».
En rappel, ses caractéristiques sont les suivantes :
• Nombre de lignes dans la table : 1 000 000 ;
• Taille d’une ligne de la table : 120 octets ;
• Taille des blocs du disque où la table est stockée : 1024 octets ;
• Temps d’accès moyen à un bloc : 8,25 ms.
363
Joachim TANKOANO
TITRE ANNEE …
TEZA 2009 …
EZRA 2007 …
DRUM 2005 …
HEREMAKONO 2001 …
ALI ZAOUA 2001 …
BUUD YAM 1997 …
GUIMBA 1995 …
AU NOM DU CHRIST 1991 …
TILAÏ 1991 …
SARRAOUNIA 1987 …
Les techniques d’indexation dense et non dense ont été développées avant
l’avènement de la technologie des bases de données. Elles ont servi de base
pour le développement de techniques d’indexation plus récentes. Ce qui
suit présente le principe général qui régit l’organisation physique des
données d’une table indexée à l’aide d’un index non dense et les
implications de ce principe général sur l’opération de construction d’une
table indexée et sur les algorithmes de recherche, insertion et suppression
de lignes. Les implications sur l’opération de modification d’une ligne ne
sera pas abordée. Dans le pire des cas, elle peut se traduire par une
suppression suivie d’une insertion de ligne.
Une table indexée sur une clé de recherche à l’aide d’un index non dense
est stockée et organisée physiquement au niveau du disque dans deux
fichiers : un fichier dit principal (FP) qui contient toutes les lignes de la table
et un fichier index (FI).
L’indexation d’une table à l’aide d’un index non dense nécessite un tri
364
SGBD relationnels – Tome 1, État de l’art
Le fichier index non dense FI est quant à lui un fichier qui, pour chaque bloc
du fichier principal FP, contient une ligne constituée de deux champs : un
champ « adresse de bloc » qui contient l’adresse de ce bloc et un champ
« valeur de clé » qui contient la valeur de la clé de recherche dans la 1ère
ligne de ce bloc. Le fichier index non dense FI est donc trié par construction
selon l’ordre croissant de la clé de recherche et ce tri doit être maintenu
après chaque insertion ou modification de ligne. À tout moment, si « c1, c2,
…, cn » désigne la liste des valeurs triées de la clé de recherche dans le fichier
index non dense FI, et « c » la valeur de la clé de recherche dans une ligne
stockée dans un bloc « i » du fichier principal FP, on doit avoir de ce fait « ci
c ci+1 ».
TITRE ANNEE …
ALI ZAOUA 2001 …
AU NOM DU CHRIST 1991 …
(FI) BUUD YAM 1997 …
ALI ZAOUA
DRUM DRUM 2005 …
HEREMAKONO EZRA 2007 …
TILAÏ GUIMBA 1995 …
HEREMAKONO 2001 …
SARRAOUNIA 1987 …
TEZA 2009 …
TILAÏ 1991 …
365
Joachim TANKOANO
Lorsqu’une table est indexée sur une clé de recherche « c » à l’aide d’un
index non dense, la recherche des lignes où « c » contient une certaine
366
SGBD relationnels – Tome 1, État de l’art
Exemple 7.6.3.iii : Ainsi, pour rechercher dans la table réduite des films
indexée dans l’exemple 7.6.3.i, le film dont la clé de recherche contient la
valeur « GUIMBIA », il faut dans un premier temps rechercher dans le
fichier index FI, en commençant par la première ligne, la dernière ligne où
la valeur de la clé de recherche est inférieure ou égale à « GUIMBIA ». Cette
première étape retourne comme résultat la ligne du fichier index où la
valeur de la clé de recherche est « DRUM ». Dans une deuxième étape, il
faut transférer en mémoire centrale le bloc du fichier principal dont
l’adresse est contenue dans la ligne déterminée par la première étape, c’est-
à-dire, le deuxième bloc du fichier principal de la table réduite des films. La
recherche en mémoire centrale dans le contenu de ce bloc permet de
367
Joachim TANKOANO
Lorsque cette table n’est pas indexée, le temps moyen calculé dans
l’exemple 7.3.5.i est de 515 625 ms, soient 8mn 43s. Ce temps a été divisé par
plus de 4 464, grâce à la création d’un index non dense et au recours à une
recherche dichotomique dans le fichier index FI, ce qui montre très bien
l’intérêt de l’indexation d’une table à l’aide d’un index non dense
▀
d) L’insertion d’une ligne dans une table indexée à l’aide d’un index non
dense
368
SGBD relationnels – Tome 1, État de l’art
pour l’insertion.
Lorsqu’une table est indexée sur une clé de recherche « c » à l’aide d’un
index non dense, l’insertion dans cette table d’une nouvelle ligne où la clé
de recherche « c » contient une certaine valeur s’effectue en procédant
comme suit :
• Dans un premier temps on doit, en parcourant le fichier index FI,
comme décrit dans le paragraphe c) ci-dessus, identifier le bloc « b »
du fichier principal FP où cette ligne devrait se trouver.
• Si ce bloc « b » n’est pas plein, on doit y effectuer les décalages
nécessaires pour préserver le tri du fichier principal FP et insérer la
nouvelle ligne dans ce bloc « b » à l’emplacement libéré.
• Si ce bloc « b » est plein et qu’il existe de la place dans le bloc
précédent ou suivant, on doit effectuer les décalages nécessaires
dans ce bloc « b » et dans un de ses blocs adjacents non pleins pour
préserver le tri du fichier principal FP, insérer la nouvelle ligne à
l’emplacement libéré et modifier en conséquence le fichier index FI
si dans un des blocs affectés par le décalage sa 1ère ligne n’est plus la
même.
• Si ce bloc « b » et ses blocs adjacents (précédant et suivant) sont
pleins, on doit allouer au fichier principal FP un nouveau bloc « b’ »,
répartir les lignes du bloc « b » et la ligne à insérer dans les deux
blocs « b » et « b’ » de manière à préserver le tri du fichier principal
FP et modifier en conséquence le fichier index FI en y insérant une
nouvelle ligne.
Pour insérer le film « FINYE » de 1983 dans cette table, il faut d’abord
parcourir le fichier index FI, en commençant par la première ligne, pour
identifier sa dernière ligne où la valeur de la clé de recherche est inférieure
ou égale à « FINYE ». Cette première étape identifie la ligne du fichier index
FI où la valeur de la clé de recherche est « DRUM » et où la valeur du champ
« adresse de bloc » pointe sur le deuxième bloc du fichier principal FP où
369
Joachim TANKOANO
TITRE ANNEE …
ALI ZAOUA 2001 …
AU NOM DU CHRIST 1991 …
(FI) BUUD YAM 1997 …
ALI ZAOUA
DRUM DRUM 2005 …
HEREMAKONO EZRA 2007 …
TEZA GUIMBA 1995 …
HEREMAKONO 2001 …
SARRAOUNIA 1987 …
…
TEZA 2009 …
TILAÏ 1991
Ce constat doit amener à effectuer dans ces deux blocs les décalages
nécessaires pour une insertion qui préserve le tri du fichier principal FP.
370
SGBD relationnels – Tome 1, État de l’art
GUIMBA 1995 …
HEREMAKONO 2001 …
SARRAOUNIA 1987 …
TEZA 2009 …
TILAÏ 1991
GUIMBA 1995 …
HEREMAKONO 2001 …
SARRAOUNIA 1987 …
TEZA 2009 …
TILAÏ 1991
e) La suppression d’une ligne dans une table indexée à l’aide d’un index
non dense
371
Joachim TANKOANO
L’indexation d’une table à l’aide d’un index non dense présente les
avantages ci-après :
• Cette technique d’indexation est la plus simple à implémenter.
• Si un fichier index non dense est volumineux, il peut à son tour être
indexé, ce qui peut conduire à une hiérarchie d’index.
L’indexation d’une table à l’aide d’un index non dense présente également
des inconvénients :
• Le fichier principal et le fichier index de la table doivent être triés et
ce tri doit être préservé après chaque insertion ou modification de
ligne. Ceci amène à prévoir pour les modifications et les insertions
futures de lignes de l’espace libre dans chaque bloc concerné, ce qui
accroit l’espace disque requis pour le stockage de ces deux fichiers.
• L’index est dit plaçant, dans le sens que son contenu dépend de
l’ordre des lignes contenues dans le fichier principal. De ce fait, il est
impossible de créer sur une table plusieurs index non denses, basés
sur des clés de recherche différentes.
• L’espace occupé par un fichier index non dense peut être non
négligeable. En d’autres termes, ce qu’on gagne en temps d’accès, on
le perd en occupation de l’espace disque disponible.
Dans ce type d’indexation d’une table, le fichier index dense FID doit
contenir une ligne pour chaque ligne du fichier principal. Chaque ligne du
fichier index dense FID doit être constituée de deux champs : un champ
« adresse de ligne » qui contient l’adresse de la ligne qui lui correspond
dans le fichier principal et un champ « valeur de clé » qui contient la valeur
de la clé de recherche de cette ligne. Le champ « adresse de ligne » doit être
constitué d’un sous-champ « adresse de bloc » qui contient l’adresse du
bloc où se trouve la ligne et d’un sous-champ « adresse de ligne dans le
bloc » qui permet d’accéder à cette ligne dans ce bloc.
372
SGBD relationnels – Tome 1, État de l’art
Les blocs du fichier principal, qui est le fichier le plus encombrant, peuvent
donc être remplis au maximum.
373
Joachim TANKOANO
Cette technique d’indexation des tables est celle qui est la plus utilisée dans
la technologie des bases de données relationnelles. Elle combine
l’organisation et le fonctionnement des arbres B (ou arbres équilibrés) et les
techniques d’indexation à l’aide d’index denses et non denses. Ce qui suit
présente le principe général qui régit l’organisation physique des données
d’une table indexée à l’aide de cette technique et les implications de ce
principe général sur les algorithmes de recherche, d’insertion et de
suppression de lignes. Tout comme pour l’indexation à l’aide d’un index
non dense, les implications sur l’opération de modification d’une ligne ne
seront pas abordées.
374
SGBD relationnels – Tome 1, État de l’art
Les blocs des fichiers index non denses « FI1 », « FI2 », … et « Fik »
constituent le fichier index de cette table et sont en général regroupés dans
un fichier unique où le premier bloc est celui du fichier index racine « Fik ».
C1 R1 C2e-1 R2-1 S
Où :
• « Ci » désigne la clé de recherche dans la ligne « i »
• « Ri » désigne les autres colonnes restantes de la ligne « i »
• « S » est un pointeur vers le bloc suivant (N.B. : pour faciliter les
insertions, les blocs sont en général doublement chaînés)
• « » représente la zone non utilisée dans ce bloc.
De même, nous considérons que chaque bloc d’un fichier index non dense
« FIi » a une structure abstraite schématisée comme suit :
P1 C2 P2 Ci Pi C2d-1 P2d-1 S
375
Joachim TANKOANO
Où :
• Chaque ligne « i » est constituée de deux champs « Pi » et « Ci »
• « Pi » pointe sur le sous-arbre « i »
• « Ci » doit correspondre à la valeur de la clé de recherche dans la 1ère
ligne du 1er bloc de ce sous-arbre « i »
• « » désigne un sous-arbre (réduit à un bloc du fichier principal FP
s’il s’agit d’un bloc du fichier index non dense « FI1 »)
• « C » désigne une clé quelconque de ce sous-arbre
• « » représente la zone non utilisée dans ce bloc
• « S » est un pointeur vers le bloc suivant (N.B. : ici également, pour
faciliter les insertions les blocs sont en général doublement chaînés).
Exemple 7.6.5.i : Dans cet exemple, pour faire simple, nous posons « e = 2 »
et « d= 2 », ce qui veut dire que le nombre de lignes dans un bloc du fichier
principal « FP » varie entre 2 et 3 et que le nombre de lignes dans un bloc
d’un fichier index non dense « Fii » varie également entre 2 et 3. Nous
supposons aussi une table de 12 lignes qui contiennent les valeurs suivantes
pour ce qui concerne la clé de recherche : « 10, 20, 25, 30, 33, 40, 48, 50, 55,
60, 70 ».
5
FI2 (index racine) 0
2 4 6
FI1 5 0 0
1 2 2 3 3 4 4 5 5
0 0 5 0 3 0 8 0 5
6 7
0 0
FP
Comme on peut le constater, les nœuds de cet arbre qui matérialise
376
SGBD relationnels – Tome 1, État de l’art
Les lignes de cette table sont triées et réparties dans des blocs chaînés qui
constituent à la fois les feuilles de l’arbre et les blocs du fichier principal
« FP ». Conformément à nos hypothèses de base, ces blocs contiennent
chacun au minimum 2 lignes et au maximum 3 lignes.
Le fichier index non dense « FI1 » est construit sur le fichier principal « FP »
et le fichier index non dense « FI2 » sur le fichier index non dense « FI1 ». Le
fichier index non dense « FI2 » est constitué d’un seul bloc correspondant à
la racine de l’arbre B+. Conformément à nos hypothèses de base, chaque
bloc de ces deux fichiers index non denses « FI1 » et « FI2 » contient
également au minimum 2 lignes et au maximum 3 lignes. Dans chacun de
ces blocs, la clé de recherche de la 1ère ligne a été omise. La clé de recherche
contenue dans chacune des autres lignes possède la même valeur que la clé
de recherche de la 1ère ligne du bloc du sous-arbre pointé par cette ligne. Par
exemple, la valeur « 50 » de la clé de recherche dans la 2ème ligne du bloc
racine correspond à la valeur de la clé de recherche de la 1ère ligne du 1er
bloc du sous-arbre pointé par cette ligne.
▀
b) La recherche d’une ligne dans une table indexée à l’aide d’un arbre B+
Lorsqu’une table est indexée sur une clé de recherche « C » à l’aide d’un
arbre B+, la recherche des lignes où « C » contient une valeur ciblée
s’effectue en parcourant l’arbre qui matérialise l’organisation physique des
données sur le disque.
Ce parcours doit se faire depuis le bloc racine qui est celui du fichier index
racine non dense « FIk » jusqu’au bloc du fichier principal « FP » qui doit
être celui qui contient les lignes recherchées. Au cours de ce parcours, dans
chaque bloc d’un fichier index non dense « FIi » atteint, on doit rechercher
la ligne qui contient la valeur de la clé de recherche la plus grande qui est
inférieure ou égale à la valeur ciblée et utiliser le pointeur de bloc contenu
dans cette ligne pour accéder au bloc suivant. En d’autres termes, ce
parcours doit se faire en lisant en mémoire centrale un bloc de chaque
377
Joachim TANKOANO
c) L’insertion d’une ligne dans une table indexée à l’aide d’un arbre B+
Lorsqu’une table est indexée sur une clé de recherche « C » à l’aide d’un
arbre B+, l’insertion d’une nouvelle ligne où la clé de recherche « C »
contient une certaine valeur s’effectue en procédant comme suit :
• On doit rechercher, en procédant comme décrit dans le paragraphe
b) ci-dessus, le bloc « b » du fichier principal où cette ligne pourrait
s’insérer.
378
SGBD relationnels – Tome 1, État de l’art
Exemple 7.6.5.iii : Supposons une table vide indexée sur une clé de
recherche « C » à l’aide d’un arbre B+ dont l’organisation physique est
schématisée par l’arbre ci-dessous.
FI1
Bloc 0
FP
Bloc 1
FI1
Bloc 0
2 4 6
0 0 0 FP
Bloc 1
379
Joachim TANKOANO
4
0 FI1
Bloc 0
2 3 4 6
0 0 0 0 FP
Bloc 1 Bloc 2
2 2 3 4 6
0 5 0 0 0 FP
Bloc 1 Bloc 2
380
SGBD relationnels – Tome 1, État de l’art
2 4
5 0 FI1
Bloc 0
1 2 2 3 4 6
0 0 5 0 0 0 FP
Bloc 1 Bloc 3 Bloc 2
1 2 2 3 4 4 6
0 0 5 0 0 8 0 FP
Bloc 1 Bloc 3 Bloc 2
381
Joachim TANKOANO
4
FI2 (index racine) 0
Bloc 6
2 5 FP
FI1
5 0
Bloc 0 Bloc 5
1 2 2 3 4 4 5 6
0 0 5 0 0 8 0 0
Bloc 1 Bloc 3 Bloc 2 Bloc 4
▀
d) La suppression d’une ligne dans une table indexée à l’aide d’un arbre
B+
Lorsqu’une table est indexée sur une clé de recherche « C » à l’aide d’un
arbre B+, la suppression d’une ligne où la clé de recherche « C » contient
une certaine valeur s’effectue en procédant comme suit :
• On doit rechercher, en procédant comme décrit dans le paragraphe
b) ci-dessus, le bloc « b » du fichier principal qui contient cette ligne
à supprimer.
• Si après la suppression de cette ligne, ce bloc « b » contient au moins
« e » lignes, on doit s’arrêter là, après avoir recherché et reconstruit,
si c’est le cas, le bloc du fichier index non dense qui contient une ligne
qui pointe sur un sous-arbre où la ligne supprimée était la 1ère ligne
du 1er bloc de ce sous-arbre.
• Sinon, si après la suppression de cette ligne, le bloc « b » contient « e-
1 » lignes et si un de ses blocs voisins (disons « b’ ») contient plus de
« e » lignes, on doit transférer une ligne du bloc « b’ » vers le bloc
« b » et s’arrêter là, après avoir recherché et reconstruit, si c’est le cas,
les blocs des index non denses qui contiennent une ligne qui pointe
sur un sous-arbre contenant le bloc « b » ou le bloc « b’ », où la 1ère
ligne a changé.
382
SGBD relationnels – Tome 1, État de l’art
regrouper dans le bloc « b » ses lignes et les lignes de l’un de ses blocs
adjacents (disons « b’ ») pour former un bloc de « 2e-1 » lignes,
désallouer le bloc « b’ », reconstruire le bloc de l’index non dense
« FI1 » qui contient la ligne qui pointait vers « b’ » en supprimant
cette ligne. La suppression de cette ligne peut à son tour provoquer
un regroupement des lignes de deux blocs dans un seul bloc et la
désallocation d’un bloc, ce processus pouvant se poursuivre
jusqu’au niveau du bloc racine.
Exemple 7.6.5.iv : Soit une table indexée sur une clé de recherche « C » à
l’aide d’un arbre B+ dont l’organisation physique est schématisée comme
suit :
2 4
5 0 FI1
Bloc 0
1 2 2 3 4 4 6
0 0 5 0 0 8 0 FP
Bloc 1 Bloc 2 Bloc 3
1 2 2 3 4 4
0 0 5 0 0 8 FP
Bloc 1 Bloc 2 Bloc 3
▀
Exemple 7.6.5.v : Soit une table indexée sur une clé de recherche « C » à
l’aide d’un arbre B+ dont l’organisation physique est schématisée comme
ci-dessous.
383
Joachim TANKOANO
4
FI2 (index racine) 0
Bloc 0
2 5 FP
FI1 5 0
Bloc 1 Bloc 2
1 2 2 3 4 4 5 5 6
0 0 5 0 0 8 0 5 0
Bloc 3 Bloc 4 Bloc 5 Bloc 6
4
FI2 (index racine) 8
Bloc 0
2 5
FI1 5 5
FP
Bloc 1 Bloc 2
1 2 2 3 4 5 5 6
0 0 5 0 8 0 5 0
Bloc 3 Bloc 4 Bloc 5 Bloc 6
▀
Exemple 7.6.5.vi : Soit une table indexée sur une clé de recherche « C » à
l’aide d’un arbre B+ dont l’organisation physique est schématisée comme
ci-dessous.
384
SGBD relationnels – Tome 1, État de l’art
4
FI2 (index racine) 0
Bloc 0
2 5
FI1 5 0
FP
Bloc 1 Bloc 2
1 2 2 3 4 4 5 6
0 0 5 0 0 8 0 0
Bloc 3 Bloc 4 Bloc 5 Bloc 6
1 2 2 3 4 5 6
0 0 5 0 8 0 0 FP
Bloc 3 Bloc 5 Bloc 6
▀
Lorsqu’une table est indexée sur une clé de recherche « C » à l’aide d’un
arbre B+, ce qui suit évalue le coût, en termes de nombre de blocs à lire,
d’une recherche de ligne contenant une certaine valeur ciblée de « C ».
385
Joachim TANKOANO
On en déduit que :
n/e = dp p = logd (n/e)
En d’autres termes :
Nombre de fichiers index non denses « FIi » = p = logd (n/e).
En conclusion, on peut dire que dans une table indexée sur une clé de
recherche « C » à l’aide d’un arbre B+, la recherche de toute ligne dans cette
table nécessite au plus la lecture de :
logd (n/e) + 1 blocs (correspondant à la lecture d’un bloc dans chaque fichier
index non dense « FIi » et d’un bloc dans le fichier
principal « FP »).
Si par ailleurs les fichiers index non denses de cette table sont composés de
lignes de 29 octets (25 octets pour la clé de recherche et 4 octets pour les
adresses de blocs) on aura pour ce qui concerne les blocs de ces fichiers
386
SGBD relationnels – Tome 1, État de l’art
On en déduit que pour retrouver une ligne dans la table des films, il faut
lire en mémoire centrale 6 blocs dans le pire des cas et 5 blocs dans le
meilleur des cas (à raison de 1 bloc dans chaque fichier index non dense
« FIi » et 1 bloc dans le fichier principal « FP »). En rappel, dans l’exemple
7.3.5.i, nous avions calculé que lorsque la table n’est pas indexée, il faut lire
au maximum 125 000 blocs et en moyenne 62 500 blocs.
Pour stocker le fichier principal et ses fichiers index, il faut 264 708 blocs
dans le pire des cas et 147 062 blocs dans le meilleur des cas. Nous avions
calculé que lorsque cette table n’est pas indexée, il faut 125 000 blocs pour
la stocker.
▀
387
Joachim TANKOANO
Si par ailleurs les fichiers index non denses de cette table sont composés
comme dans l’exemple précédent de lignes de 29 octets (25 octets pour la
clé de recherche et 4 octets pour les adresses de blocs), on aura pour ce qui
concerne les blocs de ces fichiers index non denses :
Nombre de lignes par bloc = (1024/29) = 35,31 = 36 lignes dont 1 de 4 octets.
On en déduit que pour retrouver une ligne dans la table des films, il faut
comme dans l’exemple précédent 7.6.5.vii lire 6 blocs dans le pire des cas et
388
SGBD relationnels – Tome 1, État de l’art
5 blocs dans le meilleur des cas (à raison de 1 bloc dans chaque fichier index
non dense « FIi », 1 bloc dans le fichier index dense « FID » et 1 bloc dans le
fichier principal « FP »).
Pour stocker le fichier principal et ses fichiers index, il faut 187 286 blocs
dans le pire des cas et 156 196 blocs dans le meilleur des cas.
389
Joachim TANKOANO
1 Bloc 5 Bloc 13
Si la fonction de hachage « h(c) » est telle que les paquets ainsi constitués
sont équilibrés, cette technique d’indexation divise par « p » le temps
d’accès à toute ligne de la table concernée en limitant la recherche au paquet
pointé par l’entrée du répertoire qui contient la valeur hachée de la clé de
recherche de cette ligne. L’objectif doit être de faire en sorte qu’en plus
chaque paquet ne soit constitué que d’un seul bloc pour que l’accès à toute
ligne de la table concernée puisse se faire qu’en transférant un seul bloc en
mémoire centrale.
390
SGBD relationnels – Tome 1, État de l’art
Plus « p » est grand, moins il y aura des débordements dans les paquets et
plus la diminution du temps d’accès sera importante.
Dans la pratique, il n’est pas aisé de trouver une fonction de hachage d’une
clé de recherche pouvant conduire à une répartition équilibrée des lignes
entre les paquets alloués à une table.
Où : « rang (titre [0]) » désigne le rang dans l’alphabet du 1er caractère du titre
du film, en supposant que le rang du caractère « A » est « 1 ».
Si nous supposons que chaque bloc du disque peut contenir trois lignes,
l’indexation de cette table à l’aide de cette fonction de hachage conduit à
une organisation physique des données sur le disque qui peut être
schématisée comme suit :
391
Joachim TANKOANO
Cet exemple met en évidence le fait qu’il n’est pas aisé de trouver une
fonction de hachage capable de garantir une répartition équilibrée entre les
paquets, quelles que soient les données contenues dans une table. Dans cet
exemple, le 1er paquet n’est constitué que d’un seul bloc qui de surcroit est
vide, alors que les 2 autres paquets débordent.
392
SGBD relationnels – Tome 1, État de l’art
393
Joachim TANKOANO
trouver une fonction de hachage qui évite, dans tous les cas de figure,
des déviations statiques, afin de garantir une répartition équilibrée
des lignes entre les paquets.
Ce qui suit présente les principes généraux ainsi que les avantages et
inconvénients de ces deux variantes.
Cette approche utilise une fonction de hachage qui, pour chaque valeur
possible de la clé de recherche, génère une valeur hachée sous la forme
d’une chaîne de « N » bits où « N » est suffisamment grand pour ne pas
constituer une contrainte sur le nombre de lignes que peut contenir une
table. À cet effet, on peut fixer par exemple à 32 la valeur de « N ».
394
SGBD relationnels – Tome 1, État de l’art
Au départ, « M » peut par exemple être égal à « 1 », ce qui veut dire que la
taille du répertoire est égale à « 21 » c’est-à-dire « 2 ». À cette étape initiale
de l’évolution de l’organisation physique des données, la 1ère entrée du
répertoire doit contenir la valeur binaire « 0 » et pointer sur le paquet qui
doit contenir toutes les lignes pour lesquelles la valeur hachée de leur clé de
recherche se termine par cette valeur binaire, c’est-à-dire « 0 ». Quant à la
2ème entrée du répertoire, elle doit contenir la valeur binaire « 1 » et pointer
sur le paquet qui doit contenir toutes les lignes pour lesquelles la valeur
hachée de leur clé de recherche se termine par cette valeur binaire, c’est-à-
dire « 1 ». Pour retrouver une ligne où le dernier bit de la valeur hachée de
sa clé de recherche est par exemple « 1 », il suffit de transférer en mémoire
centrale le paquet pointé par l’entrée du répertoire qui contient « 1 ».
Quand un paquet pointé par une seule entrée du répertoire doit déborder
après une insertion de ligne, on doit :
• Étendre le nombre de paquets alloués à la table concernée par
duplication de ce paquet plein
• Doubler la taille du répertoire, qui devient « 2M+1 » en dupliquant
chaque entrée : (1) par ajout du bit 0 à gauche de la valeur contenue
dans l’ancienne entrée et du bit 1 à gauche de la valeur contenue dans
le duplicata de l’ancienne entrée, (2) en faisant pointer le paquet
plein par son ancien pointeur et le nouveau paquet par le duplicata
de ce pointeur d’une part, et d’autre part, en faisant pointer les autres
paquets non concernés par l’insertion, par leurs anciens pointeurs et
leurs duplicatas
• Redistribuer la nouvelle ligne et les lignes du paquet plein entre ce
dernier et le nouveau paquet pour que chaque ligne soit dans le
paquet pointé par l’entrée du répertoire dont la valeur correspond
aux « M+1 » derniers bits de la valeur hachée de sa clé de recherche.
395
Joachim TANKOANO
Quand un paquet pointé par plus d’une entrée du répertoire doit déborder
après une insertion de ligne, on doit :
• Se contenter de dupliquer ce paquet plein sans toucher au répertoire
qui contient déjà toutes les entrées requises
• Répartir, la ligne à insérer, les lignes du paquet plein et les pointeurs
du répertoire qui le concernent, entre le paquet plein et le nouveau
paquet. Lorsque le paquet plein est pointé par plus de 2 entrées du
répertoire, chacun de ces 2 paquets (le paquet plein et le nouveau
paquet) doit être pointé, après la répartition, par les entrées du
répertoire dont la terminaison binaire des valeurs qu’elles
contiennent indiquent qu’elles sont issues de la même opération de
duplication.
396
SGBD relationnels – Tome 1, État de l’art
Répertoire Paquet 1
0
1
Paquet 2
397
Joachim TANKOANO
398
SGBD relationnels – Tome 1, État de l’art
399
Joachim TANKOANO
deux fois pour l’insertion de lignes dans des paquets pleins autres que ce
paquet 2.
Dans cet état, ce paquet 2 doit regrouper toutes les lignes pour lesquelles
les trois derniers bits de la valeur hachée de la clé de recherche sont « 001 »,
« 101 », « 011 » ou « 111 ».
400
SGBD relationnels – Tome 1, État de l’art
401
Joachim TANKOANO
Lorsque le paquet qui doit être dupliqué n’est pas celui où l’insertion doit
se faire, la ligne à insérer est mise dans une zone dite zone de débordement,
en attente du positionnement du curseur « p » sur ce paquet plein.
402
SGBD relationnels – Tome 1, État de l’art
403
Joachim TANKOANO
00 DRUM (01001100)
p
10 HEREMAKONO (10111010)
Tilaï (10001010)
11 Sarraounia (11010011)
404
SGBD relationnels – Tome 1, État de l’art
l’état suivant où :
• Le paquet d’adresse « 00 », correspondant au paquet pointé par le
curseur « p », a été dupliqué parce que le paquet d’adresse « 01 » où
devrait être inséré le film « EZRA (00100101) » est plein
• L’adresse du paquet dupliqué est devenue « 000 » par ajout du bit
« 0 » à gauche de son ancienne adresse
• L’adresse du paquet duplicata dans la zone d’extension a été dérivée
de la nouvelle adresse du paquet dupliqué en remplaçant le bit « 0 »
ajouté à gauche par le bit « 1 » pour donner « 100 »
• La seule ligne contenue dans le paquet dupliqué a été transférée dans
son paquet duplicata dans la zone d’extension, parce que l’adresse
de ce paquet duplicata est « 100 », ce qui correspond aux « 3 »
derniers bits de la valeur hachée de la clé de recherche de cette ligne
• Le film « EZRA (00100101) » a été placée dans la zone de
débordement en attente de la duplication du paquet d’adresse « 01 »
• Le curseur a été déplacé sur le paquet suivant de la zone primaire.
000
Zone de débordement
01 BUUD YAM (10001001) EZRA (00100101) p
ALIZAOUA (11110001)
10 HEREMAKONO (10111010)
Tilaï (10001010)
11 Sarraounia (11010011)
405
Joachim TANKOANO
Zone de débordement
01 BUUD YAM (10001001) EZRA (00100101) p
ALIZAOUA (11110001)
10 HEREMAKONO (10111010)
Tilaï (10001010)
11 Sarraounia (11010011)
406
SGBD relationnels – Tome 1, État de l’art
11 Sarraounia (11010011)
407
Joachim TANKOANO
Sarraounia (11010011) p
11
408
SGBD relationnels – Tome 1, État de l’art
a) Le principe général
Une table indexée sur une clé de recherche à l’aide d’un index bitmap est
stockée et organisée physiquement sur le disque dans deux fichiers : un
fichier principal FP qui contient toutes les lignes et un fichier index bitmap.
Dans le fichier index bitmap, chaque ligne est associée à la ligne de même
rang dans le fichier principal et chaque colonne représente une des valeurs
que la clé de recherche peut prendre. Un fichier bitmap contient donc autant
de lignes qu’il y a de lignes dans le fichier principal et autant de colonnes
que de valeurs différentes de la clé de recherche.
Dans chaque ligne d’un fichier index bitmap, chaque colonne doit contenir
comme valeur le bit « 0 », à l’exception de la colonne qui représente la
409
Joachim TANKOANO
Un fichier index bitmap est donc une matrice creuse, peu volumineuse,
constituée de « 0 » et de « 1 ».
Pour retrouver les adresses des lignes du fichier principal qui ont une
valeur donnée de la clé de recherche, il suffit de retrouver dans le fichier
index bitmap toutes les lignes où la colonne qui représente cette valeur
contient le bit « 1 ».
Exemple 7.5.8.i : Supposons que dans la table des films il existe une colonne
« Métrage » qui ne peut prendre que l’une des trois valeurs suivantes :
« court », « moyen », « long ». L’indexation de la table réduite des films à
l’aide d’un index bitmap en prenant comme clé de recherche la colonne
« Métrage » conduirait à une organisation physique des données qui peut
être schématisée comme suit :
Fichier principal Fichier index bitmap
TITRE ANNEE METRAGE … Court Moyen Long
410
SGBD relationnels – Tome 1, État de l’art
dans la colonne « Moyen » le bit « 1 », parce que les lignes de même rang
dans le fichier principal contiennent dans la clé de recherche
« METRAGE » la valeur « Moyen ». Les lignes « 1 », « 5 » et « 8 » du fichier
index bitmap contiennent dans la colonne « Court » le bit « 1 », parce que
les lignes de même rang dans le fichier principal contiennent dans la clé de
recherche « METRAGE » la valeur « Court ».
En outre, lorsque la cardinalité des clés de recherche est très faible, les
fichiers index bitmap qui en résultent sont très peu encombrants, ce qui
permet de charger leurs copies en mémoire centrale et de les utiliser pour
le traitement de requêtes complexes sur la table indexée sans avoir à accéder
au contenu du fichier principal stocké sur le disque, comme :
• Compter le nombre de lignes de cette table qui contiennent certaines
combinaisons de valeurs de ces clés de recherche, définies à l’aide
d’une expression booléenne.
• Rechercher les adresses des lignes qui contiennent certaines
combinaisons de valeurs de ces clés de recherche, définies également
à l’aide d’une expression booléenne.
7.6.9. Exercices
411
Joachim TANKOANO
412
SGBD relationnels – Tome 1, État de l’art
FP
0 3 4 7
FI1 0 0 0
7
0 0 0 1 5 5 7 7 8
1 3 7 0 4 8 0 8 0
1 2 2 3 3 4 4
5 0 6 0 9 0 4
413
Joachim TANKOANO
414
SGBD relationnels – Tome 1, État de l’art
415
Joachim TANKOANO
a) Les « TABLESPACES »
416
SGBD relationnels – Tome 1, État de l’art
b) Les « SEGMENTS »
417
Joachim TANKOANO
leur modification, d’une part, pour gérer les accès concurrents aux
données et d’autre part, pour permettre l’annulation des
modifications effectuées par une transaction en cas de reprise après
un incident (voir chapitre 9).
c) Les « EXTENTS »
418
SGBD relationnels – Tome 1, État de l’art
419
Joachim TANKOANO
Les lignes d’une table sont stockées dans la partie « Row Data » des BLOCS
DE DONNEES sous forme d’enregistrements de longueur variable.
Le « ROWID » d’une ligne offre le moyen le plus rapide pour accéder à une
ligne et est utilisable dans les requêtes SQL sous forme de pseudo-colonne.
420
SGBD relationnels – Tome 1, État de l’art
421
Joachim TANKOANO
Chaque entrée dans une « PAGE » du fichier index dense « FID » pointe
sur une ligne distincte du fichier principal « FP » et est composée de :
• Un entête qui contient le nombre de colonnes qui compose la clé de
recherche et les informations de verrouillage de cette entrée pour la
gestion des accès concurrents à la ligne concernée dans le fichier
422
SGBD relationnels – Tome 1, État de l’art
principal « FP »
• Une valeur de la clé de recherche composée, pour chaque colonne, du
couple « longueur et valeur de la colonne »
• Un « ROWID » qui pointe sur la ligne concernée dans le fichier
principal « FP ».
Quant au fichier principal « FP », qui peut ne pas être trié, il est stocké dans
un segment de données.
Une table peut ainsi être indexée sur plusieurs clés de recherche à l’aide
d’index B-TREE standards.
(3) Comme nous l’avons déjà vu, dans ce type d’indexation d’une table,
l’index dense doit être trié dans l’ordre croissant de la clé de recherche. Pour
que ce fichier soit trié par construction, Oracle trie préalablement le fichier
423
Joachim TANKOANO
Lorsque les valeurs d’une clé de recherche sont générées en séquence pour
des opérations d’insertion en masse, l’utilisation d’un index à clé inversée
permet de répartir ces insertions sur l’ensemble des branches de
l’arborescence de l’index. En contrepartie, les index à clé inversée ne
facilitent pas la recherche de lignes lorsque la valeur de la clé de recherche
doit être comprise dans un intervalle de valeurs.
Une table INDEX-ORGANIZED d’Oracle est une table indexée sur la clé
primaire à l’aide d’un arbre B+ construit directement sur le fichier principal
« FP ».
424
SGBD relationnels – Tome 1, État de l’art
Le fichier principal « FP » doit être trié sur la clé primaire et ses « PAGES »
doivent constituer les feuilles de l’arbre B+.
Chaque entrée d’une feuille de l’arbre B+ concerne donc une ligne distincte
de la table indexée et est composée de :
• Un entête qui contient le nombre de colonnes qui compose la ligne, le
nombre de colonnes qui compose la clé primaire, ainsi que les
informations de verrouillage de la ligne pour la gestion des accès
concurrents.
• Une valeur de la clé primaire composée, pour chaque colonne, du
couple « longueur et valeur de la colonne ».
• Les valeurs des autres colonnes de la ligne, constituées chacune du
couple « longueur et valeur de la colonne ».
425
Joachim TANKOANO
Oracle offre la possibilité d’indexer une table à l’aide d’un index bitmap
lorsque la clé de recherche a une faible cardinalité.
Un bitmap est une séquence de bits où chaque bit correspond à une ligne
distincte du fichier principal « FP » et vaut « 1 » si la valeur de la clé de
recherche dans cette ligne est égale à la valeur de la clé de recherche dans
l’entrée du fichier index dense « FID » où se trouve ce bitmat et « 0 » sinon.
Chaque bit d’un bitmap peut être transformé en « ROWID » de la ligne qui
lui correspond à l’aide d’une fonction.
Chaque entrée d’une « PAGE » du fichier index dense « FID » est de ce fait
composée comme suit de :
• Un entête qui contient le nombre de colonnes qui compose la clé de
recherche et les informations de verrouillage de cette entrée pour la
gestion des accès concurrents.
• Une valeur de la clé de recherche composée, pour chaque colonne, du
couple « longueur et valeur de la colonne ».
• Le « ROWID » de départ qui désigne le « ROWID » de la ligne du
fichier principal « FP » correspondant au 1er bit du bitmap.
426
SGBD relationnels – Tome 1, État de l’art
Oracle distingue :
• Les clusters indexés qui utilisent un index qui a la même structure
qu’un index normal (c’est-à-dire un arbre B+) pour accéder aux
427
Joachim TANKOANO
428
SGBD relationnels – Tome 1, État de l’art
429
Joachim TANKOANO
430
SGBD relationnels – Tome 1, État de l’art
7.8. Exercice
Rédigez par groupe de deux ou trois, sur la base d’une revue de documents
techniques de référence, un rapport de présentation de la gestion de la
mémoire relationnelle par le SGBD MySQL et par le SGBD PostgreSQL.
Pour chacun de ces deux SGBD, ce rapport doit faire ressortir les
mécanismes mis en œuvre pour améliorer les performances globales du
système et pour permettre un accès rapide aux lignes d’une table,
notamment à travers une étude des aspects ci-après :
• L’architecture physique d’une base de données en termes de fichiers
du système hôte.
• L’organisation logique des données à l’intérieur des fichiers du
système hôte.
• Le langage de définition des données du schéma physique d’une
base de données.
• L’architecture interne du serveur de base de données.
431
Joachim TANKOANO
BIBLIOGRAPHIE
Antonio Albano, Dario Colazzo, Giorgio Ghelli & Renzo Orsini:
Relational DBMS Internals - Copyright © 2015 by A. Albano, D.
Colazzo, G. Ghelli, R. Orsini
Chan C-Y. & Ioannidis Y.E.: Bitmap index Design and evaluation - ACM
SIGMOD Intl. Conf., SIGMOD Record V° 27, n° 2, Seattle, USA, 1998.
Comer D.: The Ubiquitous B-Tree, Computing Surveys - vol. 11, n° 2, juin 1979.
Date C.J. : Introduction aux bases de données - 8è édition - Vuibert, Paris, 2004
Fagin R., Nivergelt J., Pippengar N. & Strong H.R.: Extendible Hashing – A
Fast Access Method for Dynamic Files - ACM TODS, vol. 4, n° 3,
septembre 1979, p. 315-344.
Knott G. D.: Hashing functions – Computer J. 18, pp. 265-278, Aug. 1975
Litwin W.: Linear Hashing – A New Tool for File and Table Addressing - 6th
Very Large Data Bases, Montreal, octobre 1980, p. 224-232.
O’Neil P. & Quass D.: Improved Query Performance with Variant Indexes -
Proc. of the ACM SIGMOD Conf. on Management of Data (1997).
Silberschatz A., Korth H.F. & Sudarshan S.: Database system concepts, sixth
edition - McGraw-Hill, 2011
432
Chapitre 8. : Transformation des requêtes SQL
en code exécutable
8.1. Introduction
Pour camper le décor, ce chapitre commence par une présentation des
principes généraux du processus de transformation d’une requête SQL en
code exécutable afin de mettre en relief les principaux problèmes que ce
processus soulève et les processeurs requis pour sa mise en œuvre.
Les techniques mises en œuvre par les SGBD relationnels au niveau des
deux étapes clés de ce processus sont ensuite présentées, à savoir,
l’optimisation du plan d’exécution logique d’une requête SQL et la
génération de son plan d’exécution physique.
Pour dire comment le résultat recherché doit être construit, cette requête
doit être transformée en une séquence d’opérateurs algébriques
relationnels (voir paragraphes 2.3.3, 2.4.5 et 4.3.2), c’est-à-dire, en un calcul
algébrique relationnel. Comme nous le savons déjà, les opérateurs de ce
calcul sont des opérateurs logiques abstraits qui manipulent des éléments
du niveau logique de représentation des données, c’est-à-dire des tables, en
faisant abstraction de la représentation de ces éléments au niveau physique
et des algorithmes utilisés. Ce calcul matérialise de ce fait le plan
d’exécution logique de cette requête.
434
SGBD relationnels – Tome 1, État de l’art
Comme nous l’avons vu dans les exemples traités dans les paragraphes
4.3.1 et 4.3.2, pour répondre à un besoin, l’écriture d’une requête SQL peut
conduire à de multiples solutions, différentes dans leur formulation mais
équivalentes par rapport au résultat qu’elles produisent. En outre, la
transformation d’une de ces requêtes SQL en un calcul algébrique
relationnel peut également conduire à plusieurs arbres de requêtes
construits différemment, mais qui produisent le même résultat. Comme le
montre l’exemple qui suit, ces arbres de requêtes, structurellement
différents mais sémantiquement équivalents, peuvent avoir un coût en
termes d’entrées / sorties disque différent.
Pour la question « quels sont les noms des avions qui effectuent un vol au départ
de Bobo-Dioulasso ? » on peut formuler les deux requêtes ci-dessous,
exprimées différemment mais qui sont sémantiquement équivalentes :
SELECT NomAvion
FROM Avion, Vol
WHERE Avion.NoAvion = Vol.NoAvion
AND Vol.VD = 'Bobo-Dioulasso';
SELECT NomAvion
FROM Avion
NATURAL JOIN Vol
WHERE Vol.VD = 'Bobo-Dioulasso';
435
Joachim TANKOANO
π a.NomAvion
σ
v.VD = 'Bobo-Dioulasso'
∞ a.NoAvion = v.NoAvion
Avions a Vols v
2ème arbre de requête :
π a.NomAvion
∞ a.NoAvion = v.NoAvion
Avions a
σ
v.VD = 'Bobo-Dioulasso'
Vols v
436
SGBD relationnels – Tome 1, État de l’art
Résultat ;
Pour chaque bloc bv de Vols Faire
Pour chaque bloc ba de Avions Faire
Pour chaque ligne l_bv de bv Faire
Pour chaque ligne l_ba de ba Faire
si l_bv.NoAvion = l_ba.NoAvion
Alors ajouter {l_bv, l_ba} dans Résultat.
437
Joachim TANKOANO
438
SGBD relationnels – Tome 1, État de l’art
Besoin
439
Joachim TANKOANO
REQUÊTE SQL
OPTIMISEUR DE L’ARBRE DE
REQUÊTE
GENERATEUR DE CODE
PLAN D’EXECUTION
PHYSIQUE
440
SGBD relationnels – Tome 1, État de l’art
Pour que l’arbre qui en résulte soit équivalent à l’arbre brut initial, ces
différentes transformations successives s’appuient, comme pour les autres
simplifications des expressions algébriques, sur des règles de réécriture
basées sur des équivalences algébriques et logiques qui découlent des
propriétés des opérateurs algébriques relationnels et des opérateurs
logiques.
441
Joachim TANKOANO
442
SGBD relationnels – Tome 1, État de l’art
Règles du groupe GR7. Commutation d’une sélection avec une union (ou
intersection ou différence)
(a) c (R1 R2) c (R1) c (R2)
(b) c (R1 R2) c (R1) c (R2)
(c) c (R1 – R2) c (R1) - c (R2).
Règles du groupe GR8. Commutation d’une sélection avec une jointure (ou
produit cartésien ou division)
Si A 1
(a) c1(A) (R1 c R2) c1(A) (R1) c R2
(b) c1(A) (R1 * R2) c1(A) (R1) * R2
(c) c1(A) (R1 R2) c1(A) (R1) R2
Si A 1 et B 2
(d) c1(A) c2(B) (R1 c R2) c1(A) (R1) c c2(B) (R2)
(e) c1(A) c2(B) (R1 * R2) c1(A) (R1) * c2(B) (R2)
(f) c1(A) c2(B) (R1 R2) c1(A) (R1) c2(B) (R2)
Si A 1 ((B 1) ) ((B 2) )
(g) c1(A) c2(B) (R1 c R2) c2(B) (c1(A) (R1) c R2)
(h) c1(A) c2(B) (R1 * R2) c2(B) (c1(A) (R1) * R2)
443
Joachim TANKOANO
Règles du groupe GR9. Commutation d’une projection avec une union (ou
intersection)
(a) A (R1 R2) A (R1) A (R2)
(b) A (R1 R2) A (R1) A (R2).
p.NoPilote
a.NomAvion = 'AIRBUS' σ
p.AdrPilote = 'OUAGA' σ
v.NoAvion = a.NoAvion ∞
Vols v Pilotes p
Dans cet arbre de requête, il n’existe aucun sous-arbre dont toutes les
feuilles concernent la même table. Pour mettre cet arbre sous sa forme
444
SGBD relationnels – Tome 1, État de l’art
p.NoPilote
v.NoAvion = a.NoAvion ∞
Vols v Pilotes p
p.NoPilote
v.NoAvion = a.NoAvion ∞
Vols v Pilotes p
Pour poursuivre la descente de cette sélection, elle doit faire l’objet d’une
commutation avec la jointure qui la précède par application de
l’équivalence algébrique définie par la règle « GR8.d », c’est-à-dire « c1(A)
445
Joachim TANKOANO
(R1 c R2) c1(A) (R1) c c2(B) (R2) », ce qui conduit à l’arbre ci-après,
c2(B)
p.NoPilote
v.NoAvion = a.NoAvion ∞
Vols v Pilotes p
p.NoPilote
v.NoAvion = a.NoAvion ∞
Pilotes p
446
SGBD relationnels – Tome 1, État de l’art
p.NoPilote
v.NoAvion = a.NoAvion ∞
Pilotes p
p.NoPilote
v.NoAvion = a.NoAvion ∞
Pilotes p
447
Joachim TANKOANO
p.NoPilote
v.NoAvion = a.NoAvion ∞
Pilotes p
p.NoPilote
v.NoAvion = a.NoAvion ∞
a.NoAvion
Pilotes p
▀
448
SGBD relationnels – Tome 1, État de l’art
Exemple 8.3.2.i : Pour l’illustration de ces règles de réécriture basées sur des
équivalences logiques, considérons l’arbre de requête brut ci-après, où
toutes les feuilles concernent la table « Vols ».
449
Joachim TANKOANO
-
Vols v Vols v
v.VD = 'OUAGA' σ -
Vols v
v.NoPilote > 50 σ σ v.NoAvion [100, 200]
Vols v Vols v
450
SGBD relationnels – Tome 1, État de l’art
v.VD = 'OUAGA' σ -
v.VD = 'OUAGA' σ -
v.NoPilote > 50
v.NoAvion [100, 200] Vols v σ v.HA < 12
Vols v Vols v
v.VD = 'OUAGA'
v.NoPilote > 50 σ σ (v.HA < 12)
v.NoAvion [100, 200]
Vols v Vols v
451
Joachim TANKOANO
452
SGBD relationnels – Tome 1, État de l’art
Les notations spécifiques qui suivent sont utilisées dans cette présentation :
• « NL (T) » pour désigner le nombre de lignes dans la table « T »
• « NB (T) » pour désigner le nombre de blocs requis pour stocker la
table « T »
• « Cardc (T) » pour désigner le nombre de valeurs distinctes de la clé
de recherche « c » dans la table « T » (c’est-à-dire la cardinalité de la
clé de recherche « c »)
• « Hauteurc (T) » pour désigner le nombre de niveaux (c’est-à-dire la
profondeur) de l’index B+créé sur la clé de recherche « c » de la table
«T»
• « Ordrec (T) » pour désigner le nombre maximum de fils de chaque
nœud interne de l’index B+, créé sur la clé de recherche « c » de la
table « T »
453
Joachim TANKOANO
Trier un fichier est l’une des opérations que les SGBD effectuent le plus
fréquemment.
454
SGBD relationnels – Tome 1, État de l’art
Cette phase produit à la fin sur le disque « NB (T) / w » fragments triés.
455
Joachim TANKOANO
F F F
1 2 3
1er bloc 2ème bloc 3ème bloc
Zone tampon Zone tampon Zone tampon
→ 1 → 3 → 2
5 7 4
6 8 9
F F F
1 2 3
1er bloc 2ème bloc 3ème bloc
Zone tampon Zone tampon Zone tampon
1 3 2
→ 5 → 7 → 4
6 8 9
456
SGBD relationnels – Tome 1, État de l’art
F F F
1 2 3
1er bloc 2ème bloc 3ème bloc
Mémoire Mémoire Mémoire
tampon tampon tampon
→ 12 3 2
16 → 7 4
17 8 → 9
b) La complexité de l’algorithme
457
Joachim TANKOANO
Tout comme pour la phase de tri, chaque étape de la phase de fusion lit et
écrit une fois le fichier à trier, ce qui entraine « 2 * NB(T) * logw-1
(NB(T)/w) » entrées / sorties disque pour l’ensemble des étapes de la
phase de fusion.
15 4 3 9 18 12 16 2 5 7 14 6
Fichier à trier
Phase de tri
3 4 15 9 12 18 2 5 16 6 7 14
1ère étape de
la fusion
3 4 9 12 15 18 2 5 6 7 14 16
2ème étape de
la fusion
2 3 4 5 6 7 9 12 14 15 16 18
Fichier trié
458
SGBD relationnels – Tome 1, État de l’art
Les aspects dont dépendent les algorithmes de sélection de lignes dans une
table concernent d’une part, la complexité de l’expression logique qui
définit la condition de sélection et d’autre part, l’organisation physique des
données.
Dans ses formes les plus complexes, cette condition peut être définie par :
• Des conjonctions et/ou disjonctions de tests d’égalité (Ex. :
« (c1='valeur1') (c2='valeur2') (T) », « (c1='valeur1') (c2='valeur2') (T) », etc…)
• Des tests d’inégalité
• Des tests d’appartenance à un intervalle de valeurs (Ex. : « (c≤'valeur1')
(T) », « (c>'valeur1') (c<'valeur2') (T) », etc…)
• Une combinaison des formes précédentes.
459
Joachim TANKOANO
Résultat ;
Pour chaque bloc b de T Faire
Pour chaque ligne l de b Faire
Si condition_de_sélection = vrai alors ajouter l dans Résultat ;
Cet algorithme n’est applicable que si les deux conditions suivantes sont
vérifiées :
• La condition de sélection est un test d’égalité sur une colonne de
sélection « c » (Ex. : « c='valeur' (T) »)
• Il existe un index, sur la colonne de sélection « c », défini à l’aide d’un
arbre B+ construit sur un fichier index dense « FID » du fichier
principal « FP ».
460
SGBD relationnels – Tome 1, État de l’art
Cet algorithme n’est applicable que si les deux conditions suivantes sont
vérifiées :
• La condition de sélection est un test d’égalité sur une colonne de
sélection « c » (Ex. : « c='valeur' (T) »)
• Il existe un index, sur la colonne de sélection « c », défini à l’aide
d’une fonction de hachage qui a permis de répartir les lignes de la
table concernée dans « p » paquets.
Cet algorithme n’est applicable que si les deux conditions suivantes sont
vérifiées :
• La condition de sélection est une disjonction de tests d’égalité sur des
colonnes de sélection « c1 », « c2 », … (Ex. : « (c1='valeur1') (c2='valeur2')
(T) »)
• Il existe un index sur chacune des colonnes de sélection « c1 », « c2 »,
…
461
Joachim TANKOANO
Cet algorithme calcule la liste de lignes qui vérifient chaque test d’égalité
de la condition de sélection en utilisant l’index défini sur la colonne de
sélection concernée et procède ensuite à une concaténation de ces listes de
lignes.
Cet algorithme n’est applicable que si les deux conditions suivantes sont
vérifiées :
• La condition de sélection est une conjonction de tests d’égalité sur
des colonnes de sélection « c1 », « c2 », … (Ex. : « (c1='valeur1')
(c2='valeur2') (T) »)
Cet algorithme effectue une sélection par test d’égalité via un index qui
utilise le test d’égalité le plus sélectif pour lequel il existe un index, en ne
retenant dans le résultat final que les lignes qui satisfont également les
autres tests d’égalité.
Cet algorithme n’est applicable que si les deux conditions suivantes sont
vérifiées :
• La condition de sélection est une conjonction de tests d’égalité sur
des colonnes de sélection « c1 », « c2 », … (Ex. : « (c1='valeur1')
462
SGBD relationnels – Tome 1, État de l’art
La projection n’a donc pas de coût spécifique. Elle allège en plus le coût
d’évaluation de l’opérateur algébrique qui la précède en réduisant la taille
des lignes de son résultat, sauf lorsque les doublons doivent être éliminés
de ce résultat.
463
Joachim TANKOANO
464
SGBD relationnels – Tome 1, État de l’art
465
Joachim TANKOANO
• Les approches qui nécessitent l’existence d’un index sur les colonnes
de jointure de l’une des deux tables (Ex. : l’approche de jointure par
boucles imbriquées avec index « Nested Loop index join »)
• Les approches qui nécessitent que pour chacune des deux tables, le
fichier principal ou l’index créé sur le fichier principal soit ordonné
selon les colonnes de jointure et qui effectuent si besoin, des tris dans
des fichiers temporaires afin de satisfaire cette condition (Ex. :
l’approche de jointure par tri-fusion « Sort Merge Join »)
• Les approches qui créent dynamiquement une organisation
physique temporaire de l’une ou des deux tables afin de faciliter la
jointure en utilisant des techniques d’indexation à l’aide de
fonctions de hachage (Ex. : « Hash Join », « Grace Hash Join »,
« Hybrid Hash Join »).
466
SGBD relationnels – Tome 1, État de l’art
Cet algorithme n’est applicable que s’il existe un index sur les colonnes de
jointure de l’une des deux tables à joindre. Si la condition de jointure est
basée sur des tests d’inégalité, il doit faire l’objet d’une adaptation qui rend
son coût plus élevé.
467
Joachim TANKOANO
468
SGBD relationnels – Tome 1, État de l’art
Le but de cette première phase est de répartir les lignes de chacune des deux
469
Joachim TANKOANO
La deuxième phase de cet algorithme est une phase de test qui consiste
à effectuer la jointure des lignes des paquets de « R » et de « S » de même
rang en utilisant l’algorithme de jointure par hachage « Hash Join » :
• Pour chaque paire, un des paquets est haché en mémoire centrale
dans la zone tampon de « w » blocs, en utilisant une fonction « h’(c) »
différente de « h(c) »
• Ensuite, un parcours séquentiel est effectué sur le 2ème paquet de la
paire et pour chaque ligne de ce paquet, un test de jointure est
effectué à l’aide du paquet haché.
470
SGBD relationnels – Tome 1, État de l’art
471
Joachim TANKOANO
Pour harmoniser les interactions avec les applications qui exécutent une
requête « SELECT » (notamment à l’aide d’un curseur ou son équivalent)
et entre un nœud père et ses nœuds fils, la tâche que chaque itérateur met
en œuvre doit être implémentée en implémentant une interface normalisée
de cette boîte noire, constituée, comme pour les curseurs PL/SQL, des trois
opérations ci-après :
• L’opération « OPEN () », que le père déclenche pour la création et
l’initialisation des variables de travail de cet itérateur
• L’opération « NEXT () », que le père appelle pour récupérer la ligne
suivante du résultat généré par l’exécution de cet itérateur
472
SGBD relationnels – Tome 1, État de l’art
Exemple 8.4.6.i : Soit par exemple l’arbre de requête optimisé ci-après qui
calcule la liste des noms des avions conduits par le pilote numéro « 10 » :
a.NomAvion
∞ a.NoAvion = v.NoAvion
Avions a σ v.NoPilote = 10
Vols v
Si nous faisons l’hypothèse que la table « Vols » est indexée sur la clé de
recherche « NoPilote » à l’aide d’un arbre B+ et que la table « Avions » est
aussi indexée sur la clé de recherche « NoAvion » à l’aide d’un arbre B+, il
est possible de dériver de cet arbre de requête le plan d’exécution physique
matérialisé par l’arbre ci-dessous, où :
• La table « Vols » a été remplacée par le fichier principal « Vols_FP »
où sont stockées ses lignes et par le fichier « Vols_NoPilote_idx » qui
contient son index sur la clé de recherche « NoPilote » construit à
l’aide d’un arbre B+
• La table « Avions » a été remplacée par le fichier principal
« Avions_FP » où sont stockées ses lignes et par le fichier
« Avions_NoAvion_idx » qui contient son index sur la clé de
recherche « NoAvion » construit à l’aide d’un arbre B+
• L’opérateur algébrique relationel de jointure a été remplacé par un
sous-arbre d’itérateurs (« NestedLoopJoinIndex », « ScanByAdr* »,
« ScanIndex* », « ScanByAdr** » et « ScanIndex** ») qui ensemble
implémentent l’algorithme de jointure par boucle imbriquée avec
index, où :
o Les itérateurs « ScanIndex* » et « ScanByAdr* »
implémentent le parcours des lignes de la 1ère table de la
473
Joachim TANKOANO
Curseur
application
NomAvion suivant
NestedLoopJoinIndex
ScanByAdr* ScanByAdr **
Vols_NoPilote_idx Avions_NoAvion_idx
Le tableau qui suit décrit à titre indicatif, pour des choix d’implémentation
que nous avons retenus de façon arbitraire, les tâches que les opérations
« OPEN () », « NEXT () » et « CLOSE () » de chaque itérateur devraient
effectuer dans le cadre du déroulement de l’algorithme de jointure
implémenté. Comme on peut le constater dans cet exemple, les itérateurs
génériques de même nom effectuent toujours les mêmes types de tâches.
474
SGBD relationnels – Tome 1, État de l’art
de « NEXT() » de
« ScanByAdr* »
retourne une ligne,
récupérer toutes les
lignes qui lui
correspondent dans
« Avions_FP » en
appelant « OPEN
() », « NEXT() »
autant de fois que
nécessaire et
« CLOSE() » de
« ScanByAdr** »,
joindre ces lignes et
la ligne de
« Vols_FP » dans
une zone tampon et
retourner la 1ère
ligne de cette zone
tampon
(3) Sinon retourner
« NULL »
ScanByAdr* Déclencher l’exécution de (1) Si l’appel de Libérer les
l’opération « OPEN () » de « NEXT() » de ressources
« ScanIndex* » « ScanIndex* » allouées par
retourne une « OPEN () » et
adresse de ligne appeler
dans « Vols_FP », l’opération
utiliser cette adresse « CLOSE () » de
pour récupérer et « ScanIndex* »
retourner la ligne
concernée de
« Vols_FP »
(2) Sinon, retourner
« NULL »
ScanIndex* Déclencher le parcours de 1) Si, dans la zone Libérer les
l’arbre B+ stocké dans tampon, toutes les ressources
« Vols_NoPilote_idx » adresses des lignes allouées par
pour récupérer dans une de « Vols_FP » qui « OPEN () »
zone tampon la liste des concernent le pilote
adresses des lignes de 10 n’ont pas encore
« Vols_FP » qui été traitées, traiter
475
Joachim TANKOANO
476
SGBD relationnels – Tome 1, État de l’art
HashJoinProbe
HachJoinBuild ScanByAdr
Vols_NoPilote_idx
Le tableau qui suit résume les tâches que les opérations « OPEN () »,
« NEXT () » et « CLOSE () » des itérateurs « HashJoinProbe » et
« HachJoinBuild » devraient effectuer dans le cadre des traitements qui
implémentent l’algorithme de jointure par hachage « Hash Join ».
477
Joachim TANKOANO
ligne de la table
« Vols »
(3) Retourner la
jointure de ces deux
lignes.
HachJoinBuild Déclencher le Retourner la ligne du Libérer les
hachage dans des fichier ressources allouées
paquets en mémoire « Avions_FP » dont par « OPEN () »
centrale des lignes du le numéro d’avion
fichier « Avions_FP » est passé en
en appliquant une paramètre après
fonction de hachage l’avoir récupérée
sur la valeur de la dans le paquet dont
colonne « NoAvion » le numéro
de chaque ligne de correspond à la
cette table valeur calculée pour
ce numéro d’avion à
l’aide de la même
fonction de hachage
478
SGBD relationnels – Tome 1, État de l’art
HashJoinProbe
HachJoinBuild ScanByAdr
Vols_NoPilote_idx
479
Joachim TANKOANO
Comme nous l’avons déjà souligné dans la section 8.4, la génération pour
une requête SQL donnée d’un plan d’exécution physique efficient est
tributaire : (1) de la diversité, de l’adéquation et de l’efficience de ces
algorithmes alternatifs mis à la disposition du SGBD pour pouvoir prendre
en compte, de la meilleure façon possible, les caractéristiques spécifiques à
chaque requête et (2) de l’espace disponible en mémoire centrale.
480
SGBD relationnels – Tome 1, État de l’art
Le contenu de cette table peut être affiché en partie par l’utilisateur, à l’aide
d’une structure arborescente matérialisée par des indentations où :
481
Joachim TANKOANO
482
SGBD relationnels – Tome 1, État de l’art
483
Joachim TANKOANO
484
SGBD relationnels – Tome 1, État de l’art
8.5.4. Exemples
485
Joachim TANKOANO
0 SELECT STATEMENT
1 TABLE ACCES BY INDEX ROWID t
2 BITMAP CONVERSION TO ROWID
3 BITMAP OR
4 BITMAP AND
5 BITMAP INDEX SINGLE VALUE idx_t_c1
6 BITMAP INDEX SINGLE VALUE idx_t_c2
7 BITMAP MERGE
8 BITMAP INDEX RANGE SCAN idx_t_c3
486
SGBD relationnels – Tome 1, État de l’art
487
Joachim TANKOANO
ROWID » qui l’utilise pour accéder directement à cette ligne dans le fichier
principal de la table « Cinemas ».
▀
0 SELECT STATEMENT
1 TABLE ACCESS BY INDEX ROWID Salles
2 INDEX RANGE SCAN idx_Salles_IdCinema
488
SGBD relationnels – Tome 1, État de l’art
489
Joachim TANKOANO
490
SGBD relationnels – Tome 1, État de l’art
491
Joachim TANKOANO
8.6. Exercices
Exercice 8.6.i : Soit une base de données universitaire dont le schéma est
défini comme suit :
Etudiants (NoSS, Nom, Adresse, MoyGéné)
CoursSuivis (NoSS, NoCours, Moy)
Cours (NoCours, Titre, Prof)
1) Formulez une requête SQL qui permet d’obtenir le nom des étudiants
ayant suivi le cours BD et dont la moyenne générale est supérieure ou
égale à 12.
2) Représentez cette requête à l’aide d’un arbre de requête brut.
3) Optimisez cet arbre.
4) Quel pourrait être le plan d’exécution physique de cette requête sous
Oracle si on fait l’hypothèse que la table « Cours » est indexée sur la
colonne « NoCours » à l’aide d’un arbre B+ et que table « Etudiants »
est indexée quant à elle sur la colonne « NoSS » à l’aide également d’un
arbre B+ ?
▀
Exercice 8.6.ii : Rédigez par groupe de deux ou trois, en s’appuyant sur une
revue de documents techniques de référence, un rapport de présentation du
processus de transformation d’une requête SQL en code exécutable par le
SGBD MySQL et par le SGBD PostgreSQL.
492
SGBD relationnels – Tome 1, État de l’art
493
Joachim TANKOANO
BIBLIOGRAPHIE
Aho A.V., Sagiv Y. & Ullman J.D.: Equivalences among Relational Expressions
- SIAM Journal of Computing, vol. 8, n° 2, p. 218-246, Juin 1979.
Date C.J. : Introduction aux bases de données - 8è édition - Vuibert, Paris, 2004
Graefe G.: Query Evaluation Techniques for Large Databases - ACM Computer
Surveys, vol. 25, n° 2, p. 73-170, Juin 1993.
Graefe G., Bunker R. & Cooper S.: Hash Joins and Hash Teams in Microsoft
SQL Server - Proc. of the International Conf. on Very Large Databases
(1998), pages 86–97.
MIRANDA S. & José-Maria BUSTA : L'art des bases de données, Tome 2, Les
bases de données relationnelles - 2è édition - Eyrolles, 1990
Shapiro L. D.: Join Processing in Database Systems with Large Main Memories
- ACM Transactions on Database Systems, Volume 11, Number 3
(1986), pages 239–264.
494
SGBD relationnels – Tome 1, État de l’art
Silberschatz A., Korth H.F. & Sudarshan S.: Database system concepts, sixth
edition - McGraw-Hill, 2011
Smith J.M. & Chang P.Y.: Optimizing the performance of a Relational Algebra
Database Interface - Comm. ACM, vol. 18, n° 10, p. 68-579, 1975
Zeller H. & Gray J.: An Adaptive Hash Join Algorithm for Multiuser
Environments - Proc. of the International Conf. on Very Large
Databases (1990), pages 186–197.
495
Chapitre 9. : Gestion des accès concurrents et
des reprises en cas d’incident
9.1. Introduction
Nous avons vu dans la section 1.2 que, la gestion des accès simultanés aux
données par plusieurs utilisateurs, afin d’éviter les interférences pouvant
altérer l’intégrité des données, ainsi que la restauration des données dans
un état cohérent après la survenue d’un incident, sont des exigences
relatives à la sécurité des données, pour lesquelles la technologie des bases
de données doit fournir une garantie.
Les mécanismes mis en œuvre par les SGBD, pour fournir leurs services,
doivent permettre d’éviter la survenue des interférences pouvant altérer
l’intégrité des données en y introduisant des incohérences.
Par ailleurs, après la survenue d’un incident, les SGBD doivent fournir les
moyens pouvant permettre de remettre la base de données concernée dans
son état antérieur cohérent le plus récent, afin d’éviter ainsi, toute perte ou
altération accidentelle de données.
Ce chapitre :
• Présente dans un premier temps, (1) les caractéristiques des
anomalies qui peuvent survenir lorsque plusieurs utilisateurs ont
accès simultanément à une base de données, (2) les caractéristiques
des incidents qui peuvent survenir dans le cycle de vie d’une base
de données, (3) les propriétés attendues de l’environnement
d’exécution offert par les SGBD, pour que ces anomalies ne puissent
pas survenir et pour que la restauration des données dans un état
cohérent après la survenue d’un incident soit possible
• Examine ensuite de façon plus détaillée, comment les SGBD
procèdent pour offrir un environnement d’exécution, pouvant
apporter une solution satisfaisante aux problèmes que posent les
accès concurrents à une base de données et les reprises en cas
496
SGBD relationnels – Tome 1, État de l’art
d’incident
• Aborde, à titre d’illustration, la prise en compte des concepts et
techniques présentés, au niveau du SGBD Oracle et de son langage
SQL.
9.2. Problématique
Les applications qui manipulent une base de données sont par nature des
applications multiutilisateurs. Ces applications sont exploitées
simultanément par des centaines, voire des milliers d’utilisateurs, pour
l’exécution de transactions informatiques. Ces transactions effectuent des
traitements dont la finalité est de fournir aux utilisateurs de ces applications
les services dont ils ont besoin. On peut citer à titre d’exemple :
• Les applications bancaires, que chaque utilisateur peut utiliser pour
exécuter en ligne une transaction de transfert de crédit d’un compte
A vers un compte B
• Les applications de réservation de vols des compagnies aériennes,
que chaque utilisateur peut utiliser pour exécuter en ligne une
transaction qui effectue une réservation de « n » sièges sur le vol « x »
• Les applications de vente en ligne, que chaque utilisateur peut
utiliser pour exécuter une transaction qui effectue un achat de « n »
produits.
Exemple 9.2.i : Le pseudo code qui suit est un extrait du code d’un
programme imaginaire qui permet de réserver 5 sièges sur le vol 315 :
497
Joachim TANKOANO
498
SGBD relationnels – Tome 1, État de l’art
499
Joachim TANKOANO
500
SGBD relationnels – Tome 1, État de l’art
501
Joachim TANKOANO
502
SGBD relationnels – Tome 1, État de l’art
503
Joachim TANKOANO
Ceci revient à dire que, être recouvrable sans annulations en cascade, peut
ne pas être, comme dans cet exemple, un statut souhaitable pour une
transaction. Dans cet exemple, le « ROLLBACK » de « T2 » ne restaure pas
« X » dans un état cohérent parce que « T2 » a modifié « X » avant le
« COMMIT » de « T1 », alors que « X » avait déjà été modifié par « T1 ».
On dit que « T2 » a effectué une écriture sale. Pour que le « ROLLBACK »
de « T2 » restaure « X » dans un état cohérent, il aurait fallu que le SGBD
retarde l’écriture sale effectuée par « T2 » en ligne 4, jusqu’à ce que « T1 »
fasse son « COMMIT ».
504
SGBD relationnels – Tome 1, État de l’art
De façon générale, l’arbre binaire de décision qui suit permet de dire si une
transaction est non recouvrable, recouvrable avec annulations en cascade,
recouvrable sans annulations en cascade ou stricte.
Non recouvrable
OUI
Les causes des incidents qui peuvent survenir dans le cycle de vie d’une
base de données sont multiples et variées. Ces incidents peuvent être la
conséquence d’erreurs de conception, de programmation ou de
paramétrage d’une application, de dysfonctionnements du SGBD, d’erreurs
dans les données fournies par l’utilisateur, de violation de contraintes
d’intégrité ou de confidentialité, d’actions malveillantes, de défaillances
matérielles, d’évènements externes (coupure de courant, inondation,
tremblement de terre, etc.), etc…
Au-delà de leurs causes, pour assurer la gestion de ces incidents, les SGBD
les regroupent en trois grandes catégories :
• Les incidents localisés au niveau de l’exécution d’une transaction
505
Joachim TANKOANO
Dans tous ces trois cas de figures, il doit être possible d’effectuer une
reprise. L’objectif de cette reprise doit être de remettre la base de données
dans son état antérieur cohérent le plus récent, afin d’éviter toute perte ou
toute altération des données. En d’autres termes, toutes les transactions en
cours au moment de l’incident doivent être strictes, c’est-à-dire
recouvrables sans annulations en cascade et leur annulation doit remettre
la base de données dans un état antérieur cohérent.
La cohérence des traitements effectués par les transactions doit garantir que
chaque transaction que le SGBD exécute, démarre avec des données
506
SGBD relationnels – Tome 1, État de l’art
Ce qui suit montre comment les SGBD procèdent pour fournir une garantie
d’ACIDité (c’est-à-dire, de ces propriétés) dans le cadre de la gestion des
accès concurrents et des reprises après incident, afin d’éviter toute
altération de l’intégrité des données liée à une interférence entre
transactions et toute perte accidentelle de données.
507
Joachim TANKOANO
a) Quelques définitions
508
SGBD relationnels – Tome 1, État de l’art
elles, parce que ce plan produit le même effet que celui d’un plan
d’exécution sériel. Ceci veut dire qu’il n’est pas possible de constater, à la
fin de l’exécution d’un tel plan, une anomalie dans les résultats, due à une
mise à jour perdue, à une lecture sale, à une lecture non reproductible ou à
des tuples fantômes.
Pour ces deux transactions, on peut définir comme suit un plan d’exécution
sériel, où « T2 » s’exécute avant « T1 », un plan d’exécution sérialisable
équivalent, produisant le même effet que ce plan d’exécution sériel et un
plan d’exécution non-sérialisable, dont l’effet produit est différent de celui
d’un plan sériel :
Plan sériel (diminue A et B de
10 et augmente C de 20)
T1 T2
1 read (B)
2 B B–20
3 write (B)
4 read (C)
5 C C+20
6 write (C)
7 COMMIT
8 read (A)
9 A A–10
10 write (A)
11 read (B)
12 B B+10
13 write (B)
14 COMMIT
509
Joachim TANKOANO
510
SGBD relationnels – Tome 1, État de l’art
Les paires où, dans un plan d’exécution de ces deux transactions, les deux
opérations sont considérées comme étant en conflit sont :
T1 : read (B) - T2 : write (B)
T1 : write (B) – T2 : read (B)
T1 : write (B) – T2 : write (B).
▀
511
Joachim TANKOANO
Paires en conflit :
T1:read (B) - T2:write (B) / T1:write (B) – T2:read (B) / T1:write (B) – T2:write (B)
512
SGBD relationnels – Tome 1, État de l’art
conflit (« T1:write (B) - T2:write (B) ») ne s’exécute pas non plus dans le
même ordre dans ce 3ème plan d’exécution et dans le 2ème plan sériel. Ce 3ème
plan d’exécution n’est donc pas sérialisable parce qu’il n’est équivalent à
aucun des deux plans sériels possibles.
Plan sériel (diminue A et B de Plan sériel (diminue A et B de
10 et augmente C de 20) 10 et augmente C de 20)
T1 T2 T1 T2
1 read (B) 1 read (A)
2 B B–20 2 A A–10
3 write (B) 3 write (A)
4 read (C) 4 read (B)
5 C C+20 5 B B+10
6 write (C) 6 write (B)
7 COMMIT 7 COMMIT
8 read (A) 8 read (B)
9 A A–10 9 B B–20
10 write (A) 10 write (B)
11 read (B) 11 read (C)
12 B B+10 12 C C+20
13 write (B) 13 write (C)
14 COMMIT 14 COMMIT
513
Joachim TANKOANO
c) Le théorème de la sériabilité
514
SGBD relationnels – Tome 1, État de l’art
Plan sérialisable
T1 T2
1 read (A)
2 read (B)
3 A A–10 T1 : read (B) - T2 : write (B)
T1 : write (B) – T2 : read (B)
4 B B–20
T1 : write (B) – T2 : write (B)
5 write (A)
6 write (B)
7 read (B)
(2, 11) (6, 7) (6, 11)
8 read (C) T1 T2
9 B B+10
10 C C+20
11 write (B)
12 COMMIT
13 write (C)
14 COMMIT
N.B. : Dans ce graphe de sérialisation comme dans ceux qui vont suivre, les
arcs sont étiquetés par des paires de numéros qui correspondent à des
numéros de lignes dans le tableau qui visualise l’entrelacement des
opérations de lectures / écritures. Chaque paire identifie les deux
opérations de lectures / écritures, en conflit, pour lesquelles l’arc a été créé.
Dans cet exemple, le graphe de sérialisation est sans cycle. Pour chaque
paire d’opérations en conflit, la transaction « T2 » est toujours celle qui
s’exécute en premier. On en déduit que ce plan d’exécution est sérialisable
et que le plan d’exécution sériel équivalent est celui où on a « T2 » suivi de
« T1 ».
515
Joachim TANKOANO
Plan non-sérialisable
T1 T2
1 read (A)
2 A A–10
3 read (B)
4 write (A)
5 B B–20
6 read (B)
7 write (B)
8 B B+10
9 read (C)
10 write (B)
11 COMMIT
12 C C+20
13 write (C)
14 COMMIT
(6, 7)
T1 T2
516
SGBD relationnels – Tome 1, État de l’art
De façon plus formelle, les paires en conflit de ces deux plans d’exécution
sont :
read1 (Prix) – write2 (Prix)
write1 (Prix) – read2 (Prix)
write1 (Prix) – write2 (Prix).
Ce qui suit visualise les deux plans dans des tableaux qui mettent en
évidence l’entrelacement des opérations et donne le graphe de sérialisation
de chaque plan.
Plan 1 Plan 2
T1 T2 T1 T2
1 Read (Prix) 1 Read (Prix)
2 Read (Prix) 2 Write (Prix)
3 Write (Prix) 3 Read (Prix)
4 Commit 4 Commit
5 Write (Prix) 5 Write (Prix)
6 Commit 6 Commit
(2, 3)
T1 T2 T1 (1, 5) (2, 3) (2, 5) T2
(1, 5), (3, 5)
517
Joachim TANKOANO
Plan 2 → w0(O1), w0(O2), r3(O1), r3(O2), r1(O1), r2(O1), w1(O1), r1(O2), w2(O1),
R2(O2), w2(O2), w1(O2)
Dans ces deux plans d’exécution, les paires en conflit sont :
w0 (O1) – r1 (O1) / w0 (O1) – w1 (O1) / w0 (O1) – r2 (O1) / w0 (O1) – w2 (O1) / w0
(O1) – r3 (O1)
Ce qui suit visualise les deux plans dans des tableaux qui mettent en
évidence l’entrelacement des opérations et donne le graphe de sérialisation
de chaque plan :
518
SGBD relationnels – Tome 1, État de l’art
Plan 1 Plan 2
T0 T1 T2 T3 T0 T1 T2 T3
1 w (O1) 1 w (O1)
2 w (O2) 2 w (O2)
3 r (O1) 3 r (O1)
4 w (O1) 4 r (O2)
5 r (O1) 5 r (O1)
6 w (O1) 6 r (O1)
7 r (O1) 7 w (O1)
8 r (O2) 8 r (O2)
9 w (O2) 9 w (O1)
10 r (O2) 10 r (O2)
11 w (O2) 11 w (O2)
12 r (O2) 12 w (O2)
T0 T3 T0 T3
(1, 7) (2, 12) (1, 3) (2, 4)
Le graphe de sérialisation du plan 1 est sans cycle, ce qui veut dire que ce
plan est sérialisable. Ce plan est équivalent au plan d’exécution sériel où
l’ordre d’exécution des transactions est « T0 », « T1 », « T2 », « T3 ». À la fin
de l’exécution de ce plan, « O1 » contiendra la valeur 19, « O2 » la valeur 16
et les valeurs lues par « T3 » seront 19 pour « O1 » et 16 pour « O2 », ce qui
correspond aux bonnes valeurs.
519
Joachim TANKOANO
Ces exemples montrent très bien que, lorsque des transactions s’exécutent
simultanément sans un contrôle des accès concurrents par le SGBD, selon
les circonstances, le plan d’exécution qui en résulte peut-être sérialisable,
c’est-à-dire, sans interférences entre les transactions, mais peut aussi être
non-sérialisable, c’est-à-dire, avec interférences entre les transactions
pouvant engendrer des anomalies dues à des mises à jour perdues, à des
lectures sales, à des lectures non répétables et à des tuples fantômes,
accompagnées d’une altération de l’intégrité des données.
La sériabilité est une propriété des plans d’exécution qui ne dépend que de
l’ordre dans lequel les opérations de lectures / écritures des transactions en
concurrence s’entrelacent. Elle garantit la non-interférence de ces
transactions.
La récouvrabilité est une propriété des plans d’exécution qui ne dépend que
de l’ordre dans lequel les opérations « COMMIT » et « ROLLBACK » sont
effectuées par les transactions en concurrence, après une lecture ou une
écriture sale. Elle garantit la possibilité de reprise en cas d’incident.
520
SGBD relationnels – Tome 1, État de l’art
T1 T2
(2, 3)
521
Joachim TANKOANO
522
SGBD relationnels – Tome 1, État de l’art
13 write (B)
14 COMMIT
(2, 13)
T1 T2
(6, 11) (6, 13)
Le troisième plan d’exécution est strict parce que « T2 » peut faire son
« ROLLBACK » sans que cela ne nécessite l’annulation de « T1 », aucune
des deux transactions n’ayant fait une lecture ou une écriture sale.
▀
La gestion des accès concurrents par les SGBD a pour principal objectif de
garantir des plans d’exécution sérialisables et stricts. Comme on peut le
constater dans l’exemple précédent 9.3.1.vi, les plans d’exécution
sérialisables et stricts dégradent la concurrence.
523
Joachim TANKOANO
524
SGBD relationnels – Tome 1, État de l’art
REQUÊTE SQL
ARBRE CANONIQUE
GENERATEUR DE CODE
PLAN D’EXECUTION
RESULTAT DE LA REQUÊTE
Zone
Tampon Disque
525
Joachim TANKOANO
Dans ce qui suit, nous commençons par une présentation des principales
caractéristiques des mécanismes de contrôle de l’exécution concurrente des
transactions, basés sur l’utilisation des verrous. Ensuite, nous présentons
quelques approches utilisées par les SGBD pour traiter les situations
d’interblocage, inhérentes à l’utilisation des verrous avant d’aborder la
présentation détaillée des principales techniques de contrôle de la
concurrence des transactions, basées sur l’utilisation des verrous, à savoir :
le verrouillage ternaire en deux phases, le verrouillage des insertions de
lignes et le verrouillage hiérarchique en deux phases.
Comme dans les autres systèmes qui utilisent des verrous, de base le
verrouillage permet à une transaction d’acquérir une autorisation pour un
accès à un item, en mode partagé ou en mode exclusif. Un verrouillage
désigné par <I, V, T> indique qu’un verrou de type « V » a été accordé à la
transaction « T » sur l’item « I ».
526
SGBD relationnels – Tome 1, État de l’art
527
Joachim TANKOANO
• Le verrouillage binaire
• Le verrouillage ternaire.
Les verrouillages de longue durée sont à éviter. Ils ont un impact négatif
sur le parallélisme entre les transactions et sur la réactivité de l’application.
528
SGBD relationnels – Tome 1, État de l’art
529
Joachim TANKOANO
Le verrouillage ternaire en deux phases est l’un des mécanismes de base sur
lesquels les SGBD s’appuient pour assurer le contrôle de l’exécution des
transactions concurrentes selon une approche pessimiste. Ce mécanisme
repose sur l’utilisation des trois opérations de verrouillage ternaire
présentées plus haut (« RLOCK I » pour le verrouillage à l’aide du verrou
partagé « S », « WLOCK I » pour le verrouillage à l’aide du verrou exclusif
« X » et « UNLOCK I » pour le déverrouillage) et sur un protocole de
prévention des interférences basé sur un verrouillage en deux phases.
530
SGBD relationnels – Tome 1, État de l’art
531
Joachim TANKOANO
sérialisable.
(9, 14)
T1 T2
(7, 12)
(1, 7)
(4, 12) (2, 9) (6, 14)
(1, 4) (6, 9)
(2, 6)
T4 T3
(1, 12)
▀
532
SGBD relationnels – Tome 1, État de l’art
(3, 12)
T2 T3
(2, 13)
Ces exemples montrent que toute seule, l’utilisation des verrous ternaires
n’est pas suffisante pour garantir la sérialisation des plans d’exécution de
transactions.
533
Joachim TANKOANO
534
SGBD relationnels – Tome 1, État de l’art
535
Joachim TANKOANO
R1(A), R2(B), W3(A), W1(B), W1(A), W2(B), C2, R3(B), R1(B), C1, W3(B), C3.
Verrous posés
Plan d’exécution Décisions gestionnaire verrous
A B
1 R1(A) <S, T1> Accorder verrou <A, S, T1>
2 R2(B) <S, T1> <S, T2> Accorder verrou <B, S, T2>
3 W3(A) <S, T1> <S, T2> Refuser verrou <A, X, T3>
Conflit avec <A, S, T1>
Mettre T3 en attente de T1
4 W1(B) <S, T1> <S, T2> Refuser verrou <B, X, T1>
Conflit avec <B, S, T2>
Mettre T1 en attente de T2
5 W2(B)) <S, T1> <S, T2> Accorder verrou <B, X, T2>
<X, T2>
6 C2 <S, T1> <X, T1> Lever verrou <B, S, T2>
W1(B) Lever verrou <B, X, T2>
Débloquer T1
Accorder verrou <B, X, T1>
7 W1(A) <S, T1> <X, T1> Accorder verrou <A, X, T1>
<X, T1>
R1(B) <S, T1> <X, T1> RAS (T1 a déjà un X sur B)
<X, T1>
C1 <X, T3> Lever verrou <A, S, T1>
W3(A) Lever verrou <A, X, T1>
Lever verrou <B, X, T1>
Débloquer T3
Accorder verrou <A, X, T3>
R3(B) <X, T3> <S, T3> Accorder verrou <B, S, T3>
W3(B) <X, T3> <S, T3> Accorder verrou <B, X, T3>
<X, T3>
C3 Lever verrou <A, X, T3>
Lever verrou <B, S, T3>
Lever verrou <B, X, T3>
Cet ordre est presque celui du plan d’exécution sériel où l’ordre d’exécution
des transactions est « T2 », « T1 », « T3 ».
▀
536
SGBD relationnels – Tome 1, État de l’art
Pour que l’insertion d’une nouvelle ligne par une transaction « T2 » ne soit
pas une ligne fantôme pour une transaction « T1 » qui répète plusieurs fois
l’exécution d’un ordre « SELECT » sur une table, cette table doit être
verrouillée par « T1 » à l’aide d’un verrou partagé et par « T2 » à l’aide d’un
verrou exclusif. En faisant de la sorte, cette table sera accessible, soit
simultanément par plusieurs transactions incluant « T1 » qui n'effectuent
que des opérations de lecture, soit de façon exclusive que par la transaction
« T2 » pour l’insertion de la nouvelle ligne. Cette façon de faire limite les
possibilités d’accès simultané aux lignes de cette table.
Une base de données peut être vue comme étant un item de grosse
granularité, composé d’une hiérarchie d’items plus élémentaires les uns que
les autres. Cette hiérarchie d’items peut être schématisée à l’aide d’un arbre,
comme ci-dessous, où les nœuds sont reliés entre eux par des relations de
composition.
537
Joachim TANKOANO
Base de données
Table 1 Table n
Ligne i
Ligne 1
Colonne 1 Colonne j
538
SGBD relationnels – Tome 1, État de l’art
X SIX IX S IS
X OUI OUI OUI OUI OUI
SIX OUI OUI OUI OUI NON*
IX OUI OUI NON* OUI NON*
S OUI OUI OUI NON NON
IS OUI NON* NON* NON NON
Les « NON* » concernent les paires de verrous d’intention qui ne sont pas
en conflit s’il n’existe pas de conflit au niveau des items de niveau inférieur
pour lesquels ils ont été posés.
539
Joachim TANKOANO
540
SGBD relationnels – Tome 1, État de l’art
541
Joachim TANKOANO
542
SGBD relationnels – Tome 1, État de l’art
T1 T2 T3 T4
1 Read (x)
2 Read (x)
3 Write (y)
4 Write (x)
5 Read (z)
6 Read (y)
7 Read (y)
8 Read (x)
9 Write (z)
10 Write (x)
543
Joachim TANKOANO
544
SGBD relationnels – Tome 1, État de l’art
écriture
4 T3 : Write = = 10 = 10 = = 10 = 10 Exécute :
(x) E(T2) E(T2) ROLLBACK de T3
= = car E(T3) = 12
13 13
E(T3) < R_E(x)
5 T2 : Read (z) = = 10 = 10 = = = 10 Exécute T2:Read(z)
E(T2) E(T2) E(T2) car E(T2) > W_E(z).
= = = R_E(z) prend la
13 13 13
valeur de
l’estampille de T2
qui devient la
dernière
transaction la plus
jeune qui a eu accès
à « z » en lecture
6 T1 : Read (y) = = 10 = = = = 10 Exécute T1:Read(y)
E(T2) E(T1) E(T2) E(T2) car E(T1) > W_E(y).
= = = = R_E(y) prend la
13 15 13 13
valeur de
l’estampille de T1
qui devient la
dernière
transaction la plus
jeune qui a eu accès
à « y » en lecture
7 T4 : Read (y) = = 10 = = = = 10 Exécute T4:Read(y)
E(T2) E(T1) E(T2) E(T2) car E(T4) > W_E(y).
= = = = R_E(y) conserve la
13 15 13 13
valeur de
l’estampille de T1
est toujours la
dernière
transaction la plus
jeune qui a eu accès
à « y » en lecture
8 T1 : Read (x) = = 10 = = = = 10 Exécute T1:Read(x)
E(T1) E(T1) E(T2) E(T2) car E(T1) > W_E(x).
= = = = R_E(x) prend la
15 15 13 13
valeur de
l’estampille de T1
qui devient la
dernière
545
Joachim TANKOANO
transaction la plus
jeune qui a eu accès
à « y » en lecture)
9 T1 : Write = = 10 = = = = Exécute T1:Write(z)
(z) E(T1) E(T1) E(T2) E(T2) E(T1) car E(T1) > R_E(z)
= = = = = et E(T1) > W_E(z).
15 15 13 13 15
W_E(z) prend la
valeur de
l’estampille de T1
qui devient la
dernière
transaction qui a eu
accès à « z » en
écriture
10 T4 : Write = = 10 = = = = Exécute :
(x) E(T1) E(T1) E(T2) E(T2) E(T1) ROLLBACK de T4
= = = = = car E(T4) = 14
15 15 13 13 15
E(T4) < R_E(x)
et E(T4) < W_E(x)
▀
546
SGBD relationnels – Tome 1, État de l’art
La norme SQL prévoit les quatre niveaux d’isolation ci-après, que les
fournisseurs de SGBD doivent permettre au développeur d’activer, en
fonction des exigences de son application, afin de rendre plus important le
547
Joachim TANKOANO
Le tableau qui suit résume les possibilités offertes par chaque niveau
d’isolation en termes de contrôle de la survenue des anomalies :
548
SGBD relationnels – Tome 1, État de l’art
Ce qui suit indique pour chaque niveau d’isolation, l’ordre d’exécution des
opérations de cette séquence, qui sera établi par l’ordonnanceur du SGBD.
READ UNCOMMITED
T1 : read (X) ; T2 : read (X) ; T2 : write (X) ; T1 : read (X) ; T2 : write (X) ; T2 : COMMIT;
T1 : COMMIT
READ COMMITED
T1 : read (X) ; T2 : read (X) ; T2 : write (X) ; T2 : write (X) ; T2 : COMMIT ; T1 : read (X);
T1 : COMMIT
REPEATABLE READ
T1 : read (X) ; T2 : read (X) ; T1 : read (X) ; T1 : COMMIT ; T2 : write (X) ; T2 : write (X);
T2 : COMMIT ;
SERIALIZABLE
T1 : read (X) ; T2 : read (X) ; T1 : read (X) ; T1 : COMMIT ; T2 : write (X) ; T2 : write (X);
T2 : COMMIT ;
▀
549
Joachim TANKOANO
Cette section présente d’abord les moyens sur lesquels les SGBD s’appuient
pour effectuer les différents types de reprises après incident. Ensuite, elle
aborde la présentation de la manière dont les SGBD procèdent pour
effectuer ou pour permettre à l’administrateur de la base de données
d’effectuer ces différents types de reprises.
Le journal des transactions est un fichier que les SGBD utilisent pour
enregistrer de façon systématique, sous forme d’historique, les
informations relatives aux modifications effectuées dans une base de
données, afin de disposer des données requises pour défaire ou pour refaire
ces modifications lors d’une reprise consécutive à un incident.
Pour chaque base de données, le journal des transactions est unique et doit
être enregistré sur une mémoire non volatile, différente de préférence de
celle de la base de données.
550
SGBD relationnels – Tome 1, État de l’art
Écriture
Journal
Lecture
Journal
Lecture
Journal
551
Joachim TANKOANO
Comme nous l’avons vu dans la section 7.5, pour réduire le temps d’accès
aux blocs des disques qui servent à stocker les données, les SGBD créent en
général en mémoire centrale, une zone tampon entre les applications et la
base de données, où ils copient une partie des blocs des disques qui
contiennent cette base de données.
Chaque fois qu’une application veut accéder à un bloc d’une table, ce bloc
est d’abord recherché dans cette zone tampon. Si ce bloc s’y trouve, l’accès
au disque est évité. Si ce bloc ne s’y trouve pas, le SGBD le récupère dans la
base de données et le recopie dans la zone tampon (éventuellement en
écrasant un autre bloc) avant d’exploiter son contenu.
552
SGBD relationnels – Tome 1, État de l’art
553
Joachim TANKOANO
554
SGBD relationnels – Tome 1, État de l’art
555
Joachim TANKOANO
Exécution DÉFAIRE
Avortée Terminée
556
SGBD relationnels – Tome 1, État de l’art
T1
T2
T3
T4
T5
Les reprises à chaud concernent les incidents, comme les coupures brutales
du courant ou les plantages du moteur SQL, qui n’ont comme conséquence
que la perte du contenu de la mémoire centrale. Cette perte se traduit
principalement par la perte du contenu des zones tampons où sont stockées
des copies de blocs du disque qui contiennent la base de données et les
informations sur les écritures dans le journal des transactions non encore
répercutées sur le disque.
557
Joachim TANKOANO
Les reprises à froid concernent les incidents graves qui ont comme
conséquence la destruction partielle ou complète du contenu de la base de
données sur le disque, rendant impossible tout retour en arrière à partir de
558
SGBD relationnels – Tome 1, État de l’art
sa version courante.
Ces reprises ne sont pas contrôlables par le SGBD. Elles nécessitent une
intervention de l’administrateur de la base de données, une sauvegarde de
la base de données et un journal des transactions qui contient les
informations relatives à toutes les actions effectuées après cette sauvegarde.
559
Joachim TANKOANO
560
SGBD relationnels – Tome 1, État de l’art
561
Joachim TANKOANO
562
SGBD relationnels – Tome 1, État de l’art
563
Joachim TANKOANO
564
SGBD relationnels – Tome 1, État de l’art
565
Joachim TANKOANO
566
SGBD relationnels – Tome 1, État de l’art
567
Joachim TANKOANO
42
42
44 42
40
48 40
37
47 37
40
48 47 40
568
SGBD relationnels – Tome 1, État de l’art
Le tableau qui suit fait la synthèse des verrous requis pour l’exécution des
différents ordres SQL de manipulation des données.
569
Joachim TANKOANO
570
SGBD relationnels – Tome 1, État de l’art
l’année
571
Joachim TANKOANO
572
SGBD relationnels – Tome 1, État de l’art
verrou
3 T3:W(x) <RS, T3> <X, T3> x1 Accorder verrou X
sur compte x
Créer copie x1 de
compte x
4 T2:R(x) <RS, T3> <X, T3> x1 Équivalent à
T2:W(x) UPDATE :
Refuser verrou RX
sur Comptes et
verrou X sur compte
x car en conflit avec X
sur compte x
Mettre T2 en attente
de T3
5 T1:COMMIT <RS, T3> <X, T3> x1 RAS
6 T3:W(y) <RS, T3> <X, T3> x1 <X, T3> y1 Accorder verrou X
sur compte y
Créer copie y1 de
compte y
7 T3:COMMIT x1 y1 Lever RS sur
T2 :ROLLBACK Comptes et X sur
compte x et compte y
Générer l’erreur
« CANNOT
SERIALIZE ACCESS
FOR THIS
TRANSACTION »
car T2 ne peut plus
continuer
8 T2:R(x) <RX, T2> <X, T2> x1, x2 y1 Équivalent à
T2:W(x) UPDATE :
Accorder verrou RX
sur Comptes et
verrou X sur compte
x
Créer copie x2 de
compte x
9 T2:R(y) <RX, T2> <X, T2> x1, x2 <X, T2> y1, y2 Équivalent à
T2:W(y) UPDATE :
Accorder verrou RX
sur Comptes et
verrou X sur compte
y
Créer copie y2 de
compte y
10 T2:COMMIT x1, x2 y1, y2 Lever RX sur
Comptes, X sur
compte x et compte y
573
Joachim TANKOANO
Les principaux moyens que le SGBD Oracle offre pour la gestion d’une
reprise après la survenue d’un incident sont :
• Le fichier de contrôle
• Le journal des transactions
• Les points de sauvegarde (ou de reprise)
• Les sauvegardes de la base de données.
a) Le fichier de contrôle
574
SGBD relationnels – Tome 1, État de l’art
575
Joachim TANKOANO
Une base de données doit avoir au moins deux groupes de fichiers copies
du fichier « REDO LOG ». Chaque groupe est constitué de fichiers
identiques pouvant se trouver sur des disques différents, ceci afin de
réduire les risques d’une perte accidentelle du fichier « REDO LOG ». Le
remplissage de ces groupes de fichiers s’effectue par rotation. Lorsque les
fichiers du groupe courant sont pleins, l’écriture dans le fichier « REDO
LOG » se poursuit avec les fichiers du groupe suivant. Une base de données
peut opérer soit en mode « ARCHIVELOG », soit en mode
« NOARCHIVELOG ». Le mode « ARCHIVELOG » amène, lors du
passage d’un groupe de fichiers à un autre, à archiver le contenu du
nouveau groupe avant de l’écraser. Quant au mode
« NOARCHIVELOG », il amène, lors du passage d’un groupe de fichiers à
un autre, à écraser le contenu du nouveau groupe, sans l’archiver.
576
SGBD relationnels – Tome 1, État de l’art
577
Joachim TANKOANO
Dans ces deux cas, la reprise vise la restauration des zones tampons perdues
dans leur dernier état validé avant l’incident. Elle s’effectue à l’aide de leurs
sauvegardes effectuées dans le fichier de contrôle lors du dernier point de
reprise et du fichier « REDO LOG » courant. Elle se déroule comme suit en
deux phases :
• Au cours de la 1ère phase, appelée « CACHE RECOVERY », les
images-après du fichier « REDO LOG » sont utilisées pour
réappliquer les modifications apportées aux bocs de données,
d’index et des « ROLLBACK SEGMENTS », de manière à restaurer
les zones tampons perdues dans leur dernier état validé avant
l’incident. A l’issue de cette phase, l’état de ces zones tampons doit
refléter les modifications validées avant l’incident mais peut aussi
refléter des modifications non validées
• Au cours de la 2ème phase, appelée « TRANSACTIONAL
RECOVERY », les modifications des transactions non validées sont
annulées en utilisant les images-avant multi-versions estampillées
des « ROLLBACK SEGMENTS » reconstitués.
Pour ce qui concerne la reprise à froid, elle se déroule en trois phases à l’aide
d’une sauvegarde complète de la base de données et d’un fichier « REDO
578
SGBD relationnels – Tome 1, État de l’art
9.6. Exercice
Rédigez par groupe de deux ou trois, en s’appuyant sur une revue de
documents techniques de référence, un rapport de présentation de la
gestion des accès concurrents et des reprises après incidents par le SGBD
MySQL et par le SGBD PostgreSQL.
Pour chacun de ces deux SGBD, ce rapport doit faire ressortir les
possibilités offertes pour :
• La démarcation des transactions à l’intérieur d’une session
utilisateur
• La gestion de l’exécution concurrente de plusieurs transactions
• La gestion des reprises après incident.
579
Joachim TANKOANO
BIBLIOGRAPHIE
Barghouti N. S. & Kaiser G. E. : Concurrency Control in Advance Database
Applications - ACM Computing Survey, vol. 23, n° 3, p. 270-317, Sept.
1991
Berenson H., Bernstein P., Gray J., Melton J., O’Neil E., & O’Neil P. : A
Critique of ANSI SQL Isolation Levels - Proc. of the ACM SIGMOD Conf.
on Management of Data (1995), pages 1–10.
Besancenot J., Cart M., Ferrié J., Guerraoui R., Pucheral Ph. & Traverson
B. : Les Systèmes Transactionnels : Concepts, Normes et Produits - Ed.
Hermès, Paris, 1997.
Eswaran K. P., Gray J. N., Lorie & Traiger I. L. : The Notions of Consistency
and Predicate Locks in a Database System - Communications of the ACM,
Volume 19, Number 11 (1976), pages 624–633.
580
SGBD relationnels – Tome 1, État de l’art
Kung H.T. & Robinson J.T. : On Optimistic Method for Concurrency Control
- ACM Transaction on Database Systems (TODS), vol. 6, n° 2, p. 213-
226, Juin 1981.
MIRANDA S. & BUSTA J-M. : L'art des bases de données, Tome 2, Les bases
de données relationnelles - 2è édition - Eyrolles, 1990
Silberschatz A., Korth H.F. & Sudarshan S. : Database system concepts, sixth
edition - McGraw-Hill, 2011
581