Introduction aux bases de données relationnelles
Introduction aux bases de données relationnelles
tel que la boule B(x,ε) centrée en x de rayon ε est inclue dans U. On vérifie
est continue en tout x∈X si et seulement si pour tout ouvert U ⊂Y, f−1(U) ⊂X
que xn est élément de U pour tout n≥ N. De même, une application f∶X →Y
est ouvert. Ainsi, les notions de convergence et de continuité peuvent être définies
à partir de la notion d’[Link] 4
Notons que la famille T de tous les sous-ensembles ouverts d’un espace mé-
cations continues
Le but de ce premier chapitre est de donner les bases de la théorie. On y
traitera successivement, dans six sections distinctes, des espaces topologiques (les
objets de la théorie), des applications continues (les flèches, ou morphismes, de
la théorie), des espaces métriques (une classe importante d’exemples), des bases
et sous-bases (une façon très pratique de se donner un espace topologique), de
diverses opérations sur les espaces topologiques, et de la notion de convergence
d’une suite.
I.1 Espaces topologiques
Soit X un ensemble.
Définition. Une topologie sur X est une famille T de sous-ensembles de X
(ii) Si {Ui}i∈I est un ensemble d’éléments de T , alors l’union ⋃i∈IUi est aussi
(iii) Si U1 et U2 sont des éléments de T , alors leur intersection U1 ∩U2 est aussi
élément de T ;
élément de T.
Un ensemble X muni d’une topologie T est appelé un espace topologique, et
les éléments de T sont appelés les ouverts de X.
Formellement, un espace topologique est donc la donnée d’une paire (X,T )
avec X un ensemble et T une topologie sur X. La plupart du temps, on s’au-
torisera un léger abus de notation en notant simplement l’espace topologique
par X.
Tentonsd’illustrercettedéfinitionabstraiteparunepremièreséried’exemples.
Tstd ={U ⊂Rn∣pour tout x∈U, il existe ε>0 tel que B(x,ε) ⊂U}.
centrée en x de rayon ε. Finalement, posons
est la seconde, qui se vérifie en montrant que Rn privé d’un nombre fini de
points est un ouvert pour la topologie standard.
3. Sur l’ensemble à deux éléments X= {1,2}, il existe exactement 4 topolo-
gies : la triviale, la discrète, ainsi que T1 ={∅,{1},X} et T2 ={∅,{2},X}.
Notons que ces deux dernières topologies ne sont pas comparables, ce qui
montre que cet ordre n’est pas total.1
1. Un exercice classique à ce stade, mais particulièrement rébarbatif, est d’énumérer le
nombre de topologies sur {1,2,3}. La réponse est : 29. Pour ceux que cette question pure-
ment combinatoire intéresse, les premières valeurs de la suite tn du nombre de topologies sur
l’ensemble {1,...,n} sont données par t1 = 1, t2 = 4, t3 = 29, t4 = 355, t5 = 6942, t6 = 209527,
t7 =9535241, t8 =642779354, t9 =63260289423, et t10 =[Link] I. ESPACES TOPOLOGIQUES 8
intersection T1 ∩T2 est une topologie sur X, moins fine que T1 et que T2.
4. Si T1 et T2 sont deux topologies sur un ensemble X quelconque, alors leur
A○
={x∈X∣A est un voisinage de x∈X}.
● L’adhérence de A dans X est le sous-ensemble A⊂X défini par
A={x∈X∣X∖A n’est pas un voisinage de x∈X}.
.
Avant de passer aux exemples, un certain nombre de remarques s’imposent.
1. Par les axiomes d’une topologie, ∅et X sont fermés, l’intersection d’une fa-
Remarques.
mille quelconque de fermés est fermée, et l’union de deux fermés est fermée.
Cela fournit une définition axiomatique d’un espace topologique à partir
des sous-ensembles fermés.2
2. En déroulant la définition, on obtient facilement que pour tout A⊂X, A○
est l’union de tous les ouverts de X contenus dans A :
=⋃
A○
U ouvert,U⊂A
U.
Par conséquent, A○ est le plus grand ouvert de X inclu dans A. En par-
ticulier, A○ est un ouvert, il est inclu dans A, et A est ouvert dans X si
et seulement si A○
= A. Ainsi, A est ouvert si et seulement si A est un
voisinage de chacun de ses éléments.
2. Il est également possible de donner une définition axiomatique d’un espace topologique
uniquement à partir de la notion de voisinage, et de manière plus étonnante, à partir de la
A= ⋂
contenant A :
F fermé,F⊃A
F.
Par conséquent, A est le plus petit fermé de X contenant A. En particu-
lier, A est un fermé, il contient A, et A est fermé dans X si et seulement
=X∖A et X∖A=X∖A○
.
si A=A.
4. Pour tout A⊂X, on a les égalités (X∖A)○
5. Pour tout A⊂X, le point 4 ci-dessus implique
∂A=A∖A○
=A∩(X∖A○)=A∩X∖A.
En particulier, les points 1 et 3 ci-dessus montrent que la frontière de A⊂X
est toujours fermée dans X.
Donnons maintenant quelques exemples.
Exemples d’intérieur et d’adhérence.
1. Dans un espace topologique discret X, tout sous-ensemble A⊂X est ouvert
et fermé. Ainsi, pour tout A⊂X, on a A○
=A=A et ∂A=∅.
ona doncA○
=X siA=X etA○
X sinon (tout sous-ensemble non-vide est dense dans X). Ainsi, ∂A= ∅
=∅sinon,tandis queA=∅siA=∅etA=
B(x,r)={y∈Rn∣d(x,y) <r}.
comme sous-ensemble A de X la boule centrée en x∈Rn de rayon r>0 :
l’ensemble des irrationnels est d’intérieur vide dans R. Pour cela, il suffit
de suivre la preuve du premier point ci-dessus en utilisant le fait suivant
vu en Analyse I : tout intervalle ouvert non-vide contient un rationnel.
I.2 Applications continues
Maintenant que nous avons défini les objets de la théorie, les espaces topolo-
giques, il s’agit d’en introduire les morphismes : les applications continues.
Définition. Soient X,Y deux espaces topologiques. Une application f∶X →Y
est dite continue si pour tout ouvert U de Y, f−1(U) est un ouvert de X.
(iii) Pour tout x∈X, on a la propriété suivante : pour tout voisinage V de f(x)
dans Y, f−1(V) est un voisinage de x dans X.
Si une application f∶X→Y satisfait la propriété (iii) pour un x∈X donné,
on dit que f est continue en x. Ainsi, l’équivalence des points (i) et (iii) dit
que f est continue si et seulement si f est continue en x pour tout x∈X.
3. Cette remarque montre que les espaces topologiques et les applications continues forment
ce que l’on appelle une caté[Link] I. ESPACES TOPOLOGIQUES 11
Démonstration. L’équivalence des deux premiers points est laissée en exercices;
premier. Soit donc f∶X →Y continue en tout x∈X, et fixons un ouvert U ⊂Y.
donc, f est continue en x. Vérifions finalement que le troisième point implique le
il existe y0 ∈Y tel que f(x)=y0 pour tout x∈X. Par conséquent, pour tout
1. [Link]ffet,sif∶X→Y estconstante,
S’il existe une telle application, les espaces X et Y sont dit homéomorphes,
noté X≅Y.
4. Ce sont les isomorphismes de la caté[Link] I. ESPACES TOPOLOGIQUES 12
Remarques.
1. La relation être homéomorphe est une relation d’équivalence sur la classe
des espaces topologiques. On aura tendance à identifier deux espaces topo-
logiques homéomorphes, dans le même sens qu’on a tendance à identifier
deux groupes isomorphes ou deux ensembles en bijection.
2. On vérifie facilement qu’une application f∶(X,TX)→(Y,TY) est un ho-
méomorphisme si et seulement si f est bijective et f définit une bijection
entre TX et TY.
3. L’ensemble Homeo(X) des homéomorphismes f∶X →X forme un groupe
pour la composition, qui agit sur X. Comme cela a été mentionné en intro-
duction, on peut voir la topologie comme l’étude des propriétés invariantes
par cette action.
4. On pourrait penser que toute application continue bijective est un homéo-
compte plus d’un élément. (Un exemple plus géométrique suivra sous peu.)
nue avec f(X) ⊂ Z ⊂ Y, et tâchons de montrer que g∶X →Z est continue. Soit
Pour démontrer le troisième point, supposons d’abord que f∶X→Y est conti-
(Ui∩f−1(V))=⋃
f−1(V)=X∩f−1(V)=⋃
(f∣Ui )−1(V).
i∈I
Comme chaque restriction f∣Ui ∶Ui → Y est continue, (f∣Ui )−1(V) est ouvert
i∈I
leur intersection est aussi un ouvert de X. Par l’équation ci-dessus, f −1(V) est
aussi un ouvert de X, et f est donc bien [Link] I. ESPACES TOPOLOGIQUES 14
Remarques.
1. Comme le troisième point de la proposition I.1, le quatrième point de la
proposition ci-dessus peut-être compris comme une formulation locale de
la continuité.
2. L’énoncé de ce dernier point est aussi valide si l’on remplace “ouvert” par
“fermé”, mais uniquement si l’ensemble I est fini!
Ce petit détour par la topologie induite était important pour la théorie géné-
rale, mais il nous permet aussi de donner des exemples non-triviaux d’homéomor-
phismes. Dans tous ces exemples, on considère les ensembles R et R2 munis de
la topologie standard, et l’on utilise le fait (non-encore démontré) que la notion
de continuité sur ces espaces est bien celle étudiée en Analyse I.
Exemples d’homéomorphismes.
1. Soit f∶R →R donnée par f(x)=4x+3. C’est une application bijective, d’in-
verse g∶R →R donnée par g(y)=(y−3)/4. Comme vous l’avez vu en Ana-
lyse I,detellesfonctionssontcontinues,etf estdoncunhoméomorphisme
voisinage de 1 ∈S1. Par la proposition I.1, g n’est pas continue (en 1 ∈S1).
voisinage de g(1)=f−1(1)=0 dans [0,1), mais g−1(U)=f(U) n’est pas un
par
dp(x,y)=(n
∑
∣xi−yi∣p)1/p
i=1
⎧⎪⎪⎨⎪⎪⎩
d(x,y)=
0 si x=y;
1 sinon.
La boule correspondante B(x,r) est réduite à {x} si r ≤ 1, et couvre X
tout entier si r>1.
La raison pour laquelle les espaces métriques sont abordés dans un cours de
topologie générale a déjà été évoquée en introduction : une métrique d sur un
U ∈Td ⇔ pour tout x∈U, il existe ε>0 tel que Bd(x,ε) ⊂U.
ensemble X induit une topologie Td sur X via
d(x,y), qui est positif puisque y est un élément de B(x,r). Par l’inégalité
du triangle, tout z∈B(y,ε) satisfait
d(x,z) ≤d(x,y)+d(y,z) <d(x,y)+ε=r,CHAPITRE I. ESPACES TOPOLOGIQUES 17
et est donc élément de B(x,r). Cela démontre l’inclusion voulue. On voit
donc que le fait que les boules sont des ouverts est une conséquence de
l’inégalité du triangle.
reviendra.
boule B(x,1). Il suit que U= {x} est ouvert, et par la seconde propriété
d’une topologie, que tout sous-ensemble de X est ouvert.
On dit que deux métriques d et d′ sur un même ensemble X sont équiva-
lentes s’il existe deux constantes positives c,c′ telles que
cd(x,y) ≤d′(x,y) ≤c
pour tous x,y ∈ X. On vérifie facilement qu’il s’agit bien d’une relation d’équi-
′d(x,y)
valence.
Proposition I.3. Deux métriques équivalentes induisent la même topologie.
Démonstration. Soient donc d et d′ deux métriques équivalentes sur un en-
semble X. Par définition, on obtient les inclusions suivantes entre les boules
′
r).
de Td. Cela signifie que tout x∈ U admet un r> 0 tel que Bd(x,r) ⊂ U. Par la
Vérifions à présent que Td′ est plus fine que Td. Soit U un élément quelconque
pour tous x,y ∈ Rn. Ainsi, les métriques dp sont toutes équivalentes entre
d∞(x,y) ≤dp(x,y) ≤n1/pd∞(x,y)
pour x,y ∈ X. On démontre que d est bien une métrique, qui induit la
1 +d(x,y)
puisque d(x,y) < 1 pour tous x,y ∈ Rn. En d’autres termes, (X,d) serait
d(x,y) ≤cd(x,y) <c pour tous x,y∈X,
et TdY ) si et seulement si pour tout ε>0, il existe δ>0 tel que pour tout x ′ ∈X
avec dX(x,x′) <δ, on a dY(f(x),f(x′)) <ε.
pour tout V ⊂ Y tel que BdY (f(x),ε) ⊂ V pour un certain ε> 0, il existe δ > 0
métrique peut être formulé en termes de boules, ce qui donne l’énoncé suivant :
tel que BdX (x,δ) ⊂ f−1(V). Le cas particulier V= BdY (f(x),ε) donne : pour
tout ε > 0, il existe δ > 0 tel que BdX (x,δ) ⊂ f−1(BdY (f(x),ε)). Ce dernier
pour tout x′ ∈X avec dX(x,x′) <δ, on a dY(f(x),f(x′)) <ε. Cela démontre une
énoncé est équivalent à l’énoncé souhaité : pour tout ε>0, il existe δ>0 tel que
direction.
Pour vérifier l’autre direction, notons que dans la chaîne d’implications ci-
italiques. Supposons donc que pour tout ε>0, il existe δ>0 tel que B dX (x,δ) ⊂
dessus, il n’y a que des équivalences à une exception près : celle marquée en
f−1(BdY (f(x),ε)), et fixons V ⊂Y tel que BdY (f(x),ε) ⊂V pour un certain ε>
[Link]èse,ilexisteδ>0 telqueBdX (x,δ) estincludansf−1(BdY (f(x),ε)),
qui est lui-même inclu dans f−1(V). Cela montre l’autre direction et conclut la
preuve.
Les propositions I.1 et I.4 donnent immédiatement le corollaire suivant.
nue si et seulement si pour tout x∈X et tout ε>0, il existe δ>0 tel que si x′ ∈X
CorollaireI.5. Une application f∶X→Y entre deux espaces métriques est conti-
de X n’est pas toujours une base d’une topologie! Il existe des conditions néces-
(2) pour tous B1,B2 ∈B et tout x∈B1 ∩B2, il existe B∈B avec x∈B⊂B1 ∩B2.
(1) X=⋃B∈B B, et
Démonstration. Supposons tout d’abord que B ⊂ P(X) est une base d’une
topologie sur X, c’est-à-dire, que l’ensemble T des unions d’éléments de B est
une topologie. Dans ce cas, on a en particulier que X est élément de T , et donc
fait que B1 ∩B2 est union d’éléments de B. Cela implique le second point.
Pour montrer la réciproque, fixons B ⊂ P(X) qui satisfait aux points (1 )
et (2 ); nous devons vérifier que le sous-ensemble T ⊂ P(X) formé par les
unionsd’élémentsdeB satisfaitlestroisaxiomesd’[Link],
l’ensemble vide est égal à l’union vide, est appartient donc bien à T , tandis
que X est élément de T par le point (1 ). Le second axiome est immédiat,
= ⋃jB′
j,
=⋃i,jBi∩B′
d’oùU∩U′
[Link]’àmontrerquepourtousB1,B2 ∈
B, l’intersection B1 ∩B2 est une union d’éléments de B, ce qui découle du second
point. En effet, pour tout x∈B1 ∩B2, il existe B(x) ∈B avec x∈B⊂B1 ∩B2 ;
cela implique l’égalité B1 ∩B2 =⋃x∈B1∩B2 B(x), qu’il fallait dé[Link] I. ESPACES TOPOLOGIQUES 22
Ce résultat implique l’énoncé suivant pour les sous-bases.
Corollaire I.7. Un sous-ensemble S⊂P(X) est une sous-base d’une topologie
sur X si et seulement si X=⋃U∈SU.
Démonstration. Si S est une sous-base d’une topologie T , cela signifie que tout
X= ⋃
d’inclusions
U⊂⋃
B⊂X.
U∈S
B∈B
éléments B1,B2 de B est à nouveau élément de B. Ainsi, pour tout x∈B1 ∩B2,
Pour voir la seconde, notons que par définition de B, l’intersection de deux
seulement si pour tout x∈X et tout B∈B qui contient x, il existe B′ ∈B′
sont deux bases sur un ensemble X, alors TB′ est plus fine que TB si et
tions x∶{1,2}→X1 ∪X2 avec x(i)=∶ xi ∈ Xi pour tout i ∈ {1,2}. Notons que
De manière plus précise, on peut voir ce produit comme l’ensemble des applica-
pour tout i∈{1,2}, ce produit admet une projection naturelle πi∶X1 ×X2 →Xi
qui envoie l’élément x sur sa ième coordonnée xi.
Plus généralement, le produit d’une famille d’ensembles {Xi}i∈I indexée par
un ensemble I quelconque est l’ensemble
∏
i∈I
Pour tout j∈I, on a la projection naturelle πj∶∏i∈IXi →Xj définie par πj(x)=
i∈I
défini par
clairement la condition du corollaire I.7; c’est donc une sous-base d’une topologie
sur ∏i∈IXi appelée la topologie produit. La base correspondante est donnée
Par définition, les ouverts de la topologie produit sont donc les unions d’éléments
de la base B ci-dessus.
Remarques.
1. Si l’ensemble I d’indices est fini, alors B et B′ sont égales; dans ce cas, la
topologie des boîtes et la topologie produit coïncident. Mais en général, la
topologie produit est moins fine que la topologie des boîtes.
2. La sous-base S est exactement formée des sous-ensembles de ∏i∈IXi qui
doivent être ouverts pour que les projections πj soient continues. Ainsi, par
la remarque 1 de la section précédente, la topologie produit est la topologie
la moins fine telle que toutes les projections soient continues.
i (Ui) ⊂X
=f−1
née par fi(t)=t; elle est donc continue, ce qui implique que l’application f
elle-même est continue pour la topologie produit. Ainsi, le problème sou-
levé ci-dessus pour la topologie des boîtes n’en est plus un pour la topologie
produit.
3. Considérons enfin le cas d’une famille finie de droites réelles munies de la
topologie standard, Xi = R pour tout i∈ I= {1,...,n}. Alors, l’ensemble
produit correspondant n’est autre que Rn, sur lequel les topologies des
boîtesetproduitcoï[Link]éeparTB
habituellement l’assertion (x,x′) ∈R par xRx′. Comme vous le savez, une rela-
tion R sur un ensemble X est une relation d’équivalence si :
(ii) R est symétrique : pour tous x,x′ ∈X, si xRx′ alors x′Rx.
(i) R est réflexive : pour tout x∈X, xRx.
(iii) R est transitive : pour tous x,x′,x′′ ∈X, si xRx′ et x′Rx′′, alors xRx′′
.
de X défini par
′ ∈X∣ x∼x
[x]∶={x
′},
appelé la classe d’équivalence de x. Notons que par réflexivité, xappartient à sa
classe d’équivalence. De plus, par symétrie et transitivité, deux classes d’équiva-
lence [x] et [x′] sont soit identiques (si x∼x′), soit disjointes (sinon). Ainsi, lesCHAPITRE I. ESPACES TOPOLOGIQUES 27
classes d’équivalence forment une partition de X, c’est-à-dire que X est l’union
disjointe de ces classes. Finalement, on note X/∼ l’ensemble de ces classes d’équi-
valence, appelé ensemble quotient, et
π∶X→X/∼
la projection de x∈X sur sa classe [x].
1 +x2
2 = y2
1 +y2
2 . Les classes d’équivalence
correspondantes sont les cercles centrés en l’origine, ainsi que l’origine elle-
de rayon ∥x∥. Ainsi, l’application f∶R2 →R donnée par f(x)= ∥x∥ passe
même. La projection π envoie un élément x= (x1,x2) de R2 sur le cercle
est habituellement noté X/A. La projection π∶X →X/A identifie tous les
est surjective, et f(t)= f(t′) ⇔t∼A t′. Ainsi, elle passe au quotient et
section I.2, f enroule l’intervalle [0,1] autour du cercle.) Cette application
on définit une topologie sur X/∼ appelée la topologie quotient. L’espace topo-
logique ainsi obtenu est appelé l’espace quotient.
Remarques.
1. On vérifie facilement qu’il s’agit d’une topologie, la plus fine sur l’ensemble
quotient telle que π soit [Link] I. ESPACES TOPOLOGIQUES 28
2. Soient Y un espace topologique et f∶X →Y une application qui passe au
quotient, induisant g∶X/∼→Y telle que f= g○π. Alors, f est continue si
et seulement si g est continue.
1 +x2
2 =y2
1 +y2
2 . La topologie standard sur R2
définit donc une topologie sur l’ensemble quotient. Nous allons maintenant
vérifier que cet espace quotient est homéomorphe à [0,∞) (muni de la
topologie induite par la topologie standard sur R).
Comme on l’a vu, l’application f∶R2 →R donnée par f(x)=∥x∥ induit une
bijection g∶R2/∼→[0,∞). Comme f est continue (Analyse I), g est une
c’est-à-dire que g est ouverte; ainsi, il faut montrer que si U ⊂R2/∼ est tel
bijection continue, et il reste uniquement à vérifier que g−1 est continue,
d’où [0,1]/{0,1} ≅ S1. Ainsi, le cercle est obtenu en recollant les deux ex-
Nous allons maintenant montrer que g est en fait un homéomorphisme,
plication ouverte. Soit donc U ⊂ [0,1]/{0,1} tel que π−1(U) ⊂ [0,1] est
Exactement comme ci-dessus, il nous suffit de vérifier que g est une ap-
∖[0,∞)→(0,1)
1
termine la preuve.
Comme on le voit sur les exemples ci-dessus, il est souvent facile de trouver
une bijection continue de la forme X/∼→Y, mais il est plus difficile de montrer
que cette application est un homémorphisme. Pour cette raison, il est très utile
9. Notons que f n’est pas ouverte, puisque f([0,1/2)) n’est pas un voisinage de f(0)=1 ∈
de trouver une classe d’espaces sur lesquels toute application continue bijective
Dans ce cas, on dit que la suite (xn) converge vers x ∈X, noté xn →x.
Remarques.
pour tout B∈Bx, il existe un entier N tel que n≥N ⇒xn ∈B.
1. Si Bx est une base de voisinages de x∈X, alors xn →x si et seulement si
{Bd(x,ε) ∣ ε>0} des boules centrées en x∈X forme une base de voisinages
suitesdansl’espacetopologique(X,Td).Commeonl’avu,l’ensembleBx =
et) seulement s’il existe N tel que n≥N ⇒xn =x. Ainsi, les seules suites
convergentes dans un espace discret sont les suites qui sont constantes à
partir d’un certain indice. C’est ce qu’on appelle une suite stationnaire.
3. Soient X un espace topologique, I un ensemble, et XI
= {f∶I →X} l’es-
pace produit correspondant muni de la topologie produit. Tentons de com-
prendre quand une suite (fn) converge vers une limite f dans XI
.
Par définition, la topologie produit est engendrée par la sous-base
Nous allons vérifier que là encore, comme dans un espace discret, les seules
Soitdonc(xn) unesuitequiconvergeversx∈X,etU ∶=(X∖{xn}n∈N)∪{x}.
suites convergentes sont les suites stationnaires.
pour tout x≠y∈X, il existe des ouverts U,V ⊂X disjoints avec x∈U et y∈[Link] I. ESPACES TOPOLOGIQUES 32
Définition. Un espace topologique X est dit séparé (ou Hausdorff, ou T2) si
sont deux éléments distincts d’un espace séparé, il existe des ouverts U,V ⊂ X
avec y ≠ x; il s’agit de vérifier que (xn) ne converge pas vers y. Comme x et y
disjoints, cela signifie que pour tout n≥N, on a xn ∉V. Puisque V est un ouvert
de X qui contient y, la suite (xn) ne converge donc pas vers y∈X.
Exemples d’espaces séparés.
1. Tout espace discret est séparé : il suffit de choisir U={x} et V={y}.
2. Si X est un ensemble avec au moins deux éléments muni de la topologie
triviale, alors X n’est pas séparé.
3. Un ensemble X infini muni de le topologie cofinie Tf n’est pas séparé,
puisque deux ouverts non-vides ne sont jamais disjoints!
Pourlamêmeraison,unensembleXnon-dénombrablemunidelatopologie
codénombrable Tc n’est pas séparé.
4. Toutespacemétrique(X,d) estséparé.Eneffet,sixetysontdeuxéléments
distincts de X, alors d(x,y)=∶2r est positif par définition d’une distance.
On peut alors choisir U=B(x,r) et V=B(y,r). Ce sont des ouverts de X,
et l’inégalité du triangle implique facilement qu’ils sont disjoints.
Cedernierexemplemontrequ’enfait,toutespacemétrisableestséparé.Ainsi,
si un espace n’est pas séparé, il n’est pas métrisable. Cela donne une nouvelle
preuve (en fait, la même) qu’un ensemble muni de la topologie triviale n’est
jamais métrisable sauf s’il compte moins de deux éléments. Cela montre égale-
ment que pour X infini (resp. X non-dénombrable), l’espace topologique (X,T f)
(resp. (X,Tc)) n’est pas métrisable.
Voyons à présent comment la propriété topologique “être séparé” se comporte
relativement auxdiversesopérations sur lesespaces. Cesrésultats sont trèsfaciles
à vérifier, les preuves sont donc en exercice.
Remarques.
1. Si Y est un sous-espace d’un espace séparé X, alors Y est aussi séparé.
2. Si {Xi}i∈I est une famille d’espaces séparés, alors ∏i∈IXi est aussi séparé.
3. Si X est un espace séparé muni d’une relation d’équivalence, alors l’espace
quotient X/∼ n’est en général pas séparé.
À ce stade, il est naturel de se demander si nous n’avons pas exigé une condi-
tion trop forte pour l’unicité de la limite. En d’autres termes :CHAPITRE I. ESPACES TOPOLOGIQUES 33
Question 1. S’il y a unicité de la limite dans un espace topologique, cet espace
est-il séparé?
Un premier élément de réponse est : pas toujours! En effet, nous avons déjà
vu qu’un espace (X,Tc) avec X non-dénombrable n’est pas séparé, malgré le
fait que les seules suites convergentes sont stationnaires, et donc, admettent une
limite unique. Nous allons donner une réponse plus complète très prochainement.
En attendant, nous allons nous intéresser à la notion d’ensemble séquen-
tiellement fermé. Pour cela, fixons un espace topologique X. Pour tout sous-
ensemble A⊂X, notons
l’ensemble des limites de suites dans A. Comme toutes les suites stationnaires
sont convergentes, on a l’inclusion A⊂A′
.
On dit que A est séquentiellement fermé dans X si A′
= A. En d’autres
termes, A est séquentiellement fermé dans X si toute limite d’une suite dans A
est dans A.
Exemples d’ensembles séquentiellement fermés.
Question 2. Dans quel espace topologique a-t-on que tout sous-ensemble séquen-
tiellement fermé est fermé?
Nous allons donner une réponse satisfaisante à cette question, mais en at-
tendant, bornons-nous à montrer que ce n’est pas toujours le cas. Pour ce faire,
considérons à nouveau l’exemple d’un ensemble X non-dénombrable muni de la
topologie codénombrable Tc. Comme on l’a vu en exemple 1 ci-dessus, tout sous-
ensemble Ade X est séquentiellement fermé dans X. En revanche, comme X est
non-dénombrable, il existe des sous-ensembles non-fermés dans X, comme par
exemple A=X∖{x}.
Avant de revenir à cette question, nous allons discuter une dernière notion
si, pour toute suite (xn) dans X avec xn →x∈X, on a f(xn)→f(x) ∈Y.
Proposition I.10. Si f∶X →Y est continue en x∈X, alors f est séquentielle-
ment continue en x∈X.
dans X avec xn →x∈X; il s’agit de vérifier que f(xn)→f(x) ∈Y. Pour ce faire,
Démonstration. Soit donc f∶X→Y est continue en x∈X, et soit (xn) une suite
fixons un ouvert V de Y avec f(x) ∈V. Comme f est continue en x∈X et V est
un voisinage de f(x) ∈ Y, f−1(V) est un voisinage de x∈ X; il existe donc un
ouvert U de X avec x∈U ⊂f−1(V). Comme (xn) converge vers x∈X, il existe N
tel que n≥N ⇒xn ∈U. Pour ce même N, on a donc n≥N ⇒f(xn) ∈f(U) ⊂V.
Cela démontre que f(xn) converge vers f(x) ∈Y et termine la preuve.
À nouveau, il est naturel de se demander quand la réciproque est valide.
Question 3. Dans quel espace topologique a-t-on que toute fonction séquentielle-
ment continue en un point est continue en ce point?
À cette question aussi, nous allons répondre très prochainement; en atten-
dant, nous allons simplement montrer que ce n’est pas toujours le cas. Pour ce
application est séquentiellement continue en tout x∈X, puisque les seules suites
convergentesdans(X,Tc) sontlessuitesstationnaires,quisontévidemmentaussi
convergentes dans (X,Tdisc). Cette application n’est néanmoins continue en au-
cun x∈ X, puisque {x} est un voisinage de x∈ (X,Tdisc) mais f−1({x})= {x}
n’est pas un voisinage de x∈(X,Tc) (puisque X∖{x} est non-dénombrable).
La réponse à ces trois questions passe par la définition suivante.
Définition. Un espace topologique X est dit à base dénombrable de voisi-
nagessipourtoutx∈X,ilexisteunebasedevoisinagesBx quiestdénombrable.
Notons que cette notion est évidemment une notion topologique, c’est-à-dire,
invariante par homé[Link] I. ESPACES TOPOLOGIQUES 35
Exemples d’espaces à base dénombrable de voisinages.
1. Tout espace métrique (X,d) est à base dénombrable de voisinages. En effet,
Bx ={B(x,1/n) ∣ n≥1}
pour tout x∈X, l’ensemble dénombrable
est une base de voisinages de x∈X. Cela démontre en fait que tout espace
métrisable est à base dénombrable de voisinages.
2. Un ensemble X non-dénombrable muni de la topologie cofinie Tf n’est pas
à base dénombrable de voisinages (et n’est donc pas métrisable). C’est sans
doute l’exemple le plus simple de tel espace topologique, preuve que la plu-
part des espaces qu’on “rencontre ” sont à base dénombrable de voisinages.
Pour démontrer ce fait, supposons par l’absurde que Bx ={Bn}n≥1 est une
base dénombrable de voisinages (ouverts) de x∈ X. Par définition de Tf,
⋃n≥1(X∖Bn) est dénombrable. Comme X ne l’est pas, il existe y∉A, i.e.
cela signifie que X∖Bn est fini pour tout n≥ 1, ce qui implique que A=
y∈X∖A=X∖ ⋃
(X∖Bn)= ⋂
B n,
n≥1
n≥1
et l’on peut choisir y≠x. Par conséquent, X∖{y} est un voisinage de x∈X
qui ne contient aucun des Bn. L’ensemble Bx n’est donc pas une base de
voisinages de x∈X.
La même preuve montre qu’un ensemble X non-dénombrable muni de la
topologie codénombrable Tc n’est pas à base dénombrable de voisinages.
Il est grand temps de donner la réponse aux trois questions ci-dessus.
Théorème I.11. Soit X un espace topologique à base dénombrable de voisinages.
(1) L’espace X est séparé si et seulement s’il y a unicité de la limite de toute
suite convergente dans X.
(2) Un sous-ensemble A⊂ X fermé dans X si et seulement si A est séquentiel-
n ⊂B′′
n est un voisinage de x∈X, il existe B′
n ouvert conte-
1 ∩⋅⋅⋅∩B′
nant x; la suite Bn = B′
voisinages ouverts de x∈X, qui est une base de voisinages de xpuisque Bn ⊂B′′
n fournit une suite Bx = {Bn} décroissante de
alors A⊂A⊂A′, ce qui implique A=A′ ⇒A=A. Soit donc x∈A, ce qui équi-
vaut à dire que tout ouvert de X contenant xintersecte A. Par le lemme I.12, il
existe une base {Bn} décroissante de voisinages ouverts de x∈X. Comme Bn est
un ouvert de X contenant x, il intersecte A, et l’on peut donc choisir x n ∈Bn∩A.
Cela forme une suite (xn) d’éléments de Aqui converge vers xpar le lemme [Link] I. ESPACES TOPOLOGIQUES 37
Ainsi, x est bien limite d’une suite dans A, et donc un élément de A ′, ce qui
démontre le deuxième point.
Passonsenfinautroisiè[Link]
proposition I.10. La réciproque utilise les mêmes techniques que les deux preuves
ou Y ⊂V.
Comme d’habitude, nous allons commencer par illuster cette définition avec
quelques exemples faciles.
Exemples d’espaces connexes.
1. Tout ensemble muni de la topologie triviale est connexe.
2. Un ensemble X avec #X > 1 muni de la topologie discrète n’est pas
connexe. En effet, si X compte au moins deux éléments, les ouverts U={x}
pace topologique X avec ⋂i∈IAi non-vide, alors le sous-espace ⋃i∈IAi est connexe.
PropositionII.1. Si {Ai}i∈I est une collection de sous-espaces connexes d’un es-
pour tout i ∈ I. Pour montrer que Y= ⋃i∈IAi est connexe, considérons donc
Démonstration. Comme l’intersection est non-vide, fixons x∈ X tel que x∈ Ai
x∉ ⋂
puisque A et V sont disjoints. Ainsi,
F fermé,F⊃A
F=A,CHAPITRE II. CONNEXITÉ ET COMPACITÉ 40
ce qui contredit x∈B⊂A. On a donc bien x∈U, ce qui conclut la preuve.
La démonstration du prochain résultat est très facile, mais l’importance de
cet énoncé l’élève sans contestation possible au rang de théorème.
Théorème II.3. Si f∶X → Y est une application continue avec X connexe,
alors f(X) est connexe.
Démonstration. Par le troisième point de la proposition I.2, l’application surjec-
tive g∶X →Z= f(X) obtenue à partir de f en restreignant l’espace d’arrivée
=
g−1(U) et V′
=g−1(V) sont des ouverts de X. De plus, les propriétés élémentaires
U′ ∩V′
de théorie des ensembles donnent
U′ ∪V′
=g−1(U)∩g−1(V)=g−1(U∩V)=g−1(∅)=∅,
=g−1(U)∪g−1(V)=g−1(U∪V)=g−1(Z)=X.
Finalement, comme g est sujective et U non-vide, l’ensemble U′
= g−1(U) est
aussi non-vide, et de même pour V′. Les ouverts U′ et V′ forment donc une
décompositionnon-trivialedeX,cequiestimpossiblepuisqueXestconnexe.
Théorème II.4. Un espace produit X1 ×⋅⋅⋅×Xn est connexe si et seulement
chaque espace Xi est connexe.
la projection πi∶X1 ×⋅⋅⋅×Xn →Xi est continue. Par le théorème II.3, l’image Xi
Démonstration. Commençons par supposer le produit connexe. Pour chaque i,
l’intersection ⋂x∈XTx contient l’élément (a,b); elle est donc non-vide, et cette
la proposition II.1 implique que Tx =X×{b}∪{x}×Y est connexe. Finalement,
Démonstration. Supposons par l’absurde qu’il existe a< b dans R tels que l’in-
Notons que cet ensemble S est borné, puisqu’il est inclu dans (a,b), et non-vide,
puisqu’il contient u. Ainsi, il admet un supremum s0 =sup S. Par définition, cela
signifie que s0 est un majorant de S (i.e. s≤s0 pour tout s∈S), et s0 est le plus
petit des majorants de S (i.e. si s≤s′ pour tout s∈S, alors s0 ≤s′).
En effet, si tel n’est pas le cas, il existe s ∈ S avec x < s; on aurait donc x ∈
Nous affirmons maintenant que tout x∈V avec u<x est un majorant de S.
Supposons tout d’abord que s0 ∈ U. Comme U est ouvert, il existe ε> 0 tel
ce qui concluera la preuve.
que (s0−ε,s0 +ε) ⊂U. Notons que [u,s0) ⊂U. (Sinon, on aurait un x∈(u,s0)∩V
est impossible.) Ainsi, on a l’inclusion [u,s0 +ε/2] ⊂U, ce qui signifie que s0 +ε/2
qui serait un majorant de S par l’affirmation ci-dessus, et plus petit que s0 ce qui
Supposons enfin que s0 ∈V. Comme V est ouvert, il existe ε>0 tel que (s0−
appartient à S. C’est impossible puisque s0 est un majorant de [Link] II. CONNEXITÉ ET COMPACITÉ 42
ε,s0 +ε) ⊂ V et u< s0−ε. Par l’affirmation ci-dessus, s0−ε/2 est un majorant
de S, ce qui est impossible puisque s0 est le plus petit de ces majorants.
Corollaire II.6. La droite réelle R est connexe, de même que tous les inter-
valles (a,b), [a,b), (a,b], [a,b], (−∞,a), (−∞,a], (a,∞) et [a,∞).
Démonstration. Comme on l’a vu, tous les intervalles ouverts de R sont homéo-
morphes. Puisque (a,b) est connexe par le théorème II.5, il en va donc de même
Un espace topologique X est dit connexe par arcs si pour tout x,y ∈ X, il
à y est une application continue f∶[a,b]→X telle que f(a)=x et f(b)=y.
f−1(U ∪V)= f−1(X)= [a,b]. Cela signifie que [a,b] n’est pas connexe, ce qui
=
1 Alors, X
est connexe par arcs, et donc connexe. En effet, pour tout x,y ∈ X, on
peut choisir le chemin f∶[0,1]→X donné par f(t)=tx+(1−t)y, qui reste
2. Pour tout n> 1 et tout x∈ Rn, l’espace Rn ∖{x} est connexe par arcs, et
dans X par hypothèse.
donc connexe.
et donc connexe.
Àl’aidedecettenotiondeconnexitéetdesexemplesci-dessus,onpeutdonner
quelques premières applications.
Trois applications de la connexité.
1. Pour n>1, les espaces R et Rn ne sont pas homéomorphes.2
Pour montrer cette affirmation, supposons par l’absurde qu’il existe un
{0}= (−∞,0) ∪(0,∞) n’est pas connexe alors que Rn ∖{h(0)} l’est pour
tout n>1, comme on l’a vu ci-dessus. Une contradiction.3
2. Touteapplicationcontinuef∶S1 →R admetunx∈S1 telquef(x)=f(−x).
∣f(x)−f(−x)∣,
g(x)=
puisqueledénominateurestnon-nulparhypothè[Link](−x)=−g(x),
cetteapplicationestsurjective,d’oùg(S1)={−1,1}.CommeS1 estconnexe
1. Attention, la convexité n’est pas une notion topologique!
2. À ceux qui pensent que c’est “évident”, il est bon de rappeler que pour tout n>1, il existe
une application continue surjective R → Rn, ce qu’on appelle une courbe de Peano.
3. En fait, on peut montrer que si Rn et Rm sont homéomorphes, alors n = m. Mais cela
nécessite des outils bien plus puissants.
f(x)−f(−x)CHAPITRE II. CONNEXITÉ ET COMPACITÉ 44
(on l’a vu ci-dessus), le théorème II.3 implique que g(S1)={−1,1} est aussi
connexe. Ce n’est pas le cas, car {−1,1} est un espace discret.4
3. Toute application continue f∶[0,1]→[0,1] admet un point fixe.
Sinon, on peut considérer l’application continue g∶[0,1]→{−1,1} définie
par g(x)= f(x)−x
∣f(x)−x∣. Comme g(0)= 1 et g(1)=−1, g est surjective. On
conclut comme ci-dessus.5
Remarques.
1. La réciproque de la proposition II.8 n’est pas vraie : il existe des espaces
connexes qui ne sont pas connexes par arcs. En voici un exemple, illustré
en Figure II.1.
Soit f∶(0,1)→R2 l’application donnée par f(t)= (t,sin(1/t)). C’est une
application continue, puisque chacune de ses coordonnées est une fonction
théorème II.5, son image A=f((0,1)) ⊂R2 est aussi connexe par le théo-
continue de (0,1) dans R. Comme l’intervalle (0,1) est connexe par le
rè[Link]’estautrequelegraphedelafonctiont↦sin(1/t).
sions A⊂X⊂A, ce qui implique que X est toujours connexe par la proposi-
[Link],Xn’estpasconnexepararcs,cariln’estpaspossible
de relier l’origine x = (0,0) à un point de A, par exemple y= (1,sin(1)),
par un chemin continu dans X. La raison en est que la fonction t↦sin(1/t)
ne s’étend pas en une fonction continue en l’origine, comme vous l’avez vu
en Analyse I.
Figure II.1 – Un exemple d’espace connexe mais pas connexe par arcs.
4. Plus généralement, il est possible de montrer que toute application continue f∶ Sn
Rn admet un x ∈ Sn tel que f(x)= f(−x). Le cas n = 2, que vous verrez en Topologie
→
algébrique, admet l’énoncé concret suivant : À tout moment, sur terre, il existe deux points
antipodaux du globe qui ont même température et même pression.
5. Plus généralement, le théorème du point fixe de Brouwer affirme que toute application
={x∈Rn ∣ ∥x∥ ≤1} dans lui-même admet un point [Link] II. CONNEXITÉ ET COMPACITÉ 45
continue du disque Dn
ouvert, i.e. que U est fermé. Ainsi, U ⊂ X est ouvert, fermé et non-vide.
et donc que U est ouvert. De la même manière, on montre que X∖U est
recouvrement fini.
Celaimpliquedirectementquelesintervallesouverts(a,b),(−∞,a) et(a,∞)
compact, il existe i1,...,im ∈I tels que X=X∖Y ∪Ui1 ∪⋅⋅⋅∪Uim . Cela signifie
est ouvert, et {X∖Y}∪{Ui}i∈I est un recouvrement ouvert de X. Comme X est
que Y est inclu dans Ui1 ∪⋅⋅⋅∪Uim : on a donc trouvé un sous-recouvrement fini
que Y est fermé dans X, i.e. que X∖Y est ouvert dans X, ou en d’autres termes,
V ∩Y=
de X. Il contient x puisque chaque Vy contient x. Finalement,
⋂
m
Vyi ∩Y ⊂
i=1
⋂
m
Vyi ∩
i=1
⋃
m
Uyj ⊂
j=1
⋃
m
i.e. une famille d’ouverts Ui ⊂ Y tels que f(X) ⊂ ⋃i∈IUi. Comme f est conti-
nue, f−1(Ui) ⊂X est ouvert pour tout i∈I. De plus, on a les égalités ensemblistes
X=f−1(f(X))=f−1(⋃
i∈I
Ui)=⋃
i∈I
f−1(Ui).CHAPITRE II. CONNEXITÉ ET COMPACITÉ 48
tion I.1, il suffit de montrer que pour tout F ⊂ X fermé, f(F) ⊂ Y est fermé.
Comme F est fermé dans X compact, F est compact par la proposition II.9.
est compact dans Y séparé, f(F) ⊂Y est fermé par la proposition II.10.
Comme f est continue, f(F) est compact par le théorème II.11. Puisque f(F)
Remarques.
1. En section I.2, on avait vu deux exemples d’applications continues qui ne
sont pas des homéomorphismes; nous allons maintenant voir que chacun de
fini, alors (X,Tdisc) est compact. Le problème est que l’espace (X,Ttriv)
n’estjamaisséparésiXcompteaumoinsdeuxélé[Link]
étaitl’applicationexponentiellef∶[0,1)→[Link],S1 estbienséparé,
mais [0,1) n’est pas compact, comme on l’a vu.
2. Le corollaire II.12 est extrêmement utile. Rappelons-nous par exemple les
difficultés rencontrées en sous-section I.5.2 pour vérifier que l’application
continue bijective [0,1]/{0,1}→S1 induite par l’exponentielle est un ho-
méomorphisme! Cela sera une conséquence immédiate du corollaire II.12,
une fois que l’on aura démontré que [0,1] est compact.
3. D’une manière plus générale, la discussion en sous-section I.5.2 et le co-
rollaire II.12 impliquent directement l’énoncé suivant : Soit f∶X →Y une
application continue avec X compact et Y séparé. Alors, f induit un homéo-
morphisme entre l’espace quotient X/∼et f(X), où la relation d’équivalence
sur X est définie par x∼x′ si et seulement si f(x)=f(x′).
Voici un dernier résultat général sur les espaces compacts.
Théorème II.13. Un espace produit X1 ×⋅⋅⋅×Xn est compact si et seulement
chaque espace Xi est compact.
la projection πi∶X1 ×⋅⋅⋅×Xn →Xi est continue. Par le théorème II.11, l’image Xi
Démonstration. Commençons par supposer le produit compact. Pour chaque i,
sons U= Uy1 ∩⋅⋅⋅∩Uym , et vérifions qu’il satisfait bien les propriétés voulues.
i=1 Vyi . Po-
⋂
m
i=1
Uyi ×
⋃
m
Vyj ⊂
j=1
⋃
m
X×Y=
⋃
n
(U(xj)×Y) ⊂
j=1
⋃
n
j=1
N(xj)=
⋃
n
topologie discrète. Comme Xi est fini, il est compact. En revanche, l’espace pro-
duit ∏i∈IXi ={1,2}N est infini et discret pour la topologie des boîtes. (Rappelons
que pour cette topologie, le produit d’espaces discrets est toujours discret.) Or,
comme on l’a vu en exemple 2, un espace infini discret n’est pas compact.50
CHAPITRE II. CONNEXITÉ ET COMPACITÉ II.4 Sous-espaces compacts de la droite
Tout cela est bien joli, mais une fois de plus, nous n’avons pas beaucoup
d’exemples naturels d’espaces compacts! Comme pour la connexité, nous allons
commencer par étudier les sous-espaces compacts de la droite réelle. Cela per-
mettra entre autres la généralisation promise du théorème des bornes atteintes,
et le caractérisation des sous-espaces compacts de l’espace Rn
.
Comme pour la preuve de la connexité de (a,b), la preuve suivante utilise de
manière curciale la structure d’ordre sur les réels.
Théorème II.15. Pour tout a<b∈R, l’intervalle [a,b] est compact.
famille d’ouverts Ui ⊂ R avec [a,b] ⊂ ⋃i∈IUi. Le but est de montrer que [a,b]
Démonstration. Soit U= {Ui}i∈I un recouvrement ouvert fixé de [a,b], i.e. une
admetunsous-recouvrementfinideU .Pourcela,considéronslesous-ensembleC
présent qu’il est non-vide. Comme a∈[a,b] ⊂⋃i∈IUi, il existe j∈I tel que a∈Uj.
Cet ensemble C est clairement borné, puisqu’il est inclu dans [a,b]. Vérifions à
petit tel majorant). Ainsi, on a bien c ∈ (a,b]; il reste à voir que [a,c] admet
plus grands que a) et c ≤ b (puisque b est un majorant de C, et c est le plus
fini de U : il existe donc i1,...,im ∈ I tels que [a,d] ⊂ Ui1 ∪⋅⋅⋅∪Uim . Cela
un majorant de C plus petit que c. Ainsi, [a,d] admet un sous-recouvrement
que c<b. Comme ci-dessus, il existe ℓ∈I et ε>0 avec [c,c+ε/2] ⊂Uℓ et c+ε<b.
Dans un second temps, montrons l’égalité c = b. Supposons par l’absurde
avec X compact. Alors, il existe xmin,xmax ∈X tel que f(xmin) ≤f(x) ≤f(xmax)
Théorème II.16 (Théorème des bornes atteintes). Soit f∶X → R continue
rème II.11. Nous affirmons qu’il existe M ∈ Y tel que y ≤ M pour tout y ∈ Y.
Comme X est compact et f continue, l’espace Y est compact par le théo-
Si tel n’était pas le cas, on aurait par l’absurde : pour tout M ∈ Y, il existe y∈
tel que y ≤ M pour tout y ∈ Y ; il existe donc xmax ∈ X tel que M= f(xmax),
qui satisfait f(x) ≤ f(xmax) pour tout x∈ X. L’existence de xmin se prouve de
manière analogue, ou en appliquant le résultat ci-dessus à la fonction−f.
Notons que cet énoncé aurait pu être démontré à la section précédente. En
revanche, c’est uniquement grâce au théorème II.15 que nous pouvons affirmer
qu’il s’agit bien d’une généralisation du théorème des bornes atteintes vu en
Analyse I, qui correspond au cas X=[a,b]. C’est la raison pour laquelle nous
ne le donnons que maintenant.
Ce même théorème II.15 nous permet également de caractériser les sous-
ensembles compacts de l’espace Rn, comme suit.
Théorème II.17. Un sous-espace de Rn est compact si et seulement s’il est
fermé et borné pour la métrique euclidienne.
Démonstration. Supposons d’abord A⊂ Rn compact. Comme Rn est séparé, la
proposition II.10 implique que A est fermé dans Rn. Considérons le recouvre-
= ⋃r>0 B(0,r), il
existe r1,...,rm >0 tels que A⊂B(0,r1)∪...B(0,rm). On a donc A⊂B(0,R),
dienne. Alors, il existe R > 0 tel que A ⊂ B(0,R) ⊂ [−R,R]n. Par le théo-
rème II.15, [−R,R] est compact, ce qui implique que [−R,R] n est compact par
le théorème II.13. Ainsi, A est fermé dans [−R,R]n compact, et donc compact
par la proposition I.9.
Remarques.
1. Plus généralement, si (X,d) est un espace métrique et A⊂X est compact,
alors A est fermé dans (X,Td) et borné pour la distance d : la preuve
ci-dessus s’étend verbatim.
2. Cet énoncé est aussi valable pour toute métrique dsur Rn équivalente à la
métrique euclidienne : dans ce cas, Aest borné pour dsi et seulement Aest
borné pour la métrique euclidienne. Par exemple, l’énoncé demeure vrai si
l’on remplace la métrique euclidienne par dp pour n’importe quel p∈[1,∞].
3. En revanche, la réciproque est fausse en général, et ce même sur l’espace
topologique Rn! Par exemple, la métrique d2 =
d2
est bornée et induit la
1+d2
topologie standard sur Rn, on l’a vu. Ainsi, A= Rn est fermé dans Rn, et
borné respectivement à d2. Mais Rn n’est bien-sûr pas [Link] II. CONNEXITÉ ET COMPACITÉ 52
4. Le théorème II.15 implique que les intervalles de la forme [a,b] et ceux
de la forme (a,b), (a,b] ou [a,b) ne sont jamais homéomorphes, puisque
les premiers sont compacts et pas les seconds. Cela peut également se dé-
montrer à l’aide de la notion de connexité, comme on l’a vu en exercices.
d(x,A)=inf{d(x,a) ∣ a∈A}.
distance de x à A est définie par
′) ∣ x,x
diam(B)=sup{d(x,x
′ ∈B}.
Notons que le diamètre est bien évidemment une notion métrique, et pas topo-
logique.
Voici l’un des résultats les plus utiles sur les espaces métriques compacts.
Malgré son importance, il porte traditionnellement le nom de lemme du nombre
de Lebesgue.
Lemme II.18. Soit U un recouvrement ouvert d’un espace métrique (X,d).
Si X est compact, alors il existe un δ > 0 tel que tout sous-ensemble de X de
diamètre inférieur à δ est contenu dans l’un des ouverts de U.
Avant d’en donner la preuve, notons que résultat est faux en général si l’es-
pace métrique (X,d) n’est pas compact. En effet, considérons par exemple la
famille U= {( 1
1
on peut donc supposer que Ui ≠ X pour tout i ∈ I. Comme X est compact, ilCHAPITRE II. CONNEXITÉ ET COMPACITÉ 53
pace métrique (X,d). S’il existe un i∈I avec Ui =X, alors le lemme est trivial;
positives. En effet, pour tout x ∈ X, il existe j tel que x ∈ Uij puisque ces
Nous allons maintenant montrer que f ne prend que des valeurs strictement
Remarques.
1. Cette notion est la généralisation naturelle aux espaces métriques de la
notion vue en Analyse I dans le cas X=Y=R. Il ne s’agit pas d’une no-
tion topologique, mais d’une notion métrique, qui dépend des métriques d X
et dY choisies. Par ailleurs, il n’y a pas de notion analogue pour des espaces
topologiques quelconques (non-métriques).
2. Il est important de bien noter la différence entre la continuité de f et sa
′ ∈X, dX(x,x
′) <δ⇒dY(f(x),f(x
′)) <ε,
′ ∈X, dX(x,x
′) <δ⇒dY(f(x),f(x
premier cas, le δpeut dépendre du xalors que dans le second il n’en dépend
pas, il est uniforme, d’où la terminologie. Ainsi, une fonction uniformément
continue est continue, mais la réciproque n’est pas toujours vraie, comme
vous l’avez vu en Analyse I.
Voilà l’application promise du lemme de Lebesgue.
Théorème II.19. Si f∶X →Y est une application continue avec X métrique
compact et Y métrique, alors f est uniformément continue.
Démonstration. Soit donc ε > 0 fixé. La famille {BdY (y,ε/2)}y∈Y forme un re-
couvrement ouvert de Y, et comme f est continue, U= {f −1(BdY (y,ε/2))}y∈Y
est un recouvrement ouvert de X. Comme X est un espace métrique com-
pact, le lemme II.18 nous garantit l’existence d’un δ > 0 tel que tout sous-
avec xni ∈Bi pour tout i=1,2,.... Par le lemme I.12, cette sous-suite converge
un nombre infini de termes de cette suite. Ainsi, on peut choisir n1 < n2 < ...
un indice i(x) ∈ I tel que B(x,1) ⊂ Ui(x) (premier cas), soit la boule B(x,1)
et i(x) ∈ I tels que B(x,r(x)) ⊂ Ui(x) mais B(x,2r(x)) n’est contenue dans
n’est contenue dans aucun Ui; dans ce second cas, choisissons 0 < r(x) < 1
nous avons défini pour chaque x∈X un indice i(x) ∈I. Comme {Ui}i∈I n’admet
aucun Ui. (C’est possible car {Ui}i∈I est un recouvrement ouvert de X.) Ainsi,
pas de sous-recouvrement fini, on peut définir une suite (yk) dans X avec yk ∉
Ui(y1) ∪⋅⋅⋅∪Ui(yk−1) pour tout k≥1. Soit xn =ykn une sous-suite quelconque. Par
construction, on a xn ∉Ui(x1) ∪⋅⋅⋅∪Ui(xn−1) pour tout n≥1 ; il nous reste à voir
que cette condition implique que (xn) ne converge pas.
Soit nfixé. Par la condition énoncée ci-dessus, on a xm ∉Ui(xn) pour tout m>n.
Supposons par l’absurde que cette suite (xn) converge vers une limite x∈X.
Dans le premier cas, on a B(xn,1) ⊂Ui(xn), d’où xm ∉B(xn,1), i.e. d(xn,xm) >1
pour tout m>n. Comme (xn) est une suite convergente, cela ne peut se passer
que pour un nombre fini de n≥1. Quitte à supprimer un nombre fini d’éléments
6. Notons que cet argument n’utilise pas l’hypothèse de dénombrabilité. Ainsi, on vient de
montrer que dans un espace compact, toute suite admet un point d’accumulation.
7. Cette démonstration ne fait pas partie du champ de l’[Link] II. CONNEXITÉ ET COMPACITÉ 57
classe; en d’autres termes, on a 0 < r(xn) < 1 tel que B(xn,r(xn)) ⊂ Ui(xn)
de cette suite, on peut donc supposer que pour tout n≥1, x n est dans la seconde
mais B(xn,2r(xn)) n’est contenue dans aucun Ui. Comme xm ∉ Ui(xn) pour
tout m>n, on a donc d(xm,xn) ≥r(xn), ce qui implique que B(xn,2d(xm,xn))
n’est contenue dans aucun Ui.
existe N tel que n ≥ N ⇒ d(xn,x) < r/5. Alors, pour tous n,m ≥ N, on a
l’inclusion B(xn,2d(xm,xn)) ⊂ Ui, ce qui contredit l’énoncé ci-dessus. En effet,
pour y∈B(xn,2d(xm,xn)), on a
d’où d(x,y) ≤ d(x,xn) +d(xn,y) < r/5 +4r/5= r, i.e. y ∈ B(x,r) ⊂ Ui. Cela
d(y,xn) <2d(xm,xn) ≤2(d(xm,x)+d(x,xn)) <2(r/5 +r/5)=4r/5 ,
homéomorphe à un ouvert de Rm
.
Une variété de dimension 1 est appelée une courbe, et une variété de dimen-
sion 2 est appelée une surface.
Cette définition appelle quelques remarques.
Remarques.
1. Les conditions de séparation et de dénombrabilité sont de nature technique,
afin d’éviter certains espaces pathologiques. Par exemple, la droite à deux
pour tout x∈ R ∖{0}; cet espace satisfait les axiomes d’une courbe, sauf
origines est définie comme le quotient X=R ×{0,1}/∼ avec (x,0)∼(x,1)
dimension m (exercice).
4. Si X (resp. Y) est une variété de dimension m (resp. n), alors X×Y est
une variété de dimension m+n. C’est aussi un exercice. En particulier,
le tore T= S1 ×S1, déjà rencontré en exemple 4 page 29, est une surface
(connexe, compacte).
Ainsi, la sphère S2 et le tore T sont deux surfaces connexes, compactes,
illustrées en figure III.1. Sont-elles homéomorphes? Tout ce que l’on peut dire
pour le moment, c’est qu’aucun des outils développés dans ce cours ne permet
de l’exclure... On y reviendra.
Encore quelques exemples.
vante : (0,y)∼ (1,−y) pour tout y ∈ (−1,1). L’espace quotient est une
6. Considérons le carré [0,1]×(−1,1) muni de la relation d’équivalence sui-
vante : (x,1)∼ (x,−1) pour tout x ∈ [−1,1] et (1,y)∼ (−1,−y) pourCHAPITRE III. CLASSIFICATION DES SURFACES 63
7. Considérons le carré [−1,1]×[−1,1] muni de la relation d’équivalence sui-
1⋯agbga−1
1 b−1
g b−1
g donne une sur-
face connexe compacte appelée le tore à g trous ou la surface orientable
de genre g, notée Σg. (Par convention, la sphère S2 est la surface orien-
table de genre 0. Notez que Σ1 =T par l’exemple 1.) Par le même argument
que dans le cas g= 2 décrit en exemple 5, la surface de genre g s’obtient
en recollant une surface de genre g−1 et un tore le long d’une composante
de bord : on parle de la somme connexe de Σg−1 et T, notée Σg =Σg−1#T.
L’exemple de Σ3 est illustré en figure III.4.
7. Considérons la carré muni du mot aabb. En découpant ce carré le long d’une
diagonale, on comprend que l’espace quotient correspondant est la somme
connexe de deux copies du plan projectif RP2. On verra en exercice que
cette surface n’est autre que la bouteille de Klein.
i=1 Ai = X, et pour
tous i≠j, l’intersection de Ai et Aj est soit vide, soit un sommet de Ai et de Aj,
soit un côté de Ai et de Aj. Si l’espace X admet une triangulation, alors on dit
que X est triangulable.
Exemples de triangulations.
1. Une triangulation du disque D2 peut être obtenue avec un unique tri-
angle A= D2, en choisissant pour h∶T →D2 n’importe quel homéomor-
phisme entre le disque et le triangle T.
2. La surface d’un tétraèdre définit une triangulation de la sphère S2 avec 4
triangles. Elle est illustrée en figure III.5. La surface d’un icosaèdre en
définit une autre, avec 20 triangles.
Voici le résultat principal de cette section.
Théorème III.3. Toute surface compacte est triangulable.
Cet énoncé, bien que tout à fait vraisemblable et intuitif, ne se démontre
pas facilement. Depuis la première preuve complète en 1925, des démonstrations
courtes ont vu le jour. En tout état de cause, la preuve de ce résultat dépasse
de beaucoup le cadre de ce cours. Nous l’admettrons donc, pour en déduire le
corollaire [Link] III. CLASSIFICATION DES SURFACES 67
Corollaire III.4. Toute surface compacte est homéomorphe à l’espace quotient
obtenu à partir d’une collection finie de triangles fermés disjoints du plan en
recollant leurs côtés deux à deux.
met une triangulation, d’où des homéomorphismes hi∶Ti →Ai ⊂X. En supposant
Démonstration. Soit donc X une surface compacte. Par le théorème III.3, X ad-
→X, appli-
cation surjective puisque les triangles Ai recouvrent X. Comme E est compact
et X séparé, h induit un homéomorphisme E/∼→X, où x∼ x′ si h(x)= h(x′)
(voir remarque 3, page 48). Il reste à vérifier que cette relation d’équivalence
correspond précisément à recoller les côtés deux à deux.
Par définition d’une triangulation, on peut en effet recoller les côtés des tri-
angles deux par deux. Par ailleurs, rien ne nous empêche de recoller les côtés
de plus de deux triangles ensemble, ou d’avoir un côté d’un triangle recollé à
aucun autre côté. Nous pourrions aussi avoir des triangles recollés le long d’un
sommet, mais recollés le long d’aucun des côtés adjacents. Ces trois situations
sont illustrées ci-dessous.
Dans ces trois cas, on peut démontrer que les points marqués en gras sur la
figure ci-dessus n’admettent pas de voisinage homéomorphe à un ouvert de R2
.
(Le dernier cas se démontre facilement à l’aide de la connexité, mais les deux
premiers cas requièrent des outils dont nous ne disposons pas dans ce cours.)
Ainsi, les espaces obtenus de sont pas des surfaces. Comme nous avions supposé
que X est une surface, la seule possibilité de recollement est celle décrite dans
l’énoncé. Cela termine la démonstration.
Le résultat suivant est maintenant presque immédiat.
Corollaire III.5. Toute surface compacte connexe est homéomomorphe à l’es-
pace quotient obtenu en identifiant deux à deux les côtés d’un polygone.
Démonstration. [Link].4,
l’espace X est obtenu en recollant deux à deux les côtés d’une collection de tri-
angles. Considérons donc ces triangles, et recollons les côtés deux à deux pour
construire X, mais en ne recollant que les paires de côtés qui appartiennent à
des composantes connexes différentes. Une fois que toutes les identifications de
ce type ont été faites, nous nous retrouvons avec un certain nombre de polygones
(disons, m), et avec toutes les identifications restantes entre des paires de côtés
qui appartiennent au même polygone. Notons que l’espace quotient X aura m
composantes connexes. Comme on a supposé X connexe, on a en fait m = 1,CHAPITRE III. CLASSIFICATION DES
SURFACES 68
d’où le résultat : X est obtenu en identifiant deux à deux les côtés d’un unique
polygone.
III.4 Preuve du théorème
Nous savons maintenant que toute surface compacte connexe s’obtient en
identifiant deux à deux les côtés d’un polygone, disons, à 2ncôtés. Comme nous
l’avons vu en section III.2, une manière pratique de se donner une telle identifi-
cation est via un mot de 2n lettres, où chaque lettre apparaît exactement deux
fois. On parle de polygone marqué. Plus généralement, on peut considérer des col-
lections de polygones marqués, où chaque lettre apparaît exactement deux fois
dans l’ensemble de tous les mots.
Bien entendu, deux collections de polygones marqués peuvent donner des
surfaces homéomorphes. (Nous avons déjà vu ce phénomène en section III.2 : les
mots abab−1 et aabbdéfinissent tous deux la bouteille de Klein.) L’idée est main-
tenant de donner une liste d’opérations sur les collections de polygones marqués
(ou collection de mots) qui ne modifient pas la surface sous-jacente. On pourra
ensuite utiliser ces opérations pour tenter de ramener toutes les collections de
mots à une certaine liste, qui correspondera donc à une liste complète de surfaces
connexes compactes.
Voici cette liste d’opérations. Pour chacune d’entre elles, nous commençons
par la décrire combinatoirement en termes des mots, puis nous expliquons son
effet géométrique sur les collections de polygones correspondants.
(i) Remplacer un mot de la forme y0y1 par les mots y0c−1 et cy1, où la lettre c
n’apparaît pas dans les mots y0 et y1 : cela correspond à découper un poly-
gone marqué.
(ii) Remplacer deux mots de la forme y0c−1 et cy1 par le mot y0y1 : cela cor-
respond à recoller deux polygones marqués le long d’un côté.
(iii) Remplacer chaque occurrence d’une lettre par une autre lettre (qui n’appa-
raît pas ailleurs); remplacer chaque occurrence d’une lettre par son inverse,
et vice-versa. Cela correspond simplement à renommer certains côtés.
(iv) Permuter cycliquement des lettres d’un mot, i.e. remplacer un mot de la
1⋯aεn−1
forme aε1
n−1 aεn
n par aεn
1⋯aεn−1
n aε 1
1⋯aεn
(v) Remplacer un mot de la forme aε1
n⋯a−ε1
n par son inverse formel a−εn
1.
Cela correspond à renverser un polygone marqué.
(vi) Remplacer un mot de la forme y0aa−1y1 par le mot y0y1. L’opération cor-
respondante est d’annuler deux côtés adjacents en les recollants.
On dira que deux collections de polygones marqués sont équivalentes si elles
peuvent être reliées par ces six opérations. Notons que dans ce cas, les deux
surfaces ainsi construites sont homé[Link] III. CLASSIFICATION DES SURFACES 69
Exemple de polygones marqués équivalents. Les mots aba−1b et aabb sont
équivalents via la suite d’opérations suivantes :
aba−1b(i)
→abc−1, ca−1b(iv),(v)
→ c−1ab, b−1ac−1 (ii)
→ c−1aac−1 (iv)
→ aac−1c−1 (iii)
→ aabb.
Cela donne une preuve combinatoire du fait que ces deux mots présentent la
même surface, un résultat déjà vu en exercices.
Il reste à démontrer l’énoncé suivant.
1⋯agbga−1
1 b−1
g b−1
g (g≥1).
Nous ne donnerons pas cette preuve non plus, mais il est à noter que cet
énoncé et sa démonstration sont de nature purement combinatoire.
Nous sommes maintenant en mesure de donner la preuve du théorème de
classification des surfaces.
Preuve du théorème III.3. Soit donc X une surface compacte connexe. Par le
corollaire III.5, X est homéomomorphe à l’espace quotient obtenu en identifiant
deux à deux les côtés d’un polygone; en d’autres termes, X est donné par un
1⋯agbga−1
1 b−1
g b−1
g (g≥1).
Comme deux polygones marqués équivalents définissent les mêmes surfaces, X
est homéomorphe à une des surfaces données par cette liste de mots. Par les
exemples en section III.2, il s’agit des surfaces suivantes :
S2
, RP2, Nh (h≥2), Σg (g≥1).
Par convention, cela correspond aux surfaces Σg pour g≥0 et Nh pour h≥1, ce
qui est précisément la liste de surfaces du théorème III.3.
La preuve est-elle vraiment terminée? Non, puisqu’il reste encore à montrer
que deux surfaces dans cette liste ne sont jamais homéomorphes (le mot “unique”
dans l’énoncé du théorème). Avec les outils dont nous disposons, il est impossible
de distinguer ces espaces les uns des autres : en effet, ils sont tous connexes
(par arcs), compacts, séparés, à base dénombrable, métrisables, et localement
homéomorphes à R2. Ils partagent donc les mêmes propriétés topologiques, parmi
celles vues dans ce cours.
Pour les distinguer, il faut un outil nouveau, du type qu’on construit en to-
pologie algébrique. Le plus pratique à ce stade est ce qu’on appelle le groupe
fondamental, dont vous verrez la définition en Topologie algébrique. À tout
espace topologique X, on associe un groupe π1(X) de telle manière qu’un ho-
méomorphisme X →Y induit un isomorphisme π1(X)→π1(Y).
3 On montre
3. De manière plus précise, π1 est un foncteur de la catégorie des espaces topologiques
(pointés) dans la catégorie des [Link] III. CLASSIFICATION DES SURFACES 70
ensuite que si X est une surface donnée par un mot w en les lettres a,b,c,...
(de telle manière que tous les sommets du polygône marqué correspondant sont
identifiés en un point), alors le groupe fondamental de X admet la présentation
π1(X)=⟨a,b,c,... ∣ w⟩.
par générateurs et relations
.
Il reste alors à vérifier que deux groupes présentés par deux mots distincts
de la liste donnée en proposition III.6 ne sont pas isomorphes, ce qui est très
facile. Cela implique alors que les espaces topologiques correspondants ne sont
pas homéomorphes, ce que nous cherchions à démontrer.
sémantique des attributs
Plus il est facile d’expliquer la sémantique des attributs d’une relation, plus la conception du
schéma de relations est bonne.
PRINCIPE 1: concevoir un schéma de relations de telle sorte qu’il soit simple d’expliquer ce
qu’il représente.
EXEMPLE
Que signifie FOURNIT (f#, nom, adresse, p#, produit, prix, couleur, nomproj, dép) ?
Ce schéma de relations doit être décomposé comme suit:
PROD(p#, produit, couleur)
FOURNITPROD(f#, nom, adresse,p#, produit, prix)
PROJET(nomproj, dép)
UTILISE(nomproj, p#)
Chaque schéma de relations et chaque attribut ont une sémantique précise.
22. les informations redondantes
Les informations redondantes, à l’origine de problèmes, doivent être supprimées dans la me-‐-
sure du possible.
PRINCIPE 2: concevoir un schéma de relations de telle manière que les insertions, les suppres-‐-
sions et les mises à jour ne posent pas de problèmes.
EXEMPLE
Si on utilise la relation suivante FOURNITPROD(f#, nom, adresse, p#, produit, prix) plutôt
que le schéma de relations suivant:
FOURNISSEUR(f#, nom, adresse)
FOURNIT(f#, p#, prix)
alors le nom et l’adresse d’un fournisseur sont stockés plusieurs fois dans les n-‐-uplets corres-‐-
pondant aux produits vendus par le fournisseur.
QUAND Y-‐-A-‐-T-‐-IL REDONDANCE D’INFORMATION ?
On constate assez facilement que la même adresse apparaît autant de fois qu’il y aura de produits si
l’on utilise la relation FOURNITPROD(f#, nom, adresse, p#, produit, prix). Or on sait qu’un fournis-‐-
seur ne possède qu’une seule adresse et cela même s’il vend plusieurs produits. On appelle cette
propriété une dépendance fonctionnelle. Un mauvais schéma relationnel peut alors entraîner des
anomalies lors des manipulations.
f# nom Labaleine Lemelon adresse p# produit prix
F1 Paris P1 parapluie 110
F2 Lyon P2 chapeau 50
F3 Toutcuir Lyon P3 sac à main 650
F1 Labaleine Paris P4 parasol 150
F1 Labaleine Paris P5 ombrelle 70
F4 Letour Nantes P6 ceinture 55
F5 P3 650
Legrand Paris sac à main Dans la relation ci-‐-dessus, il existe des redondances qui peuvent engendrer les difficultés
suivantes:
• anomalie d’insertion. Telle qu’elle se présente, cette relation ne permet pas de mémoriser dans
la base un produit dont le fournisseur n’existe pas.
• anomalie de suppression. La disparition d’un fournisseur, qui est l’unique fournisseur d’un
produit, entraîne également la disparition des informations concernant ce produit (exemple:
Letour).
• anomalie de mise à jour. Toute modification sur le prix d’un produit qui apparaît plusieurs fois
dans la relation doit être répercutée sur tous les n-‐-uplets correspondants (exemple: sac à main).
Cela augmente le temps de mise à jour et les risques d’incohérence.
On résout ces problèmes en étudiant les dépendances entre les données, et en décomposant et norma-‐-
lisant les relations. On obtient ainsi des schémas de relations qui évitent les anomalies citées ci-‐-dessus.
Attention cependant à ne pas voir la normalisation comme un dogme. Il arrive parfois que, pour des
raisons d’efficacité notamment, on soit obligé de dénormaliser.
1.2.2 Dépendance Fonctionnelle (DF)
Soient R un schéma de relations, et X=A1,A2,…,An et Y=B1,B2,…,Bm des sous-‐-ensembles de R.
X détermine fonctionnellement Y , noté X → Y , ssi pour chaque instance r de la relation R, pour chaque
paire de n-‐-uplets t et s appartenant à r, t[X] = s[X] implique t[Y] = s[Y] (où t[X] désigne la projection du
n-‐-uplet t sur les attributs X).
Autrement dit, X → Y signifie qu’une valeur de X détermine au plus une valeur de Y.
3Une dépendance fonctionnelle est une propriété définie sur l'ʹintention du schéma et non son extension
(elle est donc invariante dans le temps et ne peut être extraite à partir d'ʹexemples). C'ʹest une propriété
qui doit être extraite de la connaissance que l'ʹon a de l'ʹapplication à modéliser et qui permet d’élimi-‐-
ner la redondance.
EXEMPLES
Considérons la relation suivante
FILM (titre, année, durée, type, studio, acteurPrincipal)
avec une instance de la relation contenant les n-‐-uplets suivants:
titre année durée type studio acteurPrincipal
StarWars 1977 124 couleur Fox Carrie Fisher
StarWars 1977 124 couleur Fox Mark Hamill
StarWars 1977 124 couleur Fox Harrison Ford
1991 104 couleur Disney Emilio Estevez
1991 95 couleur Paramount Dana Carvey
1992 95 couleur Paramount Mike Meyers
Mighty Ducks Wayne’s World Wayne’s World On peut en déduire les trois DF suivantes:
{titre, année} → durée
{titre, année} → type
{titre, année} → studio
Par contre, la dépendance suivante n’est pas une DF:
{titre, année} → acteurPrincipal
En effet, étant donné un film, il peut exister dans la base (telle qu’elle est modélisée) plusieurs acteurs
principaux.
Enfin, la DF {titre, année} → durée signifie qu’il ne peut exister dans une instance de FILM les deux n-‐-
uplets suivants:
titre année durée type studio acteurPrincipal
Farenheit, 9/11 2004 124 couleur Fox Georges Bush
Farenheit, 9/11 2004 130 couleur Fox Dick Cheney
CONVENTIONS
• L’ensemble de DF suivant:
{A1,A2,…,An} → B1
{A1,A2,…,An} → B2
…
{A1,A2,…,An} → Bm
est équivalent à {A1,A2,…,An} → B1,B2,...,Bm.
41.2.3 Propriétés des DF
Les trois premières propriétés (réflexivité, augmentation et transitivité) sont également appelés axio-‐-
mes d’Armstrong. De ces trois axiomes, on peut en déduire trois autres propriétés (pseudo-‐-transitivité,
union et décomposition).
Si Y ⊆ X, alors on a X → Y
RÉFLEXIVITÉ
Si X → Y , alors on a X ∪ Z → Y ∪ Z
AUGMENTATION
TRANSITIVITÉ
PSEUDO-‐-TRANSITIVITÉ
Si X → Y et Y ∪ W → Z, alors X ∪ W → Z
Si X → Y et Y → Z, alors on a X → Z
Si X → Y et X → Z, alors X → Y ∪ Z
UNION
Si X → Y et Z ⊆ Y , alors X → Z
DÉCOMPOSITION
• les n-‐-uplets de la relation S sont la projection sur {B1,B2,…,Bm} de tous les n-‐-uplets de R. La pro-‐-
jection est l’opération qui consiste à construire la nouvelle relation S à partir de R en prenant
pour chaque n-‐-uplet t de R uniquement les attributs {B1,B2,…,Bm} et en éliminant les n-‐-uplets en
double,
• de manière similaire, les n-‐-uplets de la relation T sont la projection sur {C1,C2,…,Ck} de tous les n-‐-
uplets de R.
La décomposition de la relation R en R1,R2,…,Rn est sans perte si la jointure des relations R1,R2,…,Rn
permet de retrouver tous les n-‐-uplets de la relation R d’origine. La jointure est l’opération qui permet
de construire une nouvelle relation à partir de deux relations ayant au moins un attribut commun.
EXEMPLE
On peut décomposer la relation FILM définie précédemment en deux relations FILM1 et FILM2 telles
que:
FILM1 = (titre, année, durée, type, studio)
FILM2 = (titre, année, acteurPrincipal)
7Si on utilise la décomposition telle qu’elle est définie, on obtient au niveau des n-‐-uplets pour FILM1 et
FILM2 les résultats suivants:
titre année durée type studio
StarWars 1977 124 couleur Fox
Mighty Ducks 1991 104 couleur Disney
titre année acteurPrincipal
StarWars 1977 Carrie Fisher
StarWars 1977 Mark Hamill
StarWars 1977 Harrison Ford
1991 Emilio Estevez
1991 Dana Carvey
1992 Mike Meyers
Mighty Ducks Wayne’s World Wayne’s World On peut remarquer que cette décomposition élimine les problèmes
soulevés au paragraphe 1.2.1. La
redondance est éliminée, par exemple la durée de chaque film n’apparaît qu’une fois, dans la relation
FILM1. Le risque d’anomalie de mise à jour a ainsi disparu. De même, le risque d’anomalie de sup-‐-
pression a disparu. Si on supprime tous les acteurs du film Wayne’s World, le film disparaît égale-‐-
ment. Il apparaît que FILM2 possède malgré tout de la redondance, puisque titre et année apparais-‐-
sent plusieurs fois. Cependant, ces deux attributs forment une clé, et il n’est pas possible de représen-‐-
ter plus succinctement un film.
1.4 Normalisation des relations
Les formes normales de schémas de relations sont des propriétés souhaitables que doit posséder cha-‐-
que schéma de relations. Elles sont nécessaires (mais non suffisantes) pour une « bonne » conception.
Historiquement, les formes normales suivantes ont été proposées (de la moins restrictive à la plus res-‐-
trictive).
Première Forme Normale (1NF)
Deuxième Forme Normale (2NF)
Troisième Forme Normale (3NF)
Forme Normale de Boyce and Codd (BCNF)
Quatrième Forme Normale (4NF)
Cinquième Forme Normale (5NF)
Les formes normales définissent un ordre partiel sur les schémas de relation. On peut donc voir une
forme normale comme une classe d'ʹéquivalence (on peut comparer deux schémas dans deux classes
d'ʹéquivalence différentes mais pas dans la même). Il faut aussi noter que le seul élément qui est pris en
compte par les formes normales est la non redondance d'ʹinformations d'ʹun schéma. Selon les formes
normales, un « bon » schéma est un schéma sans redondance (ce qui ne veut pas forcément dire qu'ʹil
est efficace par exemple). Un schéma relationnel sans qualité particulière est appelé schéma en 1ère
forme normale (on note 1NF) et si on rajoute certaines qualités on obtient les deuxième et troisième
formes normales (on note 2NF et 3NF).
On ne présente ici que les formes normales dont la définition utilise exclusivement les dépendances
fonctionnelles. Si on prend en compte d'ʹautres dépendances entre données comme les dépendances
multivaluées, on obtient alors les 4NF et 5NF. La BCNF reste cependant l'ʹobjectif de normalisation le
plus « classique ».
1NF: une relation est en première forme normale ssi tout attribut a une valeur atomique (vrai par défi-‐-
nition du modèle relationnel).
82NF : une relation est en deuxième forme normale ssi elle est en 1NF et si tous les attributs non clés
sont pleinement dépendants des clés (toutes les dépendance entre une clé et un attribut non clé sont
des dépendances fonctionnelles élémentaires).
3NF : une relation est en troisième forme normale ssi elle est en 2NF et si tous les attributs non clés
sont directement et pleinement dépendants des clés (si tout attribut non clé ne dépend pas d'ʹun autre
attribut non clé).
BCNF (Boyce-‐-Codd) : une relation est en BCNF ssi elle est en 3NF et si les seules DFE sont celles de la
forme C → X avec C clé (seules les clés sont en partie gauche de DF).
1.4.1 Première forme normale (1NF)
Une relation R est dite en première forme normale (1NF) si tous ses attributs sont atomiques et qu’il
n’existe pas d’attributs répétitifs. De plus, chaque attribut doit avoir une sémantique précise. V oyons
pourquoi la relation suivante n’est pas en première forme normale.
titre année durée type studio
StarWars 1977 124 couleur Fox, Los Angeles
Mighty Ducks 1991 104 couleur Disney , San Francisco
Wayne’s World 1992 95 couleur Paramount, Los Angeles
Les attributs de cette relation ne sont pas atomiques. En effet, l’attribut studio contient à la fois le nom
et la ville, ce qui est gênant si l’on souhaite extraire tous les studios situés à Los Angeles.
Analysons maintenant un deuxième exemple. La relation suivante n’est pas non plus en 1NF.
titre année acteur1 acteur2 acteur3
StarWars 1977 Carrie Fisher Mark Hamill Harrison Ford
Mighty Ducks 1991 Emilio Estevez
Wayne’s World 1992 Dana Carvey Mike Meyers
En effet, la première forme normale stipule que les attributs ne doivent pas être répétitifs. Or, la liste
des acteurs ne respecte pas cette propriété. Si on veut rechercher dans quel film a joué Harrison Ford,
on est obligé non seulement de parcourir tous les n-‐-uplets, mais également toutes les colonnes. De
plus, si l’on souhaite rajouter un quatrième acteur, il faut modifier la relation toute entière.
Enfin, que pensez-‐-vous de la relation suivante:
titre année durée type studio
StarWars 1977 124 SF Fox
Mighty Ducks 1991 104 couleur Disney
Wayne’s World 1992 95 couleur Paramount
Il semble que cette relation soit en 1NF. Les attributs sont atomiques, il n’y a pas d’attributs répétitifs.
Malgré tout, l’attribut type ne possède pas une sémantique claire, représentant soit un genre (SF), soit
le type de la pellicule. Cette relation n’est donc pas en 1NF.
1.4.2 Deuxième forme normale (2NF)
Une relation R est dite en deuxième forme normale (2NF) ssi
• elle est en 1NF,
• tout attribut n’appartenant pas à une clé ne dépend pas d’une partie de cette clé (pas de dépen-‐-
dances partielles).
Autrement dit, dès qu’un attribut non clé dépend d’une partie d’une clé, la relation n’est pas en 2NF.
9V oyons dans un premier temps un exemple abstrait. La relation R(A,B,C) munie de l’ensemble F des
dépendances est en 1NF mais pas en 2NF.
A,B → C
B →C
Regardons maintenant sur un exemple concret. Considérons la relation suivante:
numSalarié nom numProjet heures
20036 Durand 1 18,5
20036 Durand 2 6,7
36900 Leroux 2 8,5
45002 Franck 3 23,5
45002 Franck 1 4,8
L’ensemble F des DF est:
numSalarié → nom
numSalarié,numProjet → heures
La relation n’est pas en 2NF. En effet, la clé minimale de cette relation est {numSalarié,numProjet}.
L’attribut non clé heure est en totale dépendance fonctionnelle avec la totalité de la clé. Par contre,
l’attribut non clé nom dépend d’une partie de la clé, à savoir numSalarié. Pour que la relation soit en
2NF, il est nécessaire de scinder la relation initiale en deux relations, comme ceci:
numSalarié numProjet heures
20036 1 18,5
20036 2 6,7
36900 2 8,5
45002 3 23,5
45002 1 4,8
numSalarié nom
20036 Durand
36900 Leroux
45002 Franck
Chacune de ces deux relations répond désormais aux exigences de la première et de la deuxième
forme normale. La première relation a pour clé primaire l’attribut numSalarié, et la deuxième relation
a pour clé {numSalarié,numProjet}.
1.4.3 T roisième forme normale (3NF)
OBJECTIFS DE LA 3NF
1. élimination des dépendances partielles
S’il existe une dépendance partielle Y → A, où X est une clé minimale et Y un sous-‐-ensemble
de X, alors chaque n-‐-uplet utilisé pour associer une valeur X aux valeurs de A sera répété pour
les valeurs de Y (d’où redondance des informations).
La condition de la 3NF élimine cette possibilité, évitant ainsi les mises à jour incorrectes et la
redondance.
2. élimination des dépendances transitives
S’il existe une dépendance transitive X → Y → A, alors on ne peut associer une valeur Y à une
valeur X que s’il existe une valeur A associée à une valeur Y . Cela conduit à des problèmes
d’insertion et de suppression.
DÉFINITION
On considère les définitions suivantes:
R: un schéma de relations,
F: un ensemble de DF sur R,
X: un sous-‐-ensemble de R,
A: un attribut.
10On rappelle que A est un attribut clé ssi il fait partie d’une clé minimale de R et que dans le cas con-‐-
traire, A est appelé un attribut non clé.
La relation R est dite en troisième forme normale (3NF) ssi lorsque X → A est dans F+ et A n’est pas
dans X, soit X est une clé primaire, soit A est un attribut clé.
Il existe deux cas dans lesquels X → A ne respecte pas la 3NF:
Cas 1: X est un sous-‐-ensemble d’une clé minimale. X → A est une dépendance partielle.
Cas 2: X n’est pas un sous-‐-ensemble de toutes les clés minimales. X → A est une dépendance
transitive. Elle crée une chaîne non triviale de DF Z → X → A pour une clé minimale Z.
Autrement dit, une relation est dite en 3NF ssi:
• elle est en 2NF,
• il n’existe pas de dépendance entre attributs non clé.
EXEMPLE 1
R=ABCD
F = {AB → C,B → D,BC → A}
AB et BC sont des clés minimales et ce sont les seules. A, B et C sont des attributs clés. D est
un attribut non clé.
EXEMPLE 2
R=VRC R(ville, rue, code)
F = {VR → C,C → V}
R est en 3NF.
EXEMPLE 3
R=SAIP
F = {SI → P ,S → A}
SI est la seule clé, et A est un attribut non clé.
S → A ne respecte pas la 3NF, étant donné que S n’est pas une clé primaire. De plus, S → A est
une dépendance partielle.
On remarque dans cet exemple que la dépendance S → A est dans F. Cependant, en général,
les dépendances non conformes à la forme normale étudiée sont dans F+ plutôt que dans F.
1.4.4 Forme normale de Boyce-‐-Codd (BCNF)
OBJECTIFS DE LA BCNF
1. élimination des dépendances partielles,
2. élimination des dépendances transitives,
3. élimination des anomalies non prises en compte par la 3NF.
DÉFINITION
On considère les définitions suivantes:
R: un schéma de relations,
F: un ensemble de DF sur R,
X: un sous-‐-ensemble de R,
A: un attribut.
R est en BCNF ssi lorsque X → A appartient à F+ et que A n’est pas dans X, alors X est une clé
de R.
Une relation en 3NF qui ne possède qu’un seule clé minimale est en BCNF.
EXEMPLE 1
M=NAC MEMBRE(nom,adresse,cotisation)
F = {n → a, n → c}
M est en BCNF.
11EXEMPLE 2
R=VRC R(ville,rue,code)
F = {VR → C,C → V}
R est en 3NF mais pas en BCNF. Dans R, on ne peut pas stocker la ville correspondante à un
code à moins de connaître une rue associée à ce code (anomalie d’insertion). En effet, C → V
est vraie et V n’appartient pas à C, alors que C ne contient aucune des clés minimales de R.
1.5 Dépendances fonctionnelles et conception de schémas
Nous l’avons déjà abordé au paragraphe 1.2.1, il existe deux méthodes pour concevoir un schéma de
bases de données qui soit en 3NF: la méthode dite synthétique, et la méthode par décomposition.
1.5.1 La méthode synthétique
L’algorithme dit de synthèse permet dʹobtenir une décomposition 3NF qui préserve les DF. Il est basé
sur le calcul de la couverture minimale (ou irredondante) dʹun ensemble de DF. Le point de départ de
cette méthode est la connaissance des attributs et d’un ensemble de dépendances fonctionnelles. On
construit le graphe des DF dans lequel chaque attribut constitue un noeud, et chaque DF est représen-‐-
tée par un arc. L’algorithme de synthèse va travailler sur ce graphe et construire un ensemble de rela-‐-
tions en 3NF.
ALGORITHME DE SYNTHÈSE
Pour obtenir un schéma de relations en 3NF, on applique l’algorithme suivant:
1. on construit une couverture minimale à partir de l’ensemble F des DF,
2. on en déduit les relations en 3NF en regroupant dans une même relation tous les attributs ayant
la même partie gauche dans le graphe des DF,
3. si aucune des relations obtenues à l’étape précédente ne contient pas (ou ne permet pas d’obte-‐-
nir) la clé de la relation initiale, on ajoute une relation composée uniquement des attributs de la
clé.
EXEMPLE
Soit la relation GESPROD (numEmp, nomEmp, numProj, budProj, emploi, taux, nbhr) qui décrit la
gestion de projet dans une entreprise. Les attributs sont les suivants: le numéro d’employé, le nom de
l’employé, le numéro du projet, le budget du projet, l’emploi occupé par l’employé, le taux de rému-‐-
nération de l’employé, et le nombre d’heures de travail de l’employé sur un projet donné. La seule clé
minimale de la relation est constituée des attributs {numEmp, numProj}. L’ensemble F des DF est le
suivant:
numEmp → nomEmp
numEmp → emploi
emploi → taux
numEmp → taux
numProj → budProj
numEmp,numProj → nbHr
Pour obtenir une décomposition de GESPROD muni de F en un ensemble de relations en 3NF, on ap-‐-
plique lʹalgorithme suivant:
1. construction de la couverture minimale: on élimine les dépendances transitives:
numEmp → taux est une DF transitive car numEmp → emploi et emploi → taux.
2. déduction des relations en 3NF en regroupant dans une même relation tous les attributs ayant
même partie gauche dans F.
EMPLOYÉ (numEmp, nomEmp, emploi)
PROJET (numProj, budProj)
RÉMUNÉRATION (emploi, taux)
OCCUPE (numEmp, numProj, nbHr)
3. on vérifie que la clé est présente dans au moins une relation. Dans notre exemple, la relation
OCCUPE possède la clé de la relation initiale.
121.5.2 La méthode par décomposition
Une autre manière de concevoir un schéma relationnel en troisième forme normale est de partir du
schéma complet (ensemble de tous les attributs) et de décomposer cette « grosse » relation (appelée
également relation universelle) en respectant les dépendances fonctionnelles. Cette approche est appelée
approche par décomposition. Le problème est dʹordonner lʹordre des décompositions de manière à
obtenir un schéma en 3ème forme normale. En effet, chaque relation produite ne conserve qu’un cer-‐-
tain nombre de DF (celles définies sur ses attributs propres) et nʹest donc pas forcément en 3ème forme
normale. De plus, lʹensemble des DF du schéma complet nʹest pas forcément préservé.
ALGORITHME DE DÉCOMPOSITION
entrée: un schéma relationnel (ensemble dʹattributs) et un ensemble E de DF entre ses attri-‐-
buts
sortie: une ou plusieurs relations en 3NF dont la jointure redonne la relation initiale (par con-‐-
tre des DF de E ont pu être perdues)
principe: lʹalgorithme peut se voir comme la construction dʹun arbre binaire. La racine de cet
arbre est la relation à décomposer. Lʹarbre se construit récursivement de la manière suivante:
1. on choisit une DF dfi dans lʹensemble E des DF,
2. le fils gauche du noeud racine est une relation composé de tous les attributs de dfi,
3. dfi est retirée de lʹensemble E,
4. le fils droit du noeud racine est une relation composée de tous les attributs de la racine ex-‐-
cepté ceux présents en partie droite de dfi.
Problèmes: la solution dépend du choix des DF selon lesquelles on choisit de décomposer et il ne pré-‐-
serve pas nécessairement les DF.
On sait néanmoins que toute relation admet une décomposition en 3NF qui préserve les DF.
EXEMPLE
Soit la relation universelle associée à la gestion de production définie au paragraphe 1.5.1:
GESPROD (numEmp, nomEmp, numProj, budProj, emploi, taux, nbhr)
On constate quʹelle n
ʹest pas en 2NF car
numEmp → nomEmp, taux, emploi
numProj → budProj
Ceci conduit à une décomposition de la relation GESPROD en trois relations en 2NF:
PROJET (numProj, budProj)
OCCUPE (numEmp, numProj, nbHr)
EMPREM (numEmp, nomEmp, emploi, taux)
On constate que la relation EMPREM n
ʹest pas en 3NF car
emploi → taux (un attribut non clé dépend fonctionnellement dʹun autre attribut non clé)
On décompose la relation EMPREM en deux relations en 3NF
EMPLOYÉ (numEmp, nomEmp, emploi)
RÉMUNÉRATION (emploi, taux)
On obtient finalement quatre relations en 3NF
PROJET (numProj, budProj)
OCCUPE (numEmp, numProj, nbHr)
RÉMUNÉRATION (emploi, taux)
EMPLOYÉ (numEmp, nomEmp, emploi)
EXEMPLE SUR LES FORMES NORMALES
Soit le schéma R = (P , H, N, Y , T), et F = {P → T | P , H → Y | H, N → P | H, Y → N}.
• ensemble des DFE engendrées:
H, N → T
P, H →N
H,N → Y
13H, Y → P
P, H →T
H, Y → T
• on a donc trois clés potentielles (H, N | P , H | H, Y):
H, N → P , T, Y
P , H → T, Y , N
H, Y → N, P , T
• les attributs clés sont donc: H, N, P , Y , et un attribut non clé est T.
• par définition le schéma est en 1ère forme normale. Est il en 2NF ?
Non, car P , H → T n
’est pas une DFE (on a P → T), R est donc en 1NF.
• application de l’algorithme de décomposition:
R(P, H, N, Y, T)
P ! T
R1(P, T) Clé P (3NF) R2(P, H, N, Y)
Clés H,N ou P,H ou H,Y (3NF) R =
R1 * R2 (pas de perte des DFs)
14CHAPITRE 2: SÉCURITÉ DE FONCTIONNEMENT
1. Les transactions
2. La tolérance aux pannes
3. La gestion de la concurrence
4. Le verrouillage sous Oracle
5. JDBC et les transactions
2.1 Les transactions
2.1.1 Définition
L’objectif de ce chapitre est d’étudier les mécanismes que fournit un SGBD pour s’assurer que les don-‐-
nées demeurent dans un état cohérent, c’est-‐-à-‐-dire qu’elles ne sont pas mises en cause par un pro-‐-
blème logiciel ou matériel, ou par le fait que plusieurs utilisateurs manipulent les données simultané-‐-
ment. En effet, les SGBD sont utilisés par plusieurs utilisateurs simultanément, à la fois pour les requê-‐-
tes ou pour des modifications sur la base de données.
Par exemple, on suppose que deux personnes souhaitent retirer 100€ d’un même compte. Un SGBD
doit s’assurer qu’aucun des deux retraits ne soit perdu. Par comparaison avec un système d’exploita-‐-
tion, deux personnes peuvent très bien éditer le même fichier, mais c’est le dernier qui écrit qui voit
ses modifications conservées. Ce comportement n’est pas imaginable dans le contexte des bases de
données.
Pour résoudre ce problème, on a introduit le concept de transaction; Une transaction est un pro-‐-
gramme qui forme une unité logique de traitement. Elle est constituée d’une ou plusieurs opérations
d’accès aux objets de la base de données (insertion, suppression, modification ou lecture). Enfin, une
transaction fait passer la base d’un état cohérent E1 à un état cohérent E2. En particulier:
• une transaction doit commencer à partir d’un état cohérent de la base,
• pendant la transaction, la base peut éventuellement être dans un état incohérent,
• lorsque la transaction se termine avec succès, la base doit être dans un état cohérent,
• lorsqu’une transaction a été validée, les modifications sur la base sont persistantes, même en cas de
problèmes logiciels ou matériels,
• plusieurs transactions peuvent s’exécuter en parallèle.
On distingue deux problèmes à prendre en compte:
• la tolérance aux pannes: il faut restaurer la base dans l’état où elle se trouvait avant l’incident. Les mé-‐-
canismes utilisés sont les transactions, la tenue d’un journal, la reprise après panne.
• l'ʹexécution concurrente de plusieurs transactions: il faut veiller à ce que l’action simultanée de plusieurs
utilisateurs sur les mêmes données ne conduise pas à une incohérence de ces données. Les méca-‐-
nismes utilisés sont la gestion des accès concurrents, les transactions, le verrouillage et la gestion de
l’interblocage.
2.1.2 Propriétés ACID
Un SGBD supporte ce que l’on appelle des transactions ACID. Les propriétés ACID sont:
• atomicité : lors de l’exécution d’une transaction, soit toutes ses actions sont exécutées, soit aucune ne
l’est,
• cohérence : après une transaction, la base se trouve dans un état cohérent,
• isolation : il n’y a pas d’incohérence liée à la concurrence d’accès,
• durabilité : les effets d’une transaction correctement exécutée survivent à une panne ultérieure.
V oyons sur un exemple ce que cela signifie. On suppose une transaction qui effectue un transfert d’ar-‐-
gent (100€) d’un compte A vers un compte B:
1. lire(A) 4. lire(B)
2. A:= A –100 5. B := B + 100
3. écrire(A) 6. écrire(B)
15La propriété d’atomicité spécifie que si la transaction échoue après l’étape 3 et avant l’étape 6, le sys-‐-
tème doit s’assurer qu’aucune mise à jour n’aura été effectuée, sous peine de voir une incohérence
entre la balance des deux comptes.
La propriété de cohérence spécifie que la somme des soldes de A et B est inchangée après l’exécution
de la transaction.
La propriété d’isolation spécifie que si une autre transaction essaie d’accéder à la base entre les étapes
3 et 6, elle ne verra pas les modifications faites aux étapes 1 à 3. L’isolation peut être assurée de ma-‐-
nière triviale en exécutant les transactions en séquence (de manière sérialisable). Cependant, nous ver-‐-
rons que permettre l’exécution concurrente des plusieurs transactions apporte des avantages, à condi-‐-
tion de ne pas avoir d’interférences entre les transactions simultanées.
Enfin, la propriété de durabilité spécifie que lorsque l’utilisateur a validé la transaction, les mises à
jour doivent persister, quelques soient les défaillances logicielles ou matérielles qui pourraient surve-‐-
nir.
2.1.3 États d’une transaction
Une transaction est une unité atomique (au sens indivisible) de travail qui doit être soit totalement
terminée soit pas du tout (atomicité). Le système doit donc savoir quand la transaction commence, se
termine, est validée ou est abandonnée. Pour cela, une transaction peut se trouver dans plusieurs
états:
• active: l’état initial. La transaction entre dans cet état immédiatement après son début d’exécution, et
elle y reste durant son exécution,
• partiellement validée: lorsque la dernière instruction de la transaction a été exécutée,
• échouée: dès que l’exécution ne peut plus continuer normalement,
• annulée: après que la transaction a été annulée, et que la base ait été restaurée dans l’état cohérent
d’avant le début de la transaction. Il existe alors deux options après qu’une transaction ait été annu-‐-
lée, soit on redémarre la transaction, soit on tue la transaction.
• validée: après une exécution totalement terminée.
En fait, SQL supporte les transactions, souvent de manière invisible. En effet, chaque commande effec-‐-
tuée dans l’outil d’interrogation est une transaction. Ainsi, chaque fois que vous faites une (ou plu-‐-
sieurs) requête(s) dans SQL/Plus, vous débutez sans le savoir une transaction.
2.1.4 Commit, rollback
L’instruction SQL COMMIT permet de valider une transaction. Cette instruction peut être explicite dans
une transaction où, comme c’est souvent le cas, implicite et exécutée à la fin de la transaction par le
SGBD. Une fois l’instruction COMMIT exécutée, les modifications faites sont permanentes et la transac-‐-
tion s’achève.
L’instruction ROLLBACK permet également d’achever la transaction, mais en l’annulant. Il n’y alors au-‐-
cun effet sur la base, et le SGBD doit alors revenir à l’état précédent le début de la transaction puisque
c’est le dernier point garanti de cohérence de la base.
2.1.5 Exemple
V oyons sur un exemple l’interaction entre deux transactions. On suppose la relation BarÀBière(bar,
bière, prix), et on suppose que le bar Jo vend de la Chimay (3,00€) et de la Leffe (2,50€). Paul interroge
la base, et la relation BarÀBière pour connaître le prix minimum et le prix maximum du bar Jo. Entre-‐-
temps, Jo décide de cesser de vendre de la Chimay et de la Leffe, pour ne plus vendre que de la Kwak
à 3,50€.
Paul exécute les deux instructions SQL suivantes afin de connaître les prix minimum et maximum:
(max) SELECT MAX(prix) FROM BarÀBière
WHERE bar = ‘Jo’;
(min) SELECT MIN(prix) FROM BarÀBière
WHERE bar = ‘Jo’;
16Pendant ce temps, Jo exécute les instructions suivantes:
(del) DELETE FROM BarÀBière
WHERE bar = ‘Jo’;
(ins) INSERT INTO BarÀBière
VALUES(‘Jo’, ‘Kwak’, 3.50);
On a des instructions SQL qui peuvent être entrelacées, avec les contraintes suivantes: (max) doit être
exécuté avant (min), et (del) doit être exécuté avant (ins). Que se passe-‐-t-‐-il lorsque Jo et Paul mettent à
jour la base ? Si les instructions ont lieu dans l’ordre suivant: (max)(del)(ins)(min), on obtient:
Prix 2,50 | 3,00 2,50 | 3,00 3,50
Instruction (max) (del) (ins) (min)
Résultat 3,00 3,50
Ainsi, Paul voit que MAX < MIN !
Comment peut-‐-on résoudre le problème avec les transactions ? Si l’on regroupe les instructions
(max)(min) de Paul dans une seule transaction, alors il n’y aura plus de problèmes. En effet, soit la
transaction s’exécutera avant les modifications de Jo, et Paul verra alors les anciens prix, soit la trans-‐-
action s’exécute après la modification, et il n’y aura pas de problème. La transaction permet donc aux
deux instructions (max)(min) de s’exécuter sur les mêmes données.
Il existe cependant encore une possibilité de comportement étrange. Supposons que Jo exécute sa mo-‐-
dification de prix, mais qu’au dernier moment, il change d’avis et exécute un ROLLBACK. Si Paul
exécute sa transaction après l’instruction (ins), mais avant l’annulation, il va voir une valeur 3,50 qui
n’existe pas dans la base. Pour résoudre ce problème, on va donc exécuter les instructions de Jo dans
une transaction. Ainsi, les effets de (del)(ins) dans une transaction ne pourront être vus par d’autres
transactions que lorsque la transaction aura été validée. Si la transaction venait à être annulée, ses ef-‐-
fets ne seraient pas vus par les autres transactions.
2.1.6 Gestion des transactions dans Oracle
Une transaction débute avec la première instruction SQL exécutable et se termine lors de l’exécution
d’un commit ou d’un rollback, lors de la déconnexion de l’utilisateur (commit), ou lors d’un arrêt
anormal du processus utilisateur (rollback).
Les mises à jour faites par une transaction ne sont visibles pour les autres utilisateurs qu’après la vali-‐-
dation de la transaction (tant qu'ʹune transaction n'ʹest pas validée, les autres utilisateurs accèdent aux
anciennes valeurs des données modifiées).
2.2 La tolérance aux pannes
2.2.1 Journal
Il existe plusieurs types d’incidents qui peuvent survenir sur une base de données :
• échec d’une transaction: une erreur logique dans le programme l'ʹempêche de se poursuivre norma-‐-
lement (erreur lors d'ʹune insertion, suppression ou mise à jour), ou une erreur système arrête le dé-‐-
roulement normal du programme (verrouillage, saturation, processus tué),
• crash système: il entraîne la perte des données en mémoire centrale,
• panne disque: elle provoque la perte physique des données.
Les algorithmes de récupération (recovery) sont des techniques qui permettent aux SGBD d’assurer la
cohérence, l’atomicité et la durabilité malgré les incidents qui peuvent survenir. En général, les algo-‐-
rithmes de récupération possèdent deux parties: la première prend en charge les actions qui ont lieu
lors du déroulement normal de la transaction afin d’avoir assez d’informations pour permettre la ré-‐-
cupération en cas de problème, et la deuxième qui prend en charge les actions à effectuer après un
problème afin de pouvoir récupérer la base dans un état cohérent.
17Pour assurer la reprise sur panne, les SGBD et Oracle en particulier utilisent la notion de journal. Un
journal est un fichier texte dans lequel le SGBD inscrit, dans l’ordre d’exécution, toutes les actions de
mise à jour qu’il effectue. Ainsi, le journal est une séquence d’enregistrements qui mémorise les mises
à jour faites sur la base. Lorsqu’une transaction Ti démarre, elle s’enregistre dans le journal sous la
forme <début transaction, Ti >. Avant que la transaction Ti exécute une instruction écrire(X), un enregis-‐-
trement <Ti, X, V1, V2> est écrit dans le journal (V1 est la valeur de X avant l’écriture, et V2 est la valeur
de X après l’écriture). Lorsque la transaction Ti a lu une valeur, un enregistrement <lecture, Ti, X> est
écrit dans le journal. Enfin, <valider, Ti> ou <annuler, Ti> sont écrits dans le journal suivant que la
transaction a été validée ou annulée.
En Oracle, la gestion des transactions utilise deux fichiers :
• un fichier journal redo log: il enregistre toutes les modifications effectuées (insert, update, delete)
dans les tables de la base par chaque transaction.
• un fichier rollback segment: il enregistre les anciennes valeurs des lignes des tables modifiées par
une transaction.
Le système affecte à chaque transaction un numéro chronologique (SCN – System Control Number) qui
permet de l’identifier de manière unique. Toute opération modifiant une donnée de la base est enregis-‐-
trée dans le fichier rollback segment et dans le fichier journal redo log avant mise à jour de la base. Le
journal redo log est chronologique.
Lors du commit d'ʹune transaction, il faut :
• enregistrer le commit de la transaction dans les fichiers redo log et rollback segment,
• débloquer les lignes des tables verrouillées par la transaction.
Lors du rollback d'ʹune transaction, il faut :
• redonner les anciennes valeurs à toutes les lignes des tables modifiées par la transaction (à partir des
rollback segment),
• débloquer les lignes des tables verrouillées par la transaction.
2.2.2 Reprise après incident
Elle est disponible uniquement pour les incidents sans perte de données sur disque. L’objectif est de
restaurer la base dans un état cohérent telle qu'ʹelle se trouvait juste avant la panne. Le mécanisme de
reprise est le suivant:
• appliquer toutes les modifications enregistrées dans le fichier redo log à la base de données (roll-‐-
forward)
• pour toutes les transactions sans commit, on remet les lignes des tables concernées aux anciennes
valeurs (rollback). Ceci est fait à partir des rollback segment.
Après un incident, on ne traite que les modifications effectuées après le point de reprise (ou point de
contrôle). Un point de reprise consiste à 1) écrire les buffers du fichier redo log sur disque, 2) écrire les
buffers de la base de données sur disque, 3) écrire un article point de reprise dans le fichier redo log.
On peut préciser un point de reprise en utilisant la commande SAVEPOINT pdr ;. Par la suite, on
pourra revenir à ce point en utilisant la commande ROLLBACK TO pdr; qui permet de retrouver l’envi-‐-
ronnement tel qu’il était lors de la déclaration du point de reprise.
SQL Résultats
SA VEPOINT a; Premier point de reprise de la transaction
DELETE …; Modification de la base
SA VEPOINT b; Deuxième point de reprise de la transaction
INSERT INTO…; Modification de la base
SA VEPOINT c; Troisième point de reprise de la transaction
UPDATE …; Modification de la base
18ROLLBACK TO c; L’ordre UPDATE est annulé, le point C reste défini
ROLLBACK TO b; L’ordre INSERT est annulé, le point C est perdu, le point B reste défini
ROLLBACK TO c; ORA-‐-01086 error; savepoint C no longer defined
INSERT TO…; Modification de la base
COMMIT; Valide toutes les actions effectuées par le DELETE (première modification)
et le INSERT (dernière modification). Toutes les autres modifications ont été
annulées avant le COMMIT. Le point A n’est plus actif.
EXEMPLE: traitement des transactions
La mise en œuvre du mécanisme de reprise s’effectue comme ceci. Soient les 5 transactions suivantes
au moment d'ʹun incident :
T1
T2
T3
T4
T5
Point de reprise Incident
• T1 est achevée lors du point de reprise, elle n'ʹest pas traitée.
• T2 et T4 sont validées (commit) lorsque survient l'ʹincident: on applique toutes les modifications en-‐-
registrées dans le fichier redo log à la base de données (rollforward); pour T2, on repart du point de
reprise.
• T3 et T5 ne sont pas validées (pas de commit) lorsque survient l'ʹincident, on remet les lignes des
tables concernées aux anciennes valeurs (rollback).
2.3 La gestion de la concurrence
La gestion des accès concurrents aux données permet d’éviter que la mise à jour simultanée des mê-‐-
mes données par plusieurs utilisateurs n’introduise pas des incohérences dans la base de données. On
dit que deux transactions sont concurrentes si elles accèdent simultanément aux mêmes données.
2.3.1 Accès concurrents et incohérence des données
V oici quelques problèmes classiques qui peuvent survenir avec des transactions concurrentes.
La perte de mise à jour
Il y a perte de mise à jour quand une transaction T2 vient écraser une écriture effectuée par T1.
Temps t1
t2
t3
t4
t5
t6
t7
Transaction T1 État de la base Transaction T2
lire(A)
…
A = A + 10
…
…
écrire(A)
…
A = 10
A = 20
A = 60
…
lire(A)
…
…
A = A+50
…
écrire(A)
Après une exécution séquentielle de T1 et T2 ou T2 et T1, on obtient A=70. Si les transactions sont exé-‐-
cutées de manière concurrentes, on obtient alors A=60. On a donc perdu la première mise à jour.
19Les lectures impropres
Supposons une transaction T2 qui lit une donnée A modifiée par T1. La transaction T1 est annulée et
les modifications effectuées par cette transaction sont défaites. La valeur lue et traitée par T2 est alors
incorrecte.
Temps Transaction T1 État de la base Transaction T2
t1
t2
t3
t4
t5
lire(A)
A = A +20
écrire(A)
…
rollback
A = 10
A = 30
A = 10
…
…
…
lire(A)
…
Les lectures non reproductibles
La transaction T2 lit la même donnée A à deux instants différents et n'ʹobtient pas la même valeur. En-‐-
tre les deux lectures, une autre transaction a modifié la valeur de A.
Temps Transaction T1 État de la base Transaction T2
t1
t2
t3
t4
t5
A = 10
…
lire(A)
A = A + 10
écrire(A)
commit
A = 20
lire(A)
…
…
…
lire(A)
2.3.2 Le mécanisme de verrouillage
Les principales techniques mises en œuvre pour le contrôle de l’exécution concurrente des transac-‐-
tions reposent sur le concept de verrouillage des données. Un verrou est une variable associée à une
donnée qui décrit l’état de la donnée, compte tenu des opérations qui peuvent lui être appliquées.
Ainsi, avant d'ʹaccéder à une donnée pour modifier sa valeur, la transaction T1 doit la verrouiller pour
éviter son accès par une autre transaction. Une fois terminée, la transaction T1 libère alors les données
verrouillées pour les rendre disponibles à d'ʹautres transactions.
Nous reprenons l'ʹexemple du transfert d'ʹune somme d'ʹargent entre deux comptes: T1 fait un transfert
de c1 vers c2, T2 de c1 vers c3.
T1 T2
lock(c1)
read(c1) for update
c1:=c1-‐-m1 T2 attend la libération de c1
écrire(c1) (demande accès pour update de c1)
lock(c2) "ʺ
read(c2) for update "ʺ
c2:=c2+m1 "ʺ
écrire(c2) "ʺ
unlock(c1,c2) lock(c1)
read(c1) for update
c1:=c1-‐-m2
écrire(c1)
lock(c3)
read(c3) for update
c3:=c3+m2
écrire(c3)
20unlock(c1,c3)
Le verrouillage tel qu'ʹil est appliqué ci-‐-dessus permet d'ʹéliminer les pertes de mise à jour et les lectu-‐-
res impropres. Par contre, il ne permet pas d'ʹéliminer les lectures non reproductibles.
Les verrous classiques sont les verrous binaires, c’est-‐-à-‐-dire des verrous qui peuvent avoir deux va-‐-
leurs distinctes: verrouillé ou non verrouillé (1 ou 0). Un verrou est associé à chaque élément X. Si la
valeur du verrou sur X est 0, alors il est possible d’accéder à l’élément. Le verrouillage binaire utilise
deux opérations: verrouillerÉlément et déverrouillerÉlément. Une transaction demande l’accès à
un élément X en exécutant pour commencer l’opération verrouillerÉlément(X). Si le verrou est à 1,
la transaction doit attendre. Si le verrou est à 0, le verrou est mis à 1, et la transaction est autorisée à
accéder à l’élément X. Lorsque la transaction n’a plus besoin d’utiliser l’élément, elle exécute une opé-‐-
ration déverrouillerÉlément(X) qui positionne le verrou à 0 afin que les autres transactions puis-‐-
sent accéder à X. Un verrou binaire applique donc une exclusion mutuelle sur une donnée.
On se rend compte rapidement que les verrous binaires sont trop restrictifs pour les bases de données,
car certaines transactions ne veulent que lire certaines données. On distingue donc deux types de ver-‐-
rous, les verrous partagés, qui permettent à plusieurs transactions de lire une donnée verrouillée par
une transaction, et les verrous exclusifs, qui permettent à la transaction qui a posé le verrou d’effec-‐-
tuer une opération d’écriture.
2.3.3 Le risque d'ʹinterblocage
Un interblocage (ou verrou mortel) survient lorsque chaque transaction T d’un ensemble de n (n ≥ 2)
transactions attend une donnée verrouillée par une autre transaction T’ de l’ensemble. Autrement dit,
T1 attend une donnée verrouillée par T2, et T2 attend une donnée verrouillée par T1.
EXEMPLE : transfert entre deux comptes.
T1 transfère une somme m d’un compte c1 vers un compte c2, et T2 transfère une somme n de c2 vers
c1. L'ʹexécution simultanée des deux transactions conduit à la situation suivante :
T1 T2
lock(c1)
read(c1)
c1:=c1+m lock(c2)
écrire(c1) read(c2)
c2:=c2+n
T1 attend libération de c2 "ʺ écrire(c2)
T2 attend libération de c1
"ʺ "ʺ
"ʺ "ʺ
Les données sont verrouillées en fonction des demandes de mises à jour, mais ne sont libérées qu’en
fin de transaction
2.3.4 Résolution de l'ʹinterblocage (deadlock)
Une approche pratique de la gestion des interblocages repose sur la détection de ceux-‐-ci: le système
vérifie s’il y a une situation d’interblocage. Un procédé pour détecter une situation d’interblocage con-‐-
siste pour le système à construire et à maintenir un graphe d’attente des ressources (wait-‐-for graph).
Dans ce graphe, un nœud est créé pour chaque transaction en cours d’exécution. Chaque fois qu’une
transaction Ti attend de pouvoir verrouiller une donnée X verrouillé par une transaction Tj, un arc est
créé entre les deux transactions. Il y a situation d’interblocage si et seulement si il existe un cycle dans
le graphe. Il se pose alors le problème de savoir quand le système doit vérifier la présence d’un inter-‐-
blocage (nombre de transactions, durée d’attente de plusieurs transactions,…). Si le système détecte
l’interblocage, il tue une (ou plusieurs) des transactions impliquées. Il existe différentes solutions pour
le choix de la transaction à tuer : la plus récente, celle qui a fait le moins de mises à jour … D’autres
solutions plus élaborées peuvent être utilisées, mais ne seront pas traitées dans le cadre de ce cours.
Une autre possibilité pour gérer les interblocages consiste à employer des mises hors délais (timeouts).
21Cette méthode est pratique en raison du peu d’activité qu’elle implique sur le système. Si une transac-‐-
tion attend plus longtemps que la durée spécifiée pour la mise hors délai, le système suppose qu’elle
est bloquée et il tue cette transactions, qu’il y ait ou non interblocage.
La détection des interblocages
Pour détecter les interblocages, on construit le graphe d’attente des ressources :
X
T1 T2
Y
X, Y ,… représentent des éléments des tables de la base. T1, T2 …. identifient des transactions. Un arc
orienté étiqueté X ou Y entre Ti et Tj signifie que la transaction Ti attend la libération de X ou Y . L'ʹin-‐-
terblocage se traduit par un circuit dans le graphe d’attente des ressources, comme dans la figure ci-‐-
dessus.
RAPPEL: l'ʹinterblocage peut mettre en jeu n (n≥2) transactions.
X T2
T1
Y
Z
T3
2.3.5 Niveaux d'ʹisolation
SQL définit quatre niveaux d’isolation qui permettent de choisir quelles sont les types d’interactions
autorisées pour les transactions qui s’exécutent simultanément (concurrentes). Ainsi, dans une trans-‐-
action, on peut utiliser l’instruction suivante:
SET TRANSACTION ISOLATION LEVEL X
où X = SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED
T ransactions de niveau serializable
Si on reprend l’exemple de la section 4.1.5, et si on suppose que Paul = (max)(min) et Jo = (del)(ins)
sont des transactions, et si Paul utilise le niveau d’isolation SERIALIZABLE, alors il verra la base dans
l’état soit avant les modifications de Jo, soit après, mais pas entre les deux opérations de la transaction
de Jo.
Le niveau d'ʹisolation est un choix qui affecte uniquement la vue de la base de la transaction que le
spécifie. Si on reprend notre exemple (cf section 4.1.5), si Jo choisit le niveau SERIALIZABLE, mais pas
Paul, alors Paul peut éventuellement ne voir aucun prix si la requête est exécutée entre (del) et (ins).
T ransactions de niveau repeatable read
Seules les données validées peuvent être lues, ce qui implique que les lectures répétées dans une
même transaction retourne les mêmes valeurs (pas de phénomène de lectures non reproductibles).
Cependant, une transaction pourra voir apparaître au cours des lectures répétées de nouveaux n-‐-u-‐-
plets (ou des n-‐-uplets qui ont disparu).
Sur notre exemple, si Paul a choisi le niveau REPEATABLE READ, et que l’ordre d’exécution est
(max)(del)(ins)(min), alors (max) verra les prix 2,50 et 3,00, et (min) verra 3,50, mais également 2,50 et
3,00 car ils ont été vus par la lecture précédente de (max) dans la transaction.
T ransactions de niveau read committed
Seules les données validées peuvent être lues, mais des lectures successives peuvent renvoyer des va-‐-
leurs (validées) différentes. Cela permet de voir les modifications apportées par d’autres transactions.
22Sur notre exemple, si Paul a choisi le niveau READ COMMITTED, alors il peut voir les valeurs validées,
mais pas nécessairement les mêmes à chaque requête. Ainsi, avec READ COMMITTED, l’entrelacement
(max)(del)(ins)(min) est autorisé, aussi longtemps que Jo valide (mais Paul peut voir MAX < MIN).
T ransactions de niveau read uncommitted
Une transaction qui s’exécute en niveau d’isolation READ UNCOMMITTED peut voir des données dans la
base qui ne sont pas validées par une autre transaction (et qui ne le seront peut-‐-être jamais).
Sur notre exemple, si Paul a choisi le niveau READ UNCOMMITTED, il pourra voir le prix 3,50, même si Jo
abandonne la transaction.
2.3.6 V errouillage et niveaux de granularité
Les performances du contrôle de la concurrence est affectée par la taille des éléments à verrouiller. Par
exemple, dans une base de données, on a la valeur d’un attribut d’un n-‐-uplet, un n-‐-uplet, une table, ou
toute la base. Selon que l’on pose un verrou sur un élément particulier, on peut bloquer ou non plu-‐-
sieurs transactions. En particulier, il faut remarquer que plus la taille des éléments à verrouiller est
importante, plus le degré de concurrence autorisé est faible. Par exemple, si une transaction veut blo-‐-
quer toute une table (et si elle ne souhaite accéder qu’à un n-‐-uplet particulier), toutes les autres trans-‐-
actions seront mises en attente alors qu’il n’est peut être pas nécessaire de bloquer toute la table. In-‐-
versement, si on verrouille des éléments de taille plus petite, il peut y avoir beaucoup d’éléments à
verrouiller, et donc le gestionnaire de verrouillage devra gérer un plus grand nombre de verrous
(beaucoup d’opérations de verrouillage/déverrouillage). La nature des verrous à poser dépend donc
de la nature des transactions. Par exemple, si une transaction accède à un petit nombre d’enregistre-‐-
ments, il est préférable que la granularité soit l’enregistrement. Par contre, si une transaction accède à
de nombreux enregistrements d’une même table, alors la granularité qui semble la plus appropriée
semble être la table.
2.4 Le verrouillage sous Oracle
2.4.1 Principe
Oracle implante un verrouillage au niveau de la ligne, et utilise un mécanisme appelé Read consistency
(lecture cohérente). Grâce à ce mécanisme, les mises à jour et les lectures ne se bloquent pas mutuel-‐-
lement. Toutes les données retournées par un SELECT proviennent d’un seul point dans le temps. On
ne voit que les données validées au moment du SELECT. Pour les données non validées, on voit les
anciennes valeurs (grâce au Rollback segment). Les données modifiées par une autre transaction après
le début du SELECT ne sont pas vues.
Il existe une concurrence d’accès en mise à jour: la première transaction qui accède à une donnée posi-‐-
tionne un verrou sur les données accédées (n-‐-uplets ou tables), les autres transactions souhaitant accé-‐-
der les mêmes données seront mises en attente.
Ce mécanisme ne prend pas en compte les lectures non reproductibles. On peut, pour résoudre ce
problème, utiliser une transaction spéciale appelée une transaction à lecture seulement (Read Only
T ransaction). Cette transaction conserve, lorsqu'ʹelle démarre, l’état de la base et travaille ensuite uni-‐-
quement sur cet état, jusqu'ʹà la fin de la transaction. Une telle transaction ne doit comporter que des
lectures de la base, et les modifications des données de la base sont interdites. La syntaxe est:
SET TRANSACTION READ ONLY
instruction 1
…
instruction n
COMMIT
2.4.2 Niveaux d’isolation
En fixant le niveau d’isolation des transactions, on définit le mode de fonctionnement en parallèle des
différentes transactions qui s’exécutent au même moment. La commande suivante indique le niveau
d’isolation de la transaction qui vient de commencer :
23SET TRANSACTION ISOLATION LEVEL {SERIALIZABLE | READ COMMITTED}
Oracle permet deux niveaux d’isolation des transactions les unes par rapport aux autres :
• READ COMMITTED : c’est le mode par défaut des transactions d’Oracle. Il empêche les principaux
problèmes de concurrence mais pas les lectures non reproductibles. Tout d’abord, les modifications
effectuées par une transaction ne sont connues des autres transactions que lorsque la transaction a
été confirmée (COMMIT). Oracle gère automatiquement les accès concurrents de plusieurs transac-‐-
tions sur les mêmes n-‐-uplets de table. Si une transaction est en train de modifier des n-‐-uplets d’une
table, les autres transactions peuvent lire les données telles qu’elles étaient avant ces dernières mo-‐-
difications, mais les autres transactions sont bloquées automatiquement par Oracle si elles souhai-‐-
tent modifier ces mêmes lignes.
• SERIALIZABLE : si une transaction SERIALIZABLE essaie de modifier une donnée qui pourrait avoir
été modifiée par une autre transaction non validée au début de la transaction SERIALIZABLE, alors
l’ordre de modification échoue (résolution du problème de lecture non reproductibles). Ce mode est
coûteux puisqu’il limite le fonctionnement en parallèle des transactions (les transactions s’exécutent
concurremment comme si elles s’exécutaient les unes après les autres).
2.4.3 Différents niveau de verrouillage
V errouillage de niveau n-‐-uplet
Par défaut, Oracle met en œuvre un verrouillage de niveau n-‐-uplet, c’est-‐-à-‐-dire une stratégie de ver-‐-
rouillage au niveau des n-‐-uplets, chaque n-‐-uplet d’une table pouvant être verrouillé individuellement.
Les n-‐-uplets verrouillés peuvent alors être mis à jour uniquement par la transaction qui les a ver-‐-
rouillés. Tous les autres n-‐-uplets de la table peuvent être mis à jour par d’autres transactions. De plus,
les autres transactions gardent également la possibilité de lire les n-‐-uplets, y compris ceux qui sont mis
à jour. Pour ces derniers, les transactions ont accès à l’ancienne valeur (grâce au rollback segment) jus-‐-
qu’à ce que la transaction soit validée (lecture cohérente).
Lorsqu’une transaction pose un verrou sur un n-‐-uplet, Oracle effectue les opérations suivantes:
• Premièrement, un verrou DML (data manipulation language) est posé. Ce verrou évite que d’autres
transactions puissent mettre à jour (ou poser un verrou) sur le n-‐-uplet. Ce verrou ne sera relâché que
lorsque la transaction qui a posé le verrou aura été validée ou annulée,
• Deuxièmement, un verrou DDL (data dictionary language) est posé sur la table afin d’éviter les modifi-‐-
cations structurelles de la table (suppression de la table, retrait ou ajout d’un attribut,…). Ce verrou
ne sera relâché que lorsque la transaction qui a posé le verrou aura été validée ou annulée.
V errouillage de niveau T able
Avec le verrouillage au niveau table, la table entière est verrouillée. Dès qu’une transaction a ver-‐-
rouillé une table, seule cette transaction peut mettre à jour (ou verrouiller) n’importe quel n-‐-uplet de la
table. Aucun des n-‐-uplets de la table ne peut être mis à jour par une autre transaction. Cependant, les
autres transactions peuvent malgré tout lire n’importe quel n-‐-uplet, y compris ceux qui sont mis à
jour.
Relâcher les verrous
Souvent, les utilisateurs pensent être seuls au monde. C’est précisément ce genre de comportement
qui crée les problèmes de blocage. Souvenez-‐-vous que poser un verrou (sur un n-‐-uplet ou sur une ta-‐-
ble) n’est pas une opération anodine, et que cela peut bloquer beaucoup d’autres transactions. C’est
pourquoi il faut veiller à verrouiller de manière approprié, c’est-‐-à-‐-dire qu’il faut protéger uniquement
la partie de votre transaction qui est critique (mise à jour, calcul d’une moyenne, somme,…), et qu’il
faut également relâcher le verrou. Il faut donc être conscient que l’on relâche un verrou en validant
(COMMIT) ou en annulant (ROLLBACK) la transaction.
2.4.4 Les différents modes de verrouillage
Oracle propose deux modes de verrouillage:
24• le mode exclusif (X) qui empêche les ressources verrouillées d’être partagées. C’est le mode
privilé-‐- gié pour mettre à jour des données. La transaction qui pose un verrou exclusif la
première est la seule transaction qui peut modifier la table, et ce jusqu’à ce que le verrou soit
relâché.
• le mode partagé (S) permet à une ressource d’être partagée. Plusieurs transactions peuvent avoir
un verrou partagé et peuvent ainsi éviter qu’une autre transaction obtienne un verrou exclusif.
Oracle gère les types de verrous suivants: row share (RS), row exclusive (RX), share (S), share
row exclusive (SRX), et exclusive (X).
V errous exclusifs
SQL V errou
SELECT … FROM table… pas de verrou
INSERT INTO table… RX
UPDATE table… RX
DELETE FROM table… RX
LOCK TABLE table IN ROW EXCLUSIVE MODE RX
LOCK TABLE table IN SHARE ROW EXCLUSIVE MODE SRX
LOCK TABLE table IN EXCLUSIVE MODE X
V errous partagés
SQL V errou
SELECT … FROM table FOR UPDATE OF… RS
LOCK TABLE table IN ROW SHARE MODE RS
LOCK TABLE table IN SHARE MODE S
LOCK TABLE table IN SHARE ROW EXCLUSIVE MODE SRX
2.5 JDBC et les transactions
2.5.1 JDBC = Java DataBase Connectivity
JDBC est une API d’accès aux systèmes de gestion de base de données relationnelles qui permet
d’exécuter des requêtes SQL au sein d’un programme Java et de récupérer les résultats, ce qui
représente une alternative aux solutions propriétaires. C’est de plus une tentative de standardiser
l’accès aux bases de données car l’API est indépendante du SGBD choisi, pourvu que le pilote
JDBC existe pour ce SGBD, et qu’il implémente les classes et interfaces de l’API JDBC.
Pour effectuer un traitement avec une base de données, il faut :
1. charger un pilote en mémoire,
2. établir une connexion avec la base de données,
3. récupérer les informations relatives à la connexion,
4. exécuter des requêtes SQL et/ou des procédures stockées,
5. récupérer les informations renvoyées par la base de données (si nécessaire),
6. fermer la connexion.
Pour plus de détails, consulter le polycopié sur JDBC.
252.5.2 Gestion des transactions
L’instance de l’objet Connection fournit les méthodes pour :
Activer/désactiver la validation automatique de chaque requête passée (activé par défaut) :
public void setAutoCommit(boolean autoCommit) throws SQLException;
Valider manuellement la/les requête(s) passée(s) :
public void commit() throws SQLException;
Annuler les dernières modifications faites par la/les requête(s) passée(s) :
public void roolback() throws SQLException;
Exemple :
String sql1 = "UPDATE vendeur SET sal = 1215 WHERE sal < 1215";
String sql2 = "DELETE FROM vendeur WHERE sal < 1215";
try {
[Link](false);
Statement state = [Link]();
[Link](sql1);
Statement state2 = [Link]();
[Link](sql2);
[Link]();
...
} catch (Exception e) {
try{
[Link]();
} catch (SQLExection e) {
...
}
...
}
JDBC supporte le mode transactionnel qui consiste à valider tout ou une partie d’un ensemble
d’instructions. Nous avons déjà décrit à la section « Interface Connection » les méthodes qui
permettent à un programme Java de coder des transactions (setAutoCommit, commit et rollback).
Par défaut, chaque instruction SQL est validée (on parle d’autocommit). Lorsque ce mode est
désactivé, il faut gérer manuellement les transactions avec commit ou rollback.
Quand le mode autocommit est désactivé :
La déconnexion d’un objet Connection (par la méthode close) valide implicitement la
transaction (même si commit n’a pas été invoqué avant la déconnexion).
Chaque instruction (CREATE, ALTER, DROP) valide implicitement la transaction.
26
CHAPITRE 1: BASES DE DONNÉES RELATIONNELLES
1. Les Systèmes de Gestion de Bases de Données (SGBD)
2. Introduction à la conception de bases de données relationnelles
3. Décomposition de schémas relationnels
4. Normalisation des relations
5. Dépendances fonctionnelles et conception de schémas
1.1 Les Systèmes de Gestion de Bases de Données (SGBD)
Un système de base de données peut être décrit par l’équation suivante:
Système de Base de Données = Base de Données + SGBD
Un SGBD est un système permettant de gérer et de manipuler la base de données, et une base de
données est une collection de données en relation qui sont:
1. partagées par de multiples applications (utilisateurs et/ou programmes),
2. stockées avec une redondance minimum,
3. indépendantes des applications,
4. organisées afin d’être une fondation pour de futures applications.
Le modèle de données est le formalisme qui décrit la structure logique de la base de données et les
opérations sur celle-‐-ci.
Le schéma de base de données est la structure de la base de données. L’instance de la base de don-‐-
nées est le contenu actuel de la base de données.
Une base de données est donc constituée d’une part d’un schéma de base de données et d’une instance de
la base de données d’autre part. On peut, par analogie avec les langages de programmation, définir les
correspondances suivantes:
modèle de données schéma ↔ ↔ instance ↔ variable
langage de programmation
déclaration d’une structure de données
1.1.1 Modèle de Données Relationnel
Une instance de la base de données peut être considérée comme une collection de relations mathéma-‐-
tiques. Chaque relation est représentée par une table dont chaque colonne est appelée un attribut et
chaque ligne est appelée un tuple ou n-‐-uplet. On associe à chaque attribut un ensemble de valeur, ap-‐-
pelé domaine.
Un schéma de relations est alors défini comme un ensemble d’attributs.
EXEMPLE
EMPLOYÉ = {nom, nosécu, nomdépartement, salaire, datenaissance}
CONVENTION DE NOTATION
EMPLOYÉ (nom, nosécu, nomdépartement, salaire, datenaissance)
Un schéma de base de données est une collection de schémas de relations.
EXEMPLE
{ EMPLOYÉ, DÉPARTEMENT, PROJET }
NOTATIONS
schéma de relations R R(A1,A2,...,An)
n-‐-uplet <v1,v2,...,vn>
valeur de l’attribut Ai t[Ai]
valeurs des attributs t[Au,Aw,...Az]
attribut A du schéma R R.A
11.1.2 Contraintes d’intégrité
Il existe un certain nombre de propriétés qui doivent être respectées pour chaque instance d’un sché-‐-
ma de relations ou d’un schéma de base de données afin de préserver la cohérence des informations
stockées dans la base. Ces propriétés sont appelées contraintes d’intégrité.
Les dépendances entre données sont des contraintes d’intégrité qui spécifient les relations entre les
valeurs des attributs. Elles sont très utiles dans la conception de bases de données.
1.2 Introduction à la conception de bases de données relationnelles
1.2.1 Deux approches pour concevoir un schéma de base de données
Il existe deux approches pour concevoir un schéma de base de données: une approche descendante,
également appelée méthode par décomposition, et une approche ascendante, également appelée mé-‐-
thode synthétique. Nous présentons rapidement pourquoi la conception d’un schéma de base de don-‐-
nées peut être présenter des anomalies. Les dépendances fonctionnelles sont un outil théorique qui
permet de vérifier la qualité de conception d’un schéma et de comprendre les conséquences de la re-‐-
dondance de données.
1. Conception descendante (top-‐-down design)
On part d’un schéma de relations unique…
décomposition basée sur les dépendance entre données
(par exemple, les dépendances fonctionnelles)
…pour obtenir une collection de schémas de relations.
2. Conception ascendante (bottom-‐-up design)
On part d’une collection d’attributs…
synthèse (regroupement)
…pour obtenir une collection de schémas de relations.
QUESTIONS
• Quelles sont les propriétés intéressantes d’un schéma de base de données relationnelles ?
– mesure de la qualité du schéma,
– méthodologie de conception.
• Quels sont les algorithmes permettant d’obtenir un schéma possédant les bonnes propriétés ?
– outil dédié à la conception,
– conception automatique.
MESURE DE LA QUALITÉ
1. sémantique des attributs
Plus il est facile d’expliquer la sémantique des attributs d’une relation, plus la conception du
schéma de relations est bonne.
PRINCIPE 1: concevoir un schéma de relations de telle sorte qu’il soit simple d’expliquer ce
qu’il représente.
EXEMPLE
Que signifie FOURNIT (f#, nom, adresse, p#, produit, prix, couleur, nomproj, dép) ?
Ce schéma de relations doit être décomposé comme suit:
PROD(p#, produit, couleur)
FOURNITPROD(f#, nom, adresse,p#, produit, prix)
PROJET(nomproj, dép)
UTILISE(nomproj, p#)
Chaque schéma de relations et chaque attribut ont une sémantique précise.
22. les informations redondantes
Les informations redondantes, à l’origine de problèmes, doivent être supprimées dans la me-‐-
sure du possible.
PRINCIPE 2: concevoir un schéma de relations de telle manière que les insertions, les suppres-‐-
sions et les mises à jour ne posent pas de problèmes.
EXEMPLE
Si on utilise la relation suivante FOURNITPROD(f#, nom, adresse, p#, produit, prix) plutôt
que le schéma de relations suivant:
FOURNISSEUR(f#, nom, adresse)
FOURNIT(f#, p#, prix)
alors le nom et l’adresse d’un fournisseur sont stockés plusieurs fois dans les n-‐-uplets corres-‐-
pondant aux produits vendus par le fournisseur.
QUAND Y-‐-A-‐-T-‐-IL REDONDANCE D’INFORMATION ?
On constate assez facilement que la même adresse apparaît autant de fois qu’il y aura de produits si
l’on utilise la relation FOURNITPROD(f#, nom, adresse, p#, produit, prix). Or on sait qu’un fournis-‐-
seur ne possède qu’une seule adresse et cela même s’il vend plusieurs produits. On appelle cette
propriété une dépendance fonctionnelle. Un mauvais schéma relationnel peut alors entraîner des
anomalies lors des manipulations.
f# nom Labaleine Lemelon adresse p# produit prix
F1 Paris P1 parapluie 110
F2 Lyon P2 chapeau 50
F3 Toutcuir Lyon P3 sac à main 650
F1 Labaleine Paris P4 parasol 150
F1 Labaleine Paris P5 ombrelle 70
F4 Letour Nantes P6 ceinture 55
F5 P3 650
Legrand Paris sac à main Dans la relation ci-‐-dessus, il existe des redondances qui peuvent engendrer les difficultés
suivantes:
• anomalie d’insertion. Telle qu’elle se présente, cette relation ne permet pas de mémoriser dans
la base un produit dont le fournisseur n’existe pas.
• anomalie de suppression. La disparition d’un fournisseur, qui est l’unique fournisseur d’un
produit, entraîne également la disparition des informations concernant ce produit (exemple:
Letour).
• anomalie de mise à jour. Toute modification sur le prix d’un produit qui apparaît plusieurs fois
dans la relation doit être répercutée sur tous les n-‐-uplets correspondants (exemple: sac à main).
Cela augmente le temps de mise à jour et les risques d’incohérence.
On résout ces problèmes en étudiant les dépendances entre les données, et en décomposant et norma-‐-
lisant les relations. On obtient ainsi des schémas de relations qui évitent les anomalies citées ci-‐-dessus.
Attention cependant à ne pas voir la normalisation comme un dogme. Il arrive parfois que, pour des
raisons d’efficacité notamment, on soit obligé de dénormaliser.
1.2.2 Dépendance Fonctionnelle (DF)
Soient R un schéma de relations, et X=A1,A2,…,An et Y=B1,B2,…,Bm des sous-‐-ensembles de R.
X détermine fonctionnellement Y , noté X → Y , ssi pour chaque instance r de la relation R, pour chaque
paire de n-‐-uplets t et s appartenant à r, t[X] = s[X] implique t[Y] = s[Y] (où t[X] désigne la projection du
n-‐-uplet t sur les attributs X).
Autrement dit, X → Y signifie qu’une valeur de X détermine au plus une valeur de Y.
3Une dépendance fonctionnelle est une propriété définie sur l'ʹintention du schéma et non son extension
(elle est donc invariante dans le temps et ne peut être extraite à partir d'ʹexemples). C'ʹest une propriété
qui doit être extraite de la connaissance que l'ʹon a de l'ʹapplication à modéliser et qui permet d’élimi-‐-
ner la redondance.
EXEMPLES
Considérons la relation suivante
FILM (titre, année, durée, type, studio, acteurPrincipal)
avec une instance de la relation contenant les n-‐-uplets suivants:
titre année durée type studio acteurPrincipal
StarWars 1977 124 couleur Fox Carrie Fisher
StarWars 1977 124 couleur Fox Mark Hamill
StarWars 1977 124 couleur Fox Harrison Ford
1991 104 couleur Disney Emilio Estevez
1991 95 couleur Paramount Dana Carvey
1992 95 couleur Paramount Mike Meyers
Mighty Ducks Wayne’s World Wayne’s World On peut en déduire les trois DF suivantes:
{titre, année} → durée
{titre, année} → type
{titre, année} → studio
Par contre, la dépendance suivante n’est pas une DF:
{titre, année} → acteurPrincipal
En effet, étant donné un film, il peut exister dans la base (telle qu’elle est modélisée) plusieurs acteurs
principaux.
Enfin, la DF {titre, année} → durée signifie qu’il ne peut exister dans une instance de FILM les deux n-‐-
uplets suivants:
titre année durée type studio acteurPrincipal
Farenheit, 9/11 2004 124 couleur Fox Georges Bush
Farenheit, 9/11 2004 130 couleur Fox Dick Cheney
CONVENTIONS
• L’ensemble de DF suivant:
{A1,A2,…,An} → B1
{A1,A2,…,An} → B2
…
{A1,A2,…,An} → Bm
est équivalent à {A1,A2,…,An} → B1,B2,...,Bm.
41.2.3 Propriétés des DF
Les trois premières propriétés (réflexivité, augmentation et transitivité) sont également appelés axio-‐-
mes d’Armstrong. De ces trois axiomes, on peut en déduire trois autres propriétés (pseudo-‐-transitivité,
union et décomposition).
Si Y ⊆ X, alors on a X → Y
RÉFLEXIVITÉ
Si X → Y , alors on a X ∪ Z → Y ∪ Z
AUGMENTATION
TRANSITIVITÉ
PSEUDO-‐-TRANSITIVITÉ
Si X → Y et Y ∪ W → Z, alors X ∪ W → Z
Si X → Y et Y → Z, alors on a X → Z
Si X → Y et X → Z, alors X → Y ∪ Z
UNION
Si X → Y et Z ⊆ Y , alors X → Z
DÉCOMPOSITION
• les n-‐-uplets de la relation S sont la projection sur {B1,B2,…,Bm} de tous les n-‐-uplets de R. La pro-‐-
jection est l’opération qui consiste à construire la nouvelle relation S à partir de R en prenant
pour chaque n-‐-uplet t de R uniquement les attributs {B1,B2,…,Bm} et en éliminant les n-‐-uplets en
double,
• de manière similaire, les n-‐-uplets de la relation T sont la projection sur {C1,C2,…,Ck} de tous les n-‐-
uplets de R.
La décomposition de la relation R en R1,R2,…,Rn est sans perte si la jointure des relations R1,R2,…,Rn
permet de retrouver tous les n-‐-uplets de la relation R d’origine. La jointure est l’opération qui permet
de construire une nouvelle relation à partir de deux relations ayant au moins un attribut commun.
EXEMPLE
On peut décomposer la relation FILM définie précédemment en deux relations FILM1 et FILM2 telles
que:
FILM1 = (titre, année, durée, type, studio)
FILM2 = (titre, année, acteurPrincipal)
7Si on utilise la décomposition telle qu’elle est définie, on obtient au niveau des n-‐-uplets pour FILM1 et
FILM2 les résultats suivants:
titre année durée type studio
StarWars 1977 124 couleur Fox
Mighty Ducks 1991 104 couleur Disney
titre année acteurPrincipal
StarWars 1977 Carrie Fisher
StarWars 1977 Mark Hamill
StarWars 1977 Harrison Ford
1991 Emilio Estevez
1991 Dana Carvey
1992 Mike Meyers
Mighty Ducks Wayne’s World Wayne’s World On peut remarquer que cette décomposition élimine les problèmes
soulevés au paragraphe 1.2.1. La
redondance est éliminée, par exemple la durée de chaque film n’apparaît qu’une fois, dans la relation
FILM1. Le risque d’anomalie de mise à jour a ainsi disparu. De même, le risque d’anomalie de sup-‐-
pression a disparu. Si on supprime tous les acteurs du film Wayne’s World, le film disparaît égale-‐-
ment. Il apparaît que FILM2 possède malgré tout de la redondance, puisque titre et année apparais-‐-
sent plusieurs fois. Cependant, ces deux attributs forment une clé, et il n’est pas possible de représen-‐-
ter plus succinctement un film.
1.4 Normalisation des relations
Les formes normales de schémas de relations sont des propriétés souhaitables que doit posséder cha-‐-
que schéma de relations. Elles sont nécessaires (mais non suffisantes) pour une « bonne » conception.
Historiquement, les formes normales suivantes ont été proposées (de la moins restrictive à la plus res-‐-
trictive).
Première Forme Normale (1NF)
Deuxième Forme Normale (2NF)
Troisième Forme Normale (3NF)
Forme Normale de Boyce and Codd (BCNF)
Quatrième Forme Normale (4NF)
Cinquième Forme Normale (5NF)
Les formes normales définissent un ordre partiel sur les schémas de relation. On peut donc voir une
forme normale comme une classe d'ʹéquivalence (on peut comparer deux schémas dans deux classes
d'ʹéquivalence différentes mais pas dans la même). Il faut aussi noter que le seul élément qui est pris en
compte par les formes normales est la non redondance d'ʹinformations d'ʹun schéma. Selon les formes
normales, un « bon » schéma est un schéma sans redondance (ce qui ne veut pas forcément dire qu'ʹil
est efficace par exemple). Un schéma relationnel sans qualité particulière est appelé schéma en 1ère
forme normale (on note 1NF) et si on rajoute certaines qualités on obtient les deuxième et troisième
formes normales (on note 2NF et 3NF).
On ne présente ici que les formes normales dont la définition utilise exclusivement les dépendances
fonctionnelles. Si on prend en compte d'ʹautres dépendances entre données comme les dépendances
multivaluées, on obtient alors les 4NF et 5NF. La BCNF reste cependant l'ʹobjectif de normalisation le
plus « classique ».
1NF: une relation est en première forme normale ssi tout attribut a une valeur atomique (vrai par défi-‐-
nition du modèle relationnel).
82NF : une relation est en deuxième forme normale ssi elle est en 1NF et si tous les attributs non clés
sont pleinement dépendants des clés (toutes les dépendance entre une clé et un attribut non clé sont
des dépendances fonctionnelles élémentaires).
3NF : une relation est en troisième forme normale ssi elle est en 2NF et si tous les attributs non clés
sont directement et pleinement dépendants des clés (si tout attribut non clé ne dépend pas d'ʹun autre
attribut non clé).
BCNF (Boyce-‐-Codd) : une relation est en BCNF ssi elle est en 3NF et si les seules DFE sont celles de la
forme C → X avec C clé (seules les clés sont en partie gauche de DF).
1.4.1 Première forme normale (1NF)
Une relation R est dite en première forme normale (1NF) si tous ses attributs sont atomiques et qu’il
n’existe pas d’attributs répétitifs. De plus, chaque attribut doit avoir une sémantique précise. V oyons
pourquoi la relation suivante n’est pas en première forme normale.
titre année durée type studio
StarWars 1977 124 couleur Fox, Los Angeles
Mighty Ducks 1991 104 couleur Disney , San Francisco
Wayne’s World 1992 95 couleur Paramount, Los Angeles
Les attributs de cette relation ne sont pas atomiques. En effet, l’attribut studio contient à la fois le nom
et la ville, ce qui est gênant si l’on souhaite extraire tous les studios situés à Los Angeles.
Analysons maintenant un deuxième exemple. La relation suivante n’est pas non plus en 1NF.
titre année acteur1 acteur2 acteur3
StarWars 1977 Carrie Fisher Mark Hamill Harrison Ford
Mighty Ducks 1991 Emilio Estevez
Wayne’s World 1992 Dana Carvey Mike Meyers
En effet, la première forme normale stipule que les attributs ne doivent pas être répétitifs. Or, la liste
des acteurs ne respecte pas cette propriété. Si on veut rechercher dans quel film a joué Harrison Ford,
on est obligé non seulement de parcourir tous les n-‐-uplets, mais également toutes les colonnes. De
plus, si l’on souhaite rajouter un quatrième acteur, il faut modifier la relation toute entière.
Enfin, que pensez-‐-vous de la relation suivante:
titre année durée type studio
StarWars 1977 124 SF Fox
Mighty Ducks 1991 104 couleur Disney
Wayne’s World 1992 95 couleur Paramount
Il semble que cette relation soit en 1NF. Les attributs sont atomiques, il n’y a pas d’attributs répétitifs.
Malgré tout, l’attribut type ne possède pas une sémantique claire, représentant soit un genre (SF), soit
le type de la pellicule. Cette relation n’est donc pas en 1NF.
1.4.2 Deuxième forme normale (2NF)
Une relation R est dite en deuxième forme normale (2NF) ssi
• elle est en 1NF,
• tout attribut n’appartenant pas à une clé ne dépend pas d’une partie de cette clé (pas de dépen-‐-
dances partielles).
Autrement dit, dès qu’un attribut non clé dépend d’une partie d’une clé, la relation n’est pas en 2NF.
9V oyons dans un premier temps un exemple abstrait. La relation R(A,B,C) munie de l’ensemble F des
dépendances est en 1NF mais pas en 2NF.
A,B → C
B →C
Regardons maintenant sur un exemple concret. Considérons la relation suivante:
numSalarié nom numProjet heures
20036 Durand 1 18,5
20036 Durand 2 6,7
36900 Leroux 2 8,5
45002 Franck 3 23,5
45002 Franck 1 4,8
L’ensemble F des DF est:
numSalarié → nom
numSalarié,numProjet → heures
La relation n’est pas en 2NF. En effet, la clé minimale de cette relation est {numSalarié,numProjet}.
L’attribut non clé heure est en totale dépendance fonctionnelle avec la totalité de la clé. Par contre,
l’attribut non clé nom dépend d’une partie de la clé, à savoir numSalarié. Pour que la relation soit en
2NF, il est nécessaire de scinder la relation initiale en deux relations, comme ceci:
numSalarié numProjet heures
20036 1 18,5
20036 2 6,7
36900 2 8,5
45002 3 23,5
45002 1 4,8
numSalarié nom
20036 Durand
36900 Leroux
45002 Franck
Chacune de ces deux relations répond désormais aux exigences de la première et de la deuxième
forme normale. La première relation a pour clé primaire l’attribut numSalarié, et la deuxième relation
a pour clé {numSalarié,numProjet}.
1.4.3 T roisième forme normale (3NF)
OBJECTIFS DE LA 3NF
1. élimination des dépendances partielles
S’il existe une dépendance partielle Y → A, où X est une clé minimale et Y un sous-‐-ensemble
de X, alors chaque n-‐-uplet utilisé pour associer une valeur X aux valeurs de A sera répété pour
les valeurs de Y (d’où redondance des informations).
La condition de la 3NF élimine cette possibilité, évitant ainsi les mises à jour incorrectes et la
redondance.
2. élimination des dépendances transitives
S’il existe une dépendance transitive X → Y → A, alors on ne peut associer une valeur Y à une
valeur X que s’il existe une valeur A associée à une valeur Y . Cela conduit à des problèmes
d’insertion et de suppression.
DÉFINITION
On considère les définitions suivantes:
R: un schéma de relations,
F: un ensemble de DF sur R,
X: un sous-‐-ensemble de R,
A: un attribut.
10On rappelle que A est un attribut clé ssi il fait partie d’une clé minimale de R et que dans le cas con-‐-
traire, A est appelé un attribut non clé.
La relation R est dite en troisième forme normale (3NF) ssi lorsque X → A est dans F+ et A n’est pas
dans X, soit X est une clé primaire, soit A est un attribut clé.
Il existe deux cas dans lesquels X → A ne respecte pas la 3NF:
Cas 1: X est un sous-‐-ensemble d’une clé minimale. X → A est une dépendance partielle.
Cas 2: X n’est pas un sous-‐-ensemble de toutes les clés minimales. X → A est une dépendance
transitive. Elle crée une chaîne non triviale de DF Z → X → A pour une clé minimale Z.
Autrement dit, une relation est dite en 3NF ssi:
• elle est en 2NF,
• il n’existe pas de dépendance entre attributs non clé.
EXEMPLE 1
R=ABCD
F = {AB → C,B → D,BC → A}
AB et BC sont des clés minimales et ce sont les seules. A, B et C sont des attributs clés. D est
un attribut non clé.
EXEMPLE 2
R=VRC R(ville, rue, code)
F = {VR → C,C → V}
R est en 3NF.
EXEMPLE 3
R=SAIP
F = {SI → P ,S → A}
SI est la seule clé, et A est un attribut non clé.
S → A ne respecte pas la 3NF, étant donné que S n’est pas une clé primaire. De plus, S → A est
une dépendance partielle.
On remarque dans cet exemple que la dépendance S → A est dans F. Cependant, en général,
les dépendances non conformes à la forme normale étudiée sont dans F+ plutôt que dans F.
1.4.4 Forme normale de Boyce-‐-Codd (BCNF)
OBJECTIFS DE LA BCNF
1. élimination des dépendances partielles,
2. élimination des dépendances transitives,
3. élimination des anomalies non prises en compte par la 3NF.
DÉFINITION
On considère les définitions suivantes:
R: un schéma de relations,
F: un ensemble de DF sur R,
X: un sous-‐-ensemble de R,
A: un attribut.
R est en BCNF ssi lorsque X → A appartient à F+ et que A n’est pas dans X, alors X est une clé
de R.
Une relation en 3NF qui ne possède qu’un seule clé minimale est en BCNF.
EXEMPLE 1
M=NAC MEMBRE(nom,adresse,cotisation)
F = {n → a, n → c}
M est en BCNF.
11EXEMPLE 2
R=VRC R(ville,rue,code)
F = {VR → C,C → V}
R est en 3NF mais pas en BCNF. Dans R, on ne peut pas stocker la ville correspondante à un
code à moins de connaître une rue associée à ce code (anomalie d’insertion). En effet, C → V
est vraie et V n’appartient pas à C, alors que C ne contient aucune des clés minimales de R.
1.5 Dépendances fonctionnelles et conception de schémas
Nous l’avons déjà abordé au paragraphe 1.2.1, il existe deux méthodes pour concevoir un schéma de
bases de données qui soit en 3NF: la méthode dite synthétique, et la méthode par décomposition.
1.5.1 La méthode synthétique
L’algorithme dit de synthèse permet dʹobtenir une décomposition 3NF qui préserve les DF. Il est basé
sur le calcul de la couverture minimale (ou irredondante) dʹun ensemble de DF. Le point de départ de
cette méthode est la connaissance des attributs et d’un ensemble de dépendances fonctionnelles. On
construit le graphe des DF dans lequel chaque attribut constitue un noeud, et chaque DF est représen-‐-
tée par un arc. L’algorithme de synthèse va travailler sur ce graphe et construire un ensemble de rela-‐-
tions en 3NF.
ALGORITHME DE SYNTHÈSE
Pour obtenir un schéma de relations en 3NF, on applique l’algorithme suivant:
1. on construit une couverture minimale à partir de l’ensemble F des DF,
2. on en déduit les relations en 3NF en regroupant dans une même relation tous les attributs ayant
la même partie gauche dans le graphe des DF,
3. si aucune des relations obtenues à l’étape précédente ne contient pas (ou ne permet pas d’obte-‐-
nir) la clé de la relation initiale, on ajoute une relation composée uniquement des attributs de la
clé.
EXEMPLE
Soit la relation GESPROD (numEmp, nomEmp, numProj, budProj, emploi, taux, nbhr) qui décrit la
gestion de projet dans une entreprise. Les attributs sont les suivants: le numéro d’employé, le nom de
l’employé, le numéro du projet, le budget du projet, l’emploi occupé par l’employé, le taux de rému-‐-
nération de l’employé, et le nombre d’heures de travail de l’employé sur un projet donné. La seule clé
minimale de la relation est constituée des attributs {numEmp, numProj}. L’ensemble F des DF est le
suivant:
numEmp → nomEmp
numEmp → emploi
emploi → taux
numEmp → taux
numProj → budProj
numEmp,numProj → nbHr
Pour obtenir une décomposition de GESPROD muni de F en un ensemble de relations en 3NF, on ap-‐-
plique lʹalgorithme suivant:
1. construction de la couverture minimale: on élimine les dépendances transitives:
numEmp → taux est une DF transitive car numEmp → emploi et emploi → taux.
2. déduction des relations en 3NF en regroupant dans une même relation tous les attributs ayant
même partie gauche dans F.
EMPLOYÉ (numEmp, nomEmp, emploi)
PROJET (numProj, budProj)
RÉMUNÉRATION (emploi, taux)
OCCUPE (numEmp, numProj, nbHr)
3. on vérifie que la clé est présente dans au moins une relation. Dans notre exemple, la relation
OCCUPE possède la clé de la relation initiale.
121.5.2 La méthode par décomposition
Une autre manière de concevoir un schéma relationnel en troisième forme normale est de partir du
schéma complet (ensemble de tous les attributs) et de décomposer cette « grosse » relation (appelée
également relation universelle) en respectant les dépendances fonctionnelles. Cette approche est appelée
approche par décomposition. Le problème est dʹordonner lʹordre des décompositions de manière à
obtenir un schéma en 3ème forme normale. En effet, chaque relation produite ne conserve qu’un cer-‐-
tain nombre de DF (celles définies sur ses attributs propres) et nʹest donc pas forcément en 3ème forme
normale. De plus, lʹensemble des DF du schéma complet nʹest pas forcément préservé.
ALGORITHME DE DÉCOMPOSITION
entrée: un schéma relationnel (ensemble dʹattributs) et un ensemble E de DF entre ses attri-‐-
buts
sortie: une ou plusieurs relations en 3NF dont la jointure redonne la relation initiale (par con-‐-
tre des DF de E ont pu être perdues)
principe: lʹalgorithme peut se voir comme la construction dʹun arbre binaire. La racine de cet
arbre est la relation à décomposer. Lʹarbre se construit récursivement de la manière suivante:
1. on choisit une DF dfi dans lʹensemble E des DF,
2. le fils gauche du noeud racine est une relation composé de tous les attributs de dfi,
3. dfi est retirée de lʹensemble E,
4. le fils droit du noeud racine est une relation composée de tous les attributs de la racine ex-‐-
cepté ceux présents en partie droite de dfi.
Problèmes: la solution dépend du choix des DF selon lesquelles on choisit de décomposer et il ne pré-‐-
serve pas nécessairement les DF.
On sait néanmoins que toute relation admet une décomposition en 3NF qui préserve les DF.
EXEMPLE
Soit la relation universelle associée à la gestion de production définie au paragraphe 1.5.1:
GESPROD (numEmp, nomEmp, numProj, budProj, emploi, taux, nbhr)
On constate quʹelle n
ʹest pas en 2NF car
numEmp → nomEmp, taux, emploi
numProj → budProj
Ceci conduit à une décomposition de la relation GESPROD en trois relations en 2NF:
PROJET (numProj, budProj)
OCCUPE (numEmp, numProj, nbHr)
EMPREM (numEmp, nomEmp, emploi, taux)
On constate que la relation EMPREM n
ʹest pas en 3NF car
emploi → taux (un attribut non clé dépend fonctionnellement dʹun autre attribut non clé)
On décompose la relation EMPREM en deux relations en 3NF
EMPLOYÉ (numEmp, nomEmp, emploi)
RÉMUNÉRATION (emploi, taux)
On obtient finalement quatre relations en 3NF
PROJET (numProj, budProj)
OCCUPE (numEmp, numProj, nbHr)
RÉMUNÉRATION (emploi, taux)
EMPLOYÉ (numEmp, nomEmp, emploi)
EXEMPLE SUR LES FORMES NORMALES
Soit le schéma R = (P , H, N, Y , T), et F = {P → T | P , H → Y | H, N → P | H, Y → N}.
• ensemble des DFE engendrées:
H, N → T
P, H →N
H,N → Y
13H, Y → P
P, H →T
H, Y → T
• on a donc trois clés potentielles (H, N | P , H | H, Y):
H, N → P , T, Y
P , H → T, Y , N
H, Y → N, P , T
• les attributs clés sont donc: H, N, P , Y , et un attribut non clé est T.
• par définition le schéma est en 1ère forme normale. Est il en 2NF ?
Non, car P , H → T n
’est pas une DFE (on a P → T), R est donc en 1NF.
• application de l’algorithme de décomposition:
R(P, H, N, Y, T)
P ! T
R1(P, T) Clé P (3NF) R2(P, H, N, Y)
Clés H,N ou P,H ou H,Y (3NF) R =
R1 * R2 (pas de perte des DFs)
14CHAPITRE 2: SÉCURITÉ DE FONCTIONNEMENT
1. Les transactions
2. La tolérance aux pannes
3. La gestion de la concurrence
4. Le verrouillage sous Oracle
5. JDBC et les transactions
2.1 Les transactions
2.1.1 Définition
L’objectif de ce chapitre est d’étudier les mécanismes que fournit un SGBD pour s’assurer que les don-‐-
nées demeurent dans un état cohérent, c’est-‐-à-‐-dire qu’elles ne sont pas mises en cause par un pro-‐-
blème logiciel ou matériel, ou par le fait que plusieurs utilisateurs manipulent les données simultané-‐-
ment. En effet, les SGBD sont utilisés par plusieurs utilisateurs simultanément, à la fois pour les requê-‐-
tes ou pour des modifications sur la base de données.
Par exemple, on suppose que deux personnes souhaitent retirer 100€ d’un même compte. Un SGBD
doit s’assurer qu’aucun des deux retraits ne soit perdu. Par comparaison avec un système d’exploita-‐-
tion, deux personnes peuvent très bien éditer le même fichier, mais c’est le dernier qui écrit qui voit
ses modifications conservées. Ce comportement n’est pas imaginable dans le contexte des bases de
données.
Pour résoudre ce problème, on a introduit le concept de transaction; Une transaction est un pro-‐-
gramme qui forme une unité logique de traitement. Elle est constituée d’une ou plusieurs opérations
d’accès aux objets de la base de données (insertion, suppression, modification ou lecture). Enfin, une
transaction fait passer la base d’un état cohérent E1 à un état cohérent E2. En particulier:
• une transaction doit commencer à partir d’un état cohérent de la base,
• pendant la transaction, la base peut éventuellement être dans un état incohérent,
• lorsque la transaction se termine avec succès, la base doit être dans un état cohérent,
• lorsqu’une transaction a été validée, les modifications sur la base sont persistantes, même en cas de
problèmes logiciels ou matériels,
• plusieurs transactions peuvent s’exécuter en parallèle.
On distingue deux problèmes à prendre en compte:
• la tolérance aux pannes: il faut restaurer la base dans l’état où elle se trouvait avant l’incident. Les mé-‐-
canismes utilisés sont les transactions, la tenue d’un journal, la reprise après panne.
• l'ʹexécution concurrente de plusieurs transactions: il faut veiller à ce que l’action simultanée de plusieurs
utilisateurs sur les mêmes données ne conduise pas à une incohérence de ces données. Les méca-‐-
nismes utilisés sont la gestion des accès concurrents, les transactions, le verrouillage et la gestion de
l’interblocage.
2.1.2 Propriétés ACID
Un SGBD supporte ce que l’on appelle des transactions ACID. Les propriétés ACID sont:
• atomicité : lors de l’exécution d’une transaction, soit toutes ses actions sont exécutées, soit aucune ne
l’est,
• cohérence : après une transaction, la base se trouve dans un état cohérent,
• isolation : il n’y a pas d’incohérence liée à la concurrence d’accès,
• durabilité : les effets d’une transaction correctement exécutée survivent à une panne ultérieure.
V oyons sur un exemple ce que cela signifie. On suppose une transaction qui effectue un transfert d’ar-‐-
gent (100€) d’un compte A vers un compte B:
1. lire(A) 4. lire(B)
2. A:= A –100 5. B := B + 100
3. écrire(A) 6. écrire(B)
15La propriété d’atomicité spécifie que si la transaction échoue après l’étape 3 et avant l’étape 6, le sys-‐-
tème doit s’assurer qu’aucune mise à jour n’aura été effectuée, sous peine de voir une incohérence
entre la balance des deux comptes.
La propriété de cohérence spécifie que la somme des soldes de A et B est inchangée après l’exécution
de la transaction.
La propriété d’isolation spécifie que si une autre transaction essaie d’accéder à la base entre les étapes
3 et 6, elle ne verra pas les modifications faites aux étapes 1 à 3. L’isolation peut être assurée de ma-‐-
nière triviale en exécutant les transactions en séquence (de manière sérialisable). Cependant, nous ver-‐-
rons que permettre l’exécution concurrente des plusieurs transactions apporte des avantages, à condi-‐-
tion de ne pas avoir d’interférences entre les transactions simultanées.
Enfin, la propriété de durabilité spécifie que lorsque l’utilisateur a validé la transaction, les mises à
jour doivent persister, quelques soient les défaillances logicielles ou matérielles qui pourraient surve-‐-
nir.
2.1.3 États d’une transaction
Une transaction est une unité atomique (au sens indivisible) de travail qui doit être soit totalement
terminée soit pas du tout (atomicité). Le système doit donc savoir quand la transaction commence, se
termine, est validée ou est abandonnée. Pour cela, une transaction peut se trouver dans plusieurs
états:
• active: l’état initial. La transaction entre dans cet état immédiatement après son début d’exécution, et
elle y reste durant son exécution,
• partiellement validée: lorsque la dernière instruction de la transaction a été exécutée,
• échouée: dès que l’exécution ne peut plus continuer normalement,
• annulée: après que la transaction a été annulée, et que la base ait été restaurée dans l’état cohérent
d’avant le début de la transaction. Il existe alors deux options après qu’une transaction ait été annu-‐-
lée, soit on redémarre la transaction, soit on tue la transaction.
• validée: après une exécution totalement terminée.
En fait, SQL supporte les transactions, souvent de manière invisible. En effet, chaque commande effec-‐-
tuée dans l’outil d’interrogation est une transaction. Ainsi, chaque fois que vous faites une (ou plu-‐-
sieurs) requête(s) dans SQL/Plus, vous débutez sans le savoir une transaction.
2.1.4 Commit, rollback
L’instruction SQL COMMIT permet de valider une transaction. Cette instruction peut être explicite dans
une transaction où, comme c’est souvent le cas, implicite et exécutée à la fin de la transaction par le
SGBD. Une fois l’instruction COMMIT exécutée, les modifications faites sont permanentes et la transac-‐-
tion s’achève.
L’instruction ROLLBACK permet également d’achever la transaction, mais en l’annulant. Il n’y alors au-‐-
cun effet sur la base, et le SGBD doit alors revenir à l’état précédent le début de la transaction puisque
c’est le dernier point garanti de cohérence de la base.
2.1.5 Exemple
V oyons sur un exemple l’interaction entre deux transactions. On suppose la relation BarÀBière(bar,
bière, prix), et on suppose que le bar Jo vend de la Chimay (3,00€) et de la Leffe (2,50€). Paul interroge
la base, et la relation BarÀBière pour connaître le prix minimum et le prix maximum du bar Jo. Entre-‐-
temps, Jo décide de cesser de vendre de la Chimay et de la Leffe, pour ne plus vendre que de la Kwak
à 3,50€.
Paul exécute les deux instructions SQL suivantes afin de connaître les prix minimum et maximum:
(max) SELECT MAX(prix) FROM BarÀBière
WHERE bar = ‘Jo’;
(min) SELECT MIN(prix) FROM BarÀBière
WHERE bar = ‘Jo’;
16Pendant ce temps, Jo exécute les instructions suivantes:
(del) DELETE FROM BarÀBière
WHERE bar = ‘Jo’;
(ins) INSERT INTO BarÀBière
VALUES(‘Jo’, ‘Kwak’, 3.50);
On a des instructions SQL qui peuvent être entrelacées, avec les contraintes suivantes: (max) doit être
exécuté avant (min), et (del) doit être exécuté avant (ins). Que se passe-‐-t-‐-il lorsque Jo et Paul mettent à
jour la base ? Si les instructions ont lieu dans l’ordre suivant: (max)(del)(ins)(min), on obtient:
Prix 2,50 | 3,00 2,50 | 3,00 3,50
Instruction (max) (del) (ins) (min)
Résultat 3,00 3,50
Ainsi, Paul voit que MAX < MIN !
Comment peut-‐-on résoudre le problème avec les transactions ? Si l’on regroupe les instructions
(max)(min) de Paul dans une seule transaction, alors il n’y aura plus de problèmes. En effet, soit la
transaction s’exécutera avant les modifications de Jo, et Paul verra alors les anciens prix, soit la trans-‐-
action s’exécute après la modification, et il n’y aura pas de problème. La transaction permet donc aux
deux instructions (max)(min) de s’exécuter sur les mêmes données.
Il existe cependant encore une possibilité de comportement étrange. Supposons que Jo exécute sa mo-‐-
dification de prix, mais qu’au dernier moment, il change d’avis et exécute un ROLLBACK. Si Paul
exécute sa transaction après l’instruction (ins), mais avant l’annulation, il va voir une valeur 3,50 qui
n’existe pas dans la base. Pour résoudre ce problème, on va donc exécuter les instructions de Jo dans
une transaction. Ainsi, les effets de (del)(ins) dans une transaction ne pourront être vus par d’autres
transactions que lorsque la transaction aura été validée. Si la transaction venait à être annulée, ses ef-‐-
fets ne seraient pas vus par les autres transactions.
2.1.6 Gestion des transactions dans Oracle
Une transaction débute avec la première instruction SQL exécutable et se termine lors de l’exécution
d’un commit ou d’un rollback, lors de la déconnexion de l’utilisateur (commit), ou lors d’un arrêt
anormal du processus utilisateur (rollback).
Les mises à jour faites par une transaction ne sont visibles pour les autres utilisateurs qu’après la vali-‐-
dation de la transaction (tant qu'ʹune transaction n'ʹest pas validée, les autres utilisateurs accèdent aux
anciennes valeurs des données modifiées).
2.2 La tolérance aux pannes
2.2.1 Journal
Il existe plusieurs types d’incidents qui peuvent survenir sur une base de données :
• échec d’une transaction: une erreur logique dans le programme l'ʹempêche de se poursuivre norma-‐-
lement (erreur lors d'ʹune insertion, suppression ou mise à jour), ou une erreur système arrête le dé-‐-
roulement normal du programme (verrouillage, saturation, processus tué),
• crash système: il entraîne la perte des données en mémoire centrale,
• panne disque: elle provoque la perte physique des données.
Les algorithmes de récupération (recovery) sont des techniques qui permettent aux SGBD d’assurer la
cohérence, l’atomicité et la durabilité malgré les incidents qui peuvent survenir. En général, les algo-‐-
rithmes de récupération possèdent deux parties: la première prend en charge les actions qui ont lieu
lors du déroulement normal de la transaction afin d’avoir assez d’informations pour permettre la ré-‐-
cupération en cas de problème, et la deuxième qui prend en charge les actions à effectuer après un
problème afin de pouvoir récupérer la base dans un état cohérent.
17Pour assurer la reprise sur panne, les SGBD et Oracle en particulier utilisent la notion de journal. Un
journal est un fichier texte dans lequel le SGBD inscrit, dans l’ordre d’exécution, toutes les actions de
mise à jour qu’il effectue. Ainsi, le journal est une séquence d’enregistrements qui mémorise les mises
à jour faites sur la base. Lorsqu’une transaction Ti démarre, elle s’enregistre dans le journal sous la
forme <début transaction, Ti >. Avant que la transaction Ti exécute une instruction écrire(X), un enregis-‐-
trement <Ti, X, V1, V2> est écrit dans le journal (V1 est la valeur de X avant l’écriture, et V2 est la valeur
de X après l’écriture). Lorsque la transaction Ti a lu une valeur, un enregistrement <lecture, Ti, X> est
écrit dans le journal. Enfin, <valider, Ti> ou <annuler, Ti> sont écrits dans le journal suivant que la
transaction a été validée ou annulée.
En Oracle, la gestion des transactions utilise deux fichiers :
• un fichier journal redo log: il enregistre toutes les modifications effectuées (insert, update, delete)
dans les tables de la base par chaque transaction.
• un fichier rollback segment: il enregistre les anciennes valeurs des lignes des tables modifiées par
une transaction.
Le système affecte à chaque transaction un numéro chronologique (SCN – System Control Number) qui
permet de l’identifier de manière unique. Toute opération modifiant une donnée de la base est enregis-‐-
trée dans le fichier rollback segment et dans le fichier journal redo log avant mise à jour de la base. Le
journal redo log est chronologique.
Lors du commit d'ʹune transaction, il faut :
• enregistrer le commit de la transaction dans les fichiers redo log et rollback segment,
• débloquer les lignes des tables verrouillées par la transaction.
Lors du rollback d'ʹune transaction, il faut :
• redonner les anciennes valeurs à toutes les lignes des tables modifiées par la transaction (à partir des
rollback segment),
• débloquer les lignes des tables verrouillées par la transaction.
2.2.2 Reprise après incident
Elle est disponible uniquement pour les incidents sans perte de données sur disque. L’objectif est de
restaurer la base dans un état cohérent telle qu'ʹelle se trouvait juste avant la panne. Le mécanisme de
reprise est le suivant:
• appliquer toutes les modifications enregistrées dans le fichier redo log à la base de données (roll-‐-
forward)
• pour toutes les transactions sans commit, on remet les lignes des tables concernées aux anciennes
valeurs (rollback). Ceci est fait à partir des rollback segment.
Après un incident, on ne traite que les modifications effectuées après le point de reprise (ou point de
contrôle). Un point de reprise consiste à 1) écrire les buffers du fichier redo log sur disque, 2) écrire les
buffers de la base de données sur disque, 3) écrire un article point de reprise dans le fichier redo log.
On peut préciser un point de reprise en utilisant la commande SAVEPOINT pdr ;. Par la suite, on
pourra revenir à ce point en utilisant la commande ROLLBACK TO pdr; qui permet de retrouver l’envi-‐-
ronnement tel qu’il était lors de la déclaration du point de reprise.
SQL Résultats
SA VEPOINT a; Premier point de reprise de la transaction
DELETE …; Modification de la base
SA VEPOINT b; Deuxième point de reprise de la transaction
INSERT INTO…; Modification de la base
SA VEPOINT c; Troisième point de reprise de la transaction
UPDATE …; Modification de la base
18ROLLBACK TO c; L’ordre UPDATE est annulé, le point C reste défini
ROLLBACK TO b; L’ordre INSERT est annulé, le point C est perdu, le point B reste défini
ROLLBACK TO c; ORA-‐-01086 error; savepoint C no longer defined
INSERT TO…; Modification de la base
COMMIT; Valide toutes les actions effectuées par le DELETE (première modification)
et le INSERT (dernière modification). Toutes les autres modifications ont été
annulées avant le COMMIT. Le point A n’est plus actif.
EXEMPLE: traitement des transactions
La mise en œuvre du mécanisme de reprise s’effectue comme ceci. Soient les 5 transactions suivantes
au moment d'ʹun incident :
T1
T2
T3
T4
T5
Point de reprise Incident
• T1 est achevée lors du point de reprise, elle n'ʹest pas traitée.
• T2 et T4 sont validées (commit) lorsque survient l'ʹincident: on applique toutes les modifications en-‐-
registrées dans le fichier redo log à la base de données (rollforward); pour T2, on repart du point de
reprise.
• T3 et T5 ne sont pas validées (pas de commit) lorsque survient l'ʹincident, on remet les lignes des
tables concernées aux anciennes valeurs (rollback).
2.3 La gestion de la concurrence
La gestion des accès concurrents aux données permet d’éviter que la mise à jour simultanée des mê-‐-
mes données par plusieurs utilisateurs n’introduise pas des incohérences dans la base de données. On
dit que deux transactions sont concurrentes si elles accèdent simultanément aux mêmes données.
2.3.1 Accès concurrents et incohérence des données
V oici quelques problèmes classiques qui peuvent survenir avec des transactions concurrentes.
La perte de mise à jour
Il y a perte de mise à jour quand une transaction T2 vient écraser une écriture effectuée par T1.
Temps t1
t2
t3
t4
t5
t6
t7
Transaction T1 État de la base Transaction T2
lire(A)
…
A = A + 10
…
…
écrire(A)
…
A = 10
A = 20
A = 60
…
lire(A)
…
…
A = A+50
…
écrire(A)
Après une exécution séquentielle de T1 et T2 ou T2 et T1, on obtient A=70. Si les transactions sont exé-‐-
cutées de manière concurrentes, on obtient alors A=60. On a donc perdu la première mise à jour.
19Les lectures impropres
Supposons une transaction T2 qui lit une donnée A modifiée par T1. La transaction T1 est annulée et
les modifications effectuées par cette transaction sont défaites. La valeur lue et traitée par T2 est alors
incorrecte.
Temps Transaction T1 État de la base Transaction T2
t1
t2
t3
t4
t5
lire(A)
A = A +20
écrire(A)
…
rollback
A = 10
A = 30
A = 10
…
…
…
lire(A)
…
Les lectures non reproductibles
La transaction T2 lit la même donnée A à deux instants différents et n'ʹobtient pas la même valeur. En-‐-
tre les deux lectures, une autre transaction a modifié la valeur de A.
Temps Transaction T1 État de la base Transaction T2
t1
t2
t3
t4
t5
A = 10
…
lire(A)
A = A + 10
écrire(A)
commit
A = 20
lire(A)
…
…
…
lire(A)
2.3.2 Le mécanisme de verrouillage
Les principales techniques mises en œuvre pour le contrôle de l’exécution concurrente des transac-‐-
tions reposent sur le concept de verrouillage des données. Un verrou est une variable associée à une
donnée qui décrit l’état de la donnée, compte tenu des opérations qui peuvent lui être appliquées.
Ainsi, avant d'ʹaccéder à une donnée pour modifier sa valeur, la transaction T1 doit la verrouiller pour
éviter son accès par une autre transaction. Une fois terminée, la transaction T1 libère alors les données
verrouillées pour les rendre disponibles à d'ʹautres transactions.
Nous reprenons l'ʹexemple du transfert d'ʹune somme d'ʹargent entre deux comptes: T1 fait un transfert
de c1 vers c2, T2 de c1 vers c3.
T1 T2
lock(c1)
read(c1) for update
c1:=c1-‐-m1 T2 attend la libération de c1
écrire(c1) (demande accès pour update de c1)
lock(c2) "ʺ
read(c2) for update "ʺ
c2:=c2+m1 "ʺ
écrire(c2) "ʺ
unlock(c1,c2) lock(c1)
read(c1) for update
c1:=c1-‐-m2
écrire(c1)
lock(c3)
read(c3) for update
c3:=c3+m2
écrire(c3)
20unlock(c1,c3)
Le verrouillage tel qu'ʹil est appliqué ci-‐-dessus permet d'ʹéliminer les pertes de mise à jour et les lectu-‐-
res impropres. Par contre, il ne permet pas d'ʹéliminer les lectures non reproductibles.
Les verrous classiques sont les verrous binaires, c’est-‐-à-‐-dire des verrous qui peuvent avoir deux va-‐-
leurs distinctes: verrouillé ou non verrouillé (1 ou 0). Un verrou est associé à chaque élément X. Si la
valeur du verrou sur X est 0, alors il est possible d’accéder à l’élément. Le verrouillage binaire utilise
deux opérations: verrouillerÉlément et déverrouillerÉlément. Une transaction demande l’accès à
un élément X en exécutant pour commencer l’opération verrouillerÉlément(X). Si le verrou est à 1,
la transaction doit attendre. Si le verrou est à 0, le verrou est mis à 1, et la transaction est autorisée à
accéder à l’élément X. Lorsque la transaction n’a plus besoin d’utiliser l’élément, elle exécute une opé-‐-
ration déverrouillerÉlément(X) qui positionne le verrou à 0 afin que les autres transactions puis-‐-
sent accéder à X. Un verrou binaire applique donc une exclusion mutuelle sur une donnée.
On se rend compte rapidement que les verrous binaires sont trop restrictifs pour les bases de données,
car certaines transactions ne veulent que lire certaines données. On distingue donc deux types de ver-‐-
rous, les verrous partagés, qui permettent à plusieurs transactions de lire une donnée verrouillée par
une transaction, et les verrous exclusifs, qui permettent à la transaction qui a posé le verrou d’effec-‐-
tuer une opération d’écriture.
2.3.3 Le risque d'ʹinterblocage
Un interblocage (ou verrou mortel) survient lorsque chaque transaction T d’un ensemble de n (n ≥ 2)
transactions attend une donnée verrouillée par une autre transaction T’ de l’ensemble. Autrement dit,
T1 attend une donnée verrouillée par T2, et T2 attend une donnée verrouillée par T1.
EXEMPLE : transfert entre deux comptes.
T1 transfère une somme m d’un compte c1 vers un compte c2, et T2 transfère une somme n de c2 vers
c1. L'ʹexécution simultanée des deux transactions conduit à la situation suivante :
T1 T2
lock(c1)
read(c1)
c1:=c1+m lock(c2)
écrire(c1) read(c2)
c2:=c2+n
T1 attend libération de c2 "ʺ écrire(c2)
T2 attend libération de c1
"ʺ "ʺ
"ʺ "ʺ
Les données sont verrouillées en fonction des demandes de mises à jour, mais ne sont libérées qu’en
fin de transaction
2.3.4 Résolution de l'ʹinterblocage (deadlock)
Une approche pratique de la gestion des interblocages repose sur la détection de ceux-‐-ci: le système
vérifie s’il y a une situation d’interblocage. Un procédé pour détecter une situation d’interblocage con-‐-
siste pour le système à construire et à maintenir un graphe d’attente des ressources (wait-‐-for graph).
Dans ce graphe, un nœud est créé pour chaque transaction en cours d’exécution. Chaque fois qu’une
transaction Ti attend de pouvoir verrouiller une donnée X verrouillé par une transaction Tj, un arc est
créé entre les deux transactions. Il y a situation d’interblocage si et seulement si il existe un cycle dans
le graphe. Il se pose alors le problème de savoir quand le système doit vérifier la présence d’un inter-‐-
blocage (nombre de transactions, durée d’attente de plusieurs transactions,…). Si le système détecte
l’interblocage, il tue une (ou plusieurs) des transactions impliquées. Il existe différentes solutions pour
le choix de la transaction à tuer : la plus récente, celle qui a fait le moins de mises à jour … D’autres
solutions plus élaborées peuvent être utilisées, mais ne seront pas traitées dans le cadre de ce cours.
Une autre possibilité pour gérer les interblocages consiste à employer des mises hors délais (timeouts).
21Cette méthode est pratique en raison du peu d’activité qu’elle implique sur le système. Si une transac-‐-
tion attend plus longtemps que la durée spécifiée pour la mise hors délai, le système suppose qu’elle
est bloquée et il tue cette transactions, qu’il y ait ou non interblocage.
La détection des interblocages
Pour détecter les interblocages, on construit le graphe d’attente des ressources :
X
T1 T2
Y
X, Y ,… représentent des éléments des tables de la base. T1, T2 …. identifient des transactions. Un arc
orienté étiqueté X ou Y entre Ti et Tj signifie que la transaction Ti attend la libération de X ou Y . L'ʹin-‐-
terblocage se traduit par un circuit dans le graphe d’attente des ressources, comme dans la figure ci-‐-
dessus.
RAPPEL: l'ʹinterblocage peut mettre en jeu n (n≥2) transactions.
X T2
T1
Y
Z
T3
2.3.5 Niveaux d'ʹisolation
SQL définit quatre niveaux d’isolation qui permettent de choisir quelles sont les types d’interactions
autorisées pour les transactions qui s’exécutent simultanément (concurrentes). Ainsi, dans une trans-‐-
action, on peut utiliser l’instruction suivante:
SET TRANSACTION ISOLATION LEVEL X
où X = SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED
T ransactions de niveau serializable
Si on reprend l’exemple de la section 4.1.5, et si on suppose que Paul = (max)(min) et Jo = (del)(ins)
sont des transactions, et si Paul utilise le niveau d’isolation SERIALIZABLE, alors il verra la base dans
l’état soit avant les modifications de Jo, soit après, mais pas entre les deux opérations de la transaction
de Jo.
Le niveau d'ʹisolation est un choix qui affecte uniquement la vue de la base de la transaction que le
spécifie. Si on reprend notre exemple (cf section 4.1.5), si Jo choisit le niveau SERIALIZABLE, mais pas
Paul, alors Paul peut éventuellement ne voir aucun prix si la requête est exécutée entre (del) et (ins).
T ransactions de niveau repeatable read
Seules les données validées peuvent être lues, ce qui implique que les lectures répétées dans une
même transaction retourne les mêmes valeurs (pas de phénomène de lectures non reproductibles).
Cependant, une transaction pourra voir apparaître au cours des lectures répétées de nouveaux n-‐-u-‐-
plets (ou des n-‐-uplets qui ont disparu).
Sur notre exemple, si Paul a choisi le niveau REPEATABLE READ, et que l’ordre d’exécution est
(max)(del)(ins)(min), alors (max) verra les prix 2,50 et 3,00, et (min) verra 3,50, mais également 2,50 et
3,00 car ils ont été vus par la lecture précédente de (max) dans la transaction.
T ransactions de niveau read committed
Seules les données validées peuvent être lues, mais des lectures successives peuvent renvoyer des va-‐-
leurs (validées) différentes. Cela permet de voir les modifications apportées par d’autres transactions.
22Sur notre exemple, si Paul a choisi le niveau READ COMMITTED, alors il peut voir les valeurs validées,
mais pas nécessairement les mêmes à chaque requête. Ainsi, avec READ COMMITTED, l’entrelacement
(max)(del)(ins)(min) est autorisé, aussi longtemps que Jo valide (mais Paul peut voir MAX < MIN).
T ransactions de niveau read uncommitted
Une transaction qui s’exécute en niveau d’isolation READ UNCOMMITTED peut voir des données dans la
base qui ne sont pas validées par une autre transaction (et qui ne le seront peut-‐-être jamais).
Sur notre exemple, si Paul a choisi le niveau READ UNCOMMITTED, il pourra voir le prix 3,50, même si Jo
abandonne la transaction.
2.3.6 V errouillage et niveaux de granularité
Les performances du contrôle de la concurrence est affectée par la taille des éléments à verrouiller. Par
exemple, dans une base de données, on a la valeur d’un attribut d’un n-‐-uplet, un n-‐-uplet, une table, ou
toute la base. Selon que l’on pose un verrou sur un élément particulier, on peut bloquer ou non plu-‐-
sieurs transactions. En particulier, il faut remarquer que plus la taille des éléments à verrouiller est
importante, plus le degré de concurrence autorisé est faible. Par exemple, si une transaction veut blo-‐-
quer toute une table (et si elle ne souhaite accéder qu’à un n-‐-uplet particulier), toutes les autres trans-‐-
actions seront mises en attente alors qu’il n’est peut être pas nécessaire de bloquer toute la table. In-‐-
versement, si on verrouille des éléments de taille plus petite, il peut y avoir beaucoup d’éléments à
verrouiller, et donc le gestionnaire de verrouillage devra gérer un plus grand nombre de verrous
(beaucoup d’opérations de verrouillage/déverrouillage). La nature des verrous à poser dépend donc
de la nature des transactions. Par exemple, si une transaction accède à un petit nombre d’enregistre-‐-
ments, il est préférable que la granularité soit l’enregistrement. Par contre, si une transaction accède à
de nombreux enregistrements d’une même table, alors la granularité qui semble la plus appropriée
semble être la table.
2.4 Le verrouillage sous Oracle
2.4.1 Principe
Oracle implante un verrouillage au niveau de la ligne, et utilise un mécanisme appelé Read consistency
(lecture cohérente). Grâce à ce mécanisme, les mises à jour et les lectures ne se bloquent pas mutuel-‐-
lement. Toutes les données retournées par un SELECT proviennent d’un seul point dans le temps. On
ne voit que les données validées au moment du SELECT. Pour les données non validées, on voit les
anciennes valeurs (grâce au Rollback segment). Les données modifiées par une autre transaction après
le début du SELECT ne sont pas vues.
Il existe une concurrence d’accès en mise à jour: la première transaction qui accède à une donnée posi-‐-
tionne un verrou sur les données accédées (n-‐-uplets ou tables), les autres transactions souhaitant accé-‐-
der les mêmes données seront mises en attente.
Ce mécanisme ne prend pas en compte les lectures non reproductibles. On peut, pour résoudre ce
problème, utiliser une transaction spéciale appelée une transaction à lecture seulement (Read Only
T ransaction). Cette transaction conserve, lorsqu'ʹelle démarre, l’état de la base et travaille ensuite uni-‐-
quement sur cet état, jusqu'ʹà la fin de la transaction. Une telle transaction ne doit comporter que des
lectures de la base, et les modifications des données de la base sont interdites. La syntaxe est:
SET TRANSACTION READ ONLY
instruction 1
…
instruction n
COMMIT
2.4.2 Niveaux d’isolation
En fixant le niveau d’isolation des transactions, on définit le mode de fonctionnement en parallèle des
différentes transactions qui s’exécutent au même moment. La commande suivante indique le niveau
d’isolation de la transaction qui vient de commencer :
23SET TRANSACTION ISOLATION LEVEL {SERIALIZABLE | READ COMMITTED}
Oracle permet deux niveaux d’isolation des transactions les unes par rapport aux autres :
• READ COMMITTED : c’est le mode par défaut des transactions d’Oracle. Il empêche les principaux
problèmes de concurrence mais pas les lectures non reproductibles. Tout d’abord, les modifications
effectuées par une transaction ne sont connues des autres transactions que lorsque la transaction a
été confirmée (COMMIT). Oracle gère automatiquement les accès concurrents de plusieurs transac-‐-
tions sur les mêmes n-‐-uplets de table. Si une transaction est en train de modifier des n-‐-uplets d’une
table, les autres transactions peuvent lire les données telles qu’elles étaient avant ces dernières mo-‐-
difications, mais les autres transactions sont bloquées automatiquement par Oracle si elles souhai-‐-
tent modifier ces mêmes lignes.
• SERIALIZABLE : si une transaction SERIALIZABLE essaie de modifier une donnée qui pourrait avoir
été modifiée par une autre transaction non validée au début de la transaction SERIALIZABLE, alors
l’ordre de modification échoue (résolution du problème de lecture non reproductibles). Ce mode est
coûteux puisqu’il limite le fonctionnement en parallèle des transactions (les transactions s’exécutent
concurremment comme si elles s’exécutaient les unes après les autres).
2.4.3 Différents niveau de verrouillage
V errouillage de niveau n-‐-uplet
Par défaut, Oracle met en œuvre un verrouillage de niveau n-‐-uplet, c’est-‐-à-‐-dire une stratégie de ver-‐-
rouillage au niveau des n-‐-uplets, chaque n-‐-uplet d’une table pouvant être verrouillé individuellement.
Les n-‐-uplets verrouillés peuvent alors être mis à jour uniquement par la transaction qui les a ver-‐-
rouillés. Tous les autres n-‐-uplets de la table peuvent être mis à jour par d’autres transactions. De plus,
les autres transactions gardent également la possibilité de lire les n-‐-uplets, y compris ceux qui sont mis
à jour. Pour ces derniers, les transactions ont accès à l’ancienne valeur (grâce au rollback segment) jus-‐-
qu’à ce que la transaction soit validée (lecture cohérente).
Lorsqu’une transaction pose un verrou sur un n-‐-uplet, Oracle effectue les opérations suivantes:
• Premièrement, un verrou DML (data manipulation language) est posé. Ce verrou évite que d’autres
transactions puissent mettre à jour (ou poser un verrou) sur le n-‐-uplet. Ce verrou ne sera relâché que
lorsque la transaction qui a posé le verrou aura été validée ou annulée,
• Deuxièmement, un verrou DDL (data dictionary language) est posé sur la table afin d’éviter les modifi-‐-
cations structurelles de la table (suppression de la table, retrait ou ajout d’un attribut,…). Ce verrou
ne sera relâché que lorsque la transaction qui a posé le verrou aura été validée ou annulée.
V errouillage de niveau T able
Avec le verrouillage au niveau table, la table entière est verrouillée. Dès qu’une transaction a ver-‐-
rouillé une table, seule cette transaction peut mettre à jour (ou verrouiller) n’importe quel n-‐-uplet de la
table. Aucun des n-‐-uplets de la table ne peut être mis à jour par une autre transaction. Cependant, les
autres transactions peuvent malgré tout lire n’importe quel n-‐-uplet, y compris ceux qui sont mis à
jour.
Relâcher les verrous
Souvent, les utilisateurs pensent être seuls au monde. C’est précisément ce genre de comportement
qui crée les problèmes de blocage. Souvenez-‐-vous que poser un verrou (sur un n-‐-uplet ou sur une ta-‐-
ble) n’est pas une opération anodine, et que cela peut bloquer beaucoup d’autres transactions. C’est
pourquoi il faut veiller à verrouiller de manière approprié, c’est-‐-à-‐-dire qu’il faut protéger uniquement
la partie de votre transaction qui est critique (mise à jour, calcul d’une moyenne, somme,…), et qu’il
faut également relâcher le verrou. Il faut donc être conscient que l’on relâche un verrou en validant
(COMMIT) ou en annulant (ROLLBACK) la transaction.
2.4.4 Les différents modes de verrouillage
Oracle propose deux modes de verrouillage:
24• le mode exclusif (X) qui empêche les ressources verrouillées d’être partagées. C’est le mode
privilé-‐- gié pour mettre à jour des données. La transaction qui pose un verrou exclusif la
première est la seule transaction qui peut modifier la table, et ce jusqu’à ce que le verrou soit
relâché.
• le mode partagé (S) permet à une ressource d’être partagée. Plusieurs transactions peuvent avoir
un verrou partagé et peuvent ainsi éviter qu’une autre transaction obtienne un verrou exclusif.
Oracle gère les types de verrous suivants: row share (RS), row exclusive (RX), share (S), share
row exclusive (SRX), et exclusive (X).
V errous exclusifs
SQL V errou
SELECT … FROM table… pas de verrou
INSERT INTO table… RX
UPDATE table… RX
DELETE FROM table… RX
LOCK TABLE table IN ROW EXCLUSIVE MODE RX
LOCK TABLE table IN SHARE ROW EXCLUSIVE MODE SRX
LOCK TABLE table IN EXCLUSIVE MODE X
V errous partagés
SQL V errou
SELECT … FROM table FOR UPDATE OF… RS
LOCK TABLE table IN ROW SHARE MODE RS
LOCK TABLE table IN SHARE MODE S
LOCK TABLE table IN SHARE ROW EXCLUSIVE MODE SRX
2.5 JDBC et les transactions
2.5.1 JDBC = Java DataBase Connectivity
JDBC est une API d’accès aux systèmes de gestion de base de données relationnelles qui permet
d’exécuter des requêtes SQL au sein d’un programme Java et de récupérer les résultats, ce qui
représente une alternative aux solutions propriétaires. C’est de plus une tentative de standardiser
l’accès aux bases de données car l’API est indépendante du SGBD choisi, pourvu que le pilote
JDBC existe pour ce SGBD, et qu’il implémente les classes et interfaces de l’API JDBC.
Pour effectuer un traitement avec une base de données, il faut :
1. charger un pilote en mémoire,
2. établir une connexion avec la base de données,
3. récupérer les informations relatives à la connexion,
4. exécuter des requêtes SQL et/ou des procédures stockées,
5. récupérer les informations renvoyées par la base de données (si nécessaire),
6. fermer la connexion.
Pour plus de détails, consulter le polycopié sur JDBC.
252.5.2 Gestion des transactions
L’instance de l’objet Connection fournit les méthodes pour :
Activer/désactiver la validation automatique de chaque requête passée (activé par défaut) :
public void setAutoCommit(boolean autoCommit) throws SQLException;
Valider manuellement la/les requête(s) passée(s) :
public void commit() throws SQLException;
Annuler les dernières modifications faites par la/les requête(s) passée(s) :
public void roolback() throws SQLException;
Exemple :
String sql1 = "UPDATE vendeur SET sal = 1215 WHERE sal < 1215";
String sql2 = "DELETE FROM vendeur WHERE sal < 1215";
try {
[Link](false);
Statement state = [Link]();
[Link](sql1);
Statement state2 = [Link]();
[Link](sql2);
[Link]();
...
} catch (Exception e) {
try{
[Link]();
} catch (SQLExection e) {
...
}
...
}
JDBC supporte le mode transactionnel qui consiste à valider tout ou une partie d’un ensemble
d’instructions. Nous avons déjà décrit à la section « Interface Connection » les méthodes qui
permettent à un programme Java de coder des transactions (setAutoCommit, commit et rollback).
Par défaut, chaque instruction SQL est validée (on parle d’autocommit). Lorsque ce mode est
désactivé, il faut gérer manuellement les transactions avec commit ou rollback.
Quand le mode autocommit est désactivé :
La déconnexion d’un objet Connection (par la méthode close) valide implicitement la
transaction (même si commit n’a pas été invoqué avant la déconnexion).
Chaque instruction (CREATE, ALTER, DROP) valide implicitement la transaction.
26
CHAPITRE 1: BASES DE DONNÉES RELATIONNELLES
1. Les Systèmes de Gestion de Bases de Données (SGBD)
2. Introduction à la conception de bases de données relationnelles
3. Décomposition de schémas relationnels
4. Normalisation des relations
5. Dépendances fonctionnelles et conception de schémas
1.1 Les Systèmes de Gestion de Bases de Données (SGBD)
Un système de base de données peut être décrit par l’équation suivante:
Système de Base de Données = Base de Données + SGBD
Un SGBD est un système permettant de gérer et de manipuler la base de données, et une base de
données est une collection de données en relation qui sont:
1. partagées par de multiples applications (utilisateurs et/ou programmes),
2. stockées avec une redondance minimum,
3. indépendantes des applications,
4. organisées afin d’être une fondation pour de futures applications.
Le modèle de données est le formalisme qui décrit la structure logique de la base de données et les
opérations sur celle-‐-ci.
Le schéma de base de données est la structure de la base de données. L’instance de la base de don-‐-
nées est le contenu actuel de la base de données.
Une base de données est donc constituée d’une part d’un schéma de base de données et d’une instance de
la base de données d’autre part. On peut, par analogie avec les langages de programmation, définir les
correspondances suivantes:
modèle de données schéma ↔ ↔ instance ↔ variable
langage de programmation
déclaration d’une structure de données
1.1.1 Modèle de Données Relationnel
Une instance de la base de données peut être considérée comme une collection de relations mathéma-‐-
tiques. Chaque relation est représentée par une table dont chaque colonne est appelée un attribut et
chaque ligne est appelée un tuple ou n-‐-uplet. On associe à chaque attribut un ensemble de valeur, ap-‐-
pelé domaine.
Un schéma de relations est alors défini comme un ensemble d’attributs.
EXEMPLE
EMPLOYÉ = {nom, nosécu, nomdépartement, salaire, datenaissance}
CONVENTION DE NOTATION
EMPLOYÉ (nom, nosécu, nomdépartement, salaire, datenaissance)
Un schéma de base de données est une collection de schémas de relations.
EXEMPLE
{ EMPLOYÉ, DÉPARTEMENT, PROJET }
NOTATIONS
schéma de relations R R(A1,A2,...,An)
n-‐-uplet <v1,v2,...,vn>
valeur de l’attribut Ai t[Ai]
valeurs des attributs t[Au,Aw,...Az]
attribut A du schéma R R.A
11.1.2 Contraintes d’intégrité
Il existe un certain nombre de propriétés qui doivent être respectées pour chaque instance d’un sché-‐-
ma de relations ou d’un schéma de base de données afin de préserver la cohérence des informations
stockées dans la base. Ces propriétés sont appelées contraintes d’intégrité.
Les dépendances entre données sont des contraintes d’intégrité qui spécifient les relations entre les
valeurs des attributs. Elles sont très utiles dans la conception de bases de données.
1.2 Introduction à la conception de bases de données relationnelles
1.2.1 Deux approches pour concevoir un schéma de base de données
Il existe deux approches pour concevoir un schéma de base de données: une approche descendante,
également appelée méthode par décomposition, et une approche ascendante, également appelée mé-‐-
thode synthétique. Nous présentons rapidement pourquoi la conception d’un schéma de base de don-‐-
nées peut être présenter des anomalies. Les dépendances fonctionnelles sont un outil théorique qui
permet de vérifier la qualité de conception d’un schéma et de comprendre les conséquences de la re-‐-
dondance de données.
1. Conception descendante (top-‐-down design)
On part d’un schéma de relations unique…
décomposition basée sur les dépendance entre données
(par exemple, les dépendances fonctionnelles)
…pour obtenir une collection de schémas de relations.
2. Conception ascendante (bottom-‐-up design)
On part d’une collection d’attributs…
synthèse (regroupement)
…pour obtenir une collection de schémas de relations.
QUESTIONS
• Quelles sont les propriétés intéressantes d’un schéma de base de données relationnelles ?
– mesure de la qualité du schéma,
– méthodologie de conception.
• Quels sont les algorithmes permettant d’obtenir un schéma possédant les bonnes propriétés ?
– outil dédié à la conception,
– conception automatique.
MESURE DE LA QUALITÉ
1. sémantique des attributs
Plus il est facile d’expliquer la sémantique des attributs d’une relation, plus la conception du
schéma de relations est bonne.
PRINCIPE 1: concevoir un schéma de relations de telle sorte qu’il soit simple d’expliquer ce
qu’il représente.
EXEMPLE
Que signifie FOURNIT (f#, nom, adresse, p#, produit, prix, couleur, nomproj, dép) ?
Ce schéma de relations doit être décomposé comme suit:
PROD(p#, produit, couleur)
FOURNITPROD(f#, nom, adresse,p#, produit, prix)
PROJET(nomproj, dép)
UTILISE(nomproj, p#)
Chaque schéma de relations et chaque attribut ont une sémantique précise.
22. les informations redondantes
Les informations redondantes, à l’origine de problèmes, doivent être supprimées dans la me-‐-
sure du possible.
PRINCIPE 2: concevoir un schéma de relations de telle manière que les insertions, les suppres-‐-
sions et les mises à jour ne posent pas de problèmes.
EXEMPLE
Si on utilise la relation suivante FOURNITPROD(f#, nom, adresse, p#, produit, prix) plutôt
que le schéma de relations suivant:
FOURNISSEUR(f#, nom, adresse)
FOURNIT(f#, p#, prix)
alors le nom et l’adresse d’un fournisseur sont stockés plusieurs fois dans les n-‐-uplets corres-‐-
pondant aux produits vendus par le fournisseur.
QUAND Y-‐-A-‐-T-‐-IL REDONDANCE D’INFORMATION ?
On constate assez facilement que la même adresse apparaît autant de fois qu’il y aura de produits si
l’on utilise la relation FOURNITPROD(f#, nom, adresse, p#, produit, prix). Or on sait qu’un fournis-‐-
seur ne possède qu’une seule adresse et cela même s’il vend plusieurs produits. On appelle cette
propriété une dépendance fonctionnelle. Un mauvais schéma relationnel peut alors entraîner des
anomalies lors des manipulations.
f# nom Labaleine Lemelon adresse p# produit prix
F1 Paris P1 parapluie 110
F2 Lyon P2 chapeau 50
F3 Toutcuir Lyon P3 sac à main 650
F1 Labaleine Paris P4 parasol 150
F1 Labaleine Paris P5 ombrelle 70
F4 Letour Nantes P6 ceinture 55
F5 P3 650
Legrand Paris sac à main Dans la relation ci-‐-dessus, il existe des redondances qui peuvent engendrer les difficultés
suivantes:
• anomalie d’insertion. Telle qu’elle se présente, cette relation ne permet pas de mémoriser dans
la base un produit dont le fournisseur n’existe pas.
• anomalie de suppression. La disparition d’un fournisseur, qui est l’unique fournisseur d’un
produit, entraîne également la disparition des informations concernant ce produit (exemple:
Letour).
• anomalie de mise à jour. Toute modification sur le prix d’un produit qui apparaît plusieurs fois
dans la relation doit être répercutée sur tous les n-‐-uplets correspondants (exemple: sac à main).
Cela augmente le temps de mise à jour et les risques d’incohérence.
On résout ces problèmes en étudiant les dépendances entre les données, et en décomposant et norma-‐-
lisant les relations. On obtient ainsi des schémas de relations qui évitent les anomalies citées ci-‐-dessus.
Attention cependant à ne pas voir la normalisation comme un dogme. Il arrive parfois que, pour des
raisons d’efficacité notamment, on soit obligé de dénormaliser.
1.2.2 Dépendance Fonctionnelle (DF)
Soient R un schéma de relations, et X=A1,A2,…,An et Y=B1,B2,…,Bm des sous-‐-ensembles de R.
X détermine fonctionnellement Y , noté X → Y , ssi pour chaque instance r de la relation R, pour chaque
paire de n-‐-uplets t et s appartenant à r, t[X] = s[X] implique t[Y] = s[Y] (où t[X] désigne la projection du
n-‐-uplet t sur les attributs X).
Autrement dit, X → Y signifie qu’une valeur de X détermine au plus une valeur de Y.
3Une dépendance fonctionnelle est une propriété définie sur l'ʹintention du schéma et non son extension
(elle est donc invariante dans le temps et ne peut être extraite à partir d'ʹexemples). C'ʹest une propriété
qui doit être extraite de la connaissance que l'ʹon a de l'ʹapplication à modéliser et qui permet d’élimi-‐-
ner la redondance.
EXEMPLES
Considérons la relation suivante
FILM (titre, année, durée, type, studio, acteurPrincipal)
avec une instance de la relation contenant les n-‐-uplets suivants:
titre année durée type studio acteurPrincipal
StarWars 1977 124 couleur Fox Carrie Fisher
StarWars 1977 124 couleur Fox Mark Hamill
StarWars 1977 124 couleur Fox Harrison Ford
1991 104 couleur Disney Emilio Estevez
1991 95 couleur Paramount Dana Carvey
1992 95 couleur Paramount Mike Meyers
Mighty Ducks Wayne’s World Wayne’s World On peut en déduire les trois DF suivantes:
{titre, année} → durée
{titre, année} → type
{titre, année} → studio
Par contre, la dépendance suivante n’est pas une DF:
{titre, année} → acteurPrincipal
En effet, étant donné un film, il peut exister dans la base (telle qu’elle est modélisée) plusieurs acteurs
principaux.
Enfin, la DF {titre, année} → durée signifie qu’il ne peut exister dans une instance de FILM les deux n-‐-
uplets suivants:
titre année durée type studio acteurPrincipal
Farenheit, 9/11 2004 124 couleur Fox Georges Bush
Farenheit, 9/11 2004 130 couleur Fox Dick Cheney
CONVENTIONS
• L’ensemble de DF suivant:
{A1,A2,…,An} → B1
{A1,A2,…,An} → B2
…
{A1,A2,…,An} → Bm
est équivalent à {A1,A2,…,An} → B1,B2,...,Bm.
41.2.3 Propriétés des DF
Les trois premières propriétés (réflexivité, augmentation et transitivité) sont également appelés axio-‐-
mes d’Armstrong. De ces trois axiomes, on peut en déduire trois autres propriétés (pseudo-‐-transitivité,
union et décomposition).
Si Y ⊆ X, alors on a X → Y
RÉFLEXIVITÉ
Si X → Y , alors on a X ∪ Z → Y ∪ Z
AUGMENTATION
TRANSITIVITÉ
PSEUDO-‐-TRANSITIVITÉ
Si X → Y et Y ∪ W → Z, alors X ∪ W → Z
Si X → Y et Y → Z, alors on a X → Z
Si X → Y et X → Z, alors X → Y ∪ Z
UNION
Si X → Y et Z ⊆ Y , alors X → Z
DÉCOMPOSITION
• les n-‐-uplets de la relation S sont la projection sur {B1,B2,…,Bm} de tous les n-‐-uplets de R. La pro-‐-
jection est l’opération qui consiste à construire la nouvelle relation S à partir de R en prenant
pour chaque n-‐-uplet t de R uniquement les attributs {B1,B2,…,Bm} et en éliminant les n-‐-uplets en
double,
• de manière similaire, les n-‐-uplets de la relation T sont la projection sur {C1,C2,…,Ck} de tous les n-‐-
uplets de R.
La décomposition de la relation R en R1,R2,…,Rn est sans perte si la jointure des relations R1,R2,…,Rn
permet de retrouver tous les n-‐-uplets de la relation R d’origine. La jointure est l’opération qui permet
de construire une nouvelle relation à partir de deux relations ayant au moins un attribut commun.
EXEMPLE
On peut décomposer la relation FILM définie précédemment en deux relations FILM1 et FILM2 telles
que:
FILM1 = (titre, année, durée, type, studio)
FILM2 = (titre, année, acteurPrincipal)
7Si on utilise la décomposition telle qu’elle est définie, on obtient au niveau des n-‐-uplets pour FILM1 et
FILM2 les résultats suivants:
titre année durée type studio
StarWars 1977 124 couleur Fox
Mighty Ducks 1991 104 couleur Disney
titre année acteurPrincipal
StarWars 1977 Carrie Fisher
StarWars 1977 Mark Hamill
StarWars 1977 Harrison Ford
1991 Emilio Estevez
1991 Dana Carvey
1992 Mike Meyers
Mighty Ducks Wayne’s World Wayne’s World On peut remarquer que cette décomposition élimine les problèmes
soulevés au paragraphe 1.2.1. La
redondance est éliminée, par exemple la durée de chaque film n’apparaît qu’une fois, dans la relation
FILM1. Le risque d’anomalie de mise à jour a ainsi disparu. De même, le risque d’anomalie de sup-‐-
pression a disparu. Si on supprime tous les acteurs du film Wayne’s World, le film disparaît égale-‐-
ment. Il apparaît que FILM2 possède malgré tout de la redondance, puisque titre et année apparais-‐-
sent plusieurs fois. Cependant, ces deux attributs forment une clé, et il n’est pas possible de représen-‐-
ter plus succinctement un film.
1.4 Normalisation des relations
Les formes normales de schémas de relations sont des propriétés souhaitables que doit posséder cha-‐-
que schéma de relations. Elles sont nécessaires (mais non suffisantes) pour une « bonne » conception.
Historiquement, les formes normales suivantes ont été proposées (de la moins restrictive à la plus res-‐-
trictive).
Première Forme Normale (1NF)
Deuxième Forme Normale (2NF)
Troisième Forme Normale (3NF)
Forme Normale de Boyce and Codd (BCNF)
Quatrième Forme Normale (4NF)
Cinquième Forme Normale (5NF)
Les formes normales définissent un ordre partiel sur les schémas de relation. On peut donc voir une
forme normale comme une classe d'ʹéquivalence (on peut comparer deux schémas dans deux classes
d'ʹéquivalence différentes mais pas dans la même). Il faut aussi noter que le seul élément qui est pris en
compte par les formes normales est la non redondance d'ʹinformations d'ʹun schéma. Selon les formes
normales, un « bon » schéma est un schéma sans redondance (ce qui ne veut pas forcément dire qu'ʹil
est efficace par exemple). Un schéma relationnel sans qualité particulière est appelé schéma en 1ère
forme normale (on note 1NF) et si on rajoute certaines qualités on obtient les deuxième et troisième
formes normales (on note 2NF et 3NF).
On ne présente ici que les formes normales dont la définition utilise exclusivement les dépendances
fonctionnelles. Si on prend en compte d'ʹautres dépendances entre données comme les dépendances
multivaluées, on obtient alors les 4NF et 5NF. La BCNF reste cependant l'ʹobjectif de normalisation le
plus « classique ».
1NF: une relation est en première forme normale ssi tout attribut a une valeur atomique (vrai par défi-‐-
nition du modèle relationnel).
82NF : une relation est en deuxième forme normale ssi elle est en 1NF et si tous les attributs non clés
sont pleinement dépendants des clés (toutes les dépendance entre une clé et un attribut non clé sont
des dépendances fonctionnelles élémentaires).
3NF : une relation est en troisième forme normale ssi elle est en 2NF et si tous les attributs non clés
sont directement et pleinement dépendants des clés (si tout attribut non clé ne dépend pas d'ʹun autre
attribut non clé).
BCNF (Boyce-‐-Codd) : une relation est en BCNF ssi elle est en 3NF et si les seules DFE sont celles de la
forme C → X avec C clé (seules les clés sont en partie gauche de DF).
1.4.1 Première forme normale (1NF)
Une relation R est dite en première forme normale (1NF) si tous ses attributs sont atomiques et qu’il
n’existe pas d’attributs répétitifs. De plus, chaque attribut doit avoir une sémantique précise. V oyons
pourquoi la relation suivante n’est pas en première forme normale.
titre année durée type studio
StarWars 1977 124 couleur Fox, Los Angeles
Mighty Ducks 1991 104 couleur Disney , San Francisco
Wayne’s World 1992 95 couleur Paramount, Los Angeles
Les attributs de cette relation ne sont pas atomiques. En effet, l’attribut studio contient à la fois le nom
et la ville, ce qui est gênant si l’on souhaite extraire tous les studios situés à Los Angeles.
Analysons maintenant un deuxième exemple. La relation suivante n’est pas non plus en 1NF.
titre année acteur1 acteur2 acteur3
StarWars 1977 Carrie Fisher Mark Hamill Harrison Ford
Mighty Ducks 1991 Emilio Estevez
Wayne’s World 1992 Dana Carvey Mike Meyers
En effet, la première forme normale stipule que les attributs ne doivent pas être répétitifs. Or, la liste
des acteurs ne respecte pas cette propriété. Si on veut rechercher dans quel film a joué Harrison Ford,
on est obligé non seulement de parcourir tous les n-‐-uplets, mais également toutes les colonnes. De
plus, si l’on souhaite rajouter un quatrième acteur, il faut modifier la relation toute entière.
Enfin, que pensez-‐-vous de la relation suivante:
titre année durée type studio
StarWars 1977 124 SF Fox
Mighty Ducks 1991 104 couleur Disney
Wayne’s World 1992 95 couleur Paramount
Il semble que cette relation soit en 1NF. Les attributs sont atomiques, il n’y a pas d’attributs répétitifs.
Malgré tout, l’attribut type ne possède pas une sémantique claire, représentant soit un genre (SF), soit
le type de la pellicule. Cette relation n’est donc pas en 1NF.
1.4.2 Deuxième forme normale (2NF)
Une relation R est dite en deuxième forme normale (2NF) ssi
• elle est en 1NF,
• tout attribut n’appartenant pas à une clé ne dépend pas d’une partie de cette clé (pas de dépen-‐-
dances partielles).
Autrement dit, dès qu’un attribut non clé dépend d’une partie d’une clé, la relation n’est pas en 2NF.
9V oyons dans un premier temps un exemple abstrait. La relation R(A,B,C) munie de l’ensemble F des
dépendances est en 1NF mais pas en 2NF.
A,B → C
B →C
Regardons maintenant sur un exemple concret. Considérons la relation suivante:
numSalarié nom numProjet heures
20036 Durand 1 18,5
20036 Durand 2 6,7
36900 Leroux 2 8,5
45002 Franck 3 23,5
45002 Franck 1 4,8
L’ensemble F des DF est:
numSalarié → nom
numSalarié,numProjet → heures
La relation n’est pas en 2NF. En effet, la clé minimale de cette relation est {numSalarié,numProjet}.
L’attribut non clé heure est en totale dépendance fonctionnelle avec la totalité de la clé. Par contre,
l’attribut non clé nom dépend d’une partie de la clé, à savoir numSalarié. Pour que la relation soit en
2NF, il est nécessaire de scinder la relation initiale en deux relations, comme ceci:
numSalarié numProjet heures
20036 1 18,5
20036 2 6,7
36900 2 8,5
45002 3 23,5
45002 1 4,8
numSalarié nom
20036 Durand
36900 Leroux
45002 Franck
Chacune de ces deux relations répond désormais aux exigences de la première et de la deuxième
forme normale. La première relation a pour clé primaire l’attribut numSalarié, et la deuxième relation
a pour clé {numSalarié,numProjet}.
1.4.3 T roisième forme normale (3NF)
OBJECTIFS DE LA 3NF
1. élimination des dépendances partielles
S’il existe une dépendance partielle Y → A, où X est une clé minimale et Y un sous-‐-ensemble
de X, alors chaque n-‐-uplet utilisé pour associer une valeur X aux valeurs de A sera répété pour
les valeurs de Y (d’où redondance des informations).
La condition de la 3NF élimine cette possibilité, évitant ainsi les mises à jour incorrectes et la
redondance.
2. élimination des dépendances transitives
S’il existe une dépendance transitive X → Y → A, alors on ne peut associer une valeur Y à une
valeur X que s’il existe une valeur A associée à une valeur Y . Cela conduit à des problèmes
d’insertion et de suppression.
DÉFINITION
On considère les définitions suivantes:
R: un schéma de relations,
F: un ensemble de DF sur R,
X: un sous-‐-ensemble de R,
A: un attribut.
10On rappelle que A est un attribut clé ssi il fait partie d’une clé minimale de R et que dans le cas con-‐-
traire, A est appelé un attribut non clé.
La relation R est dite en troisième forme normale (3NF) ssi lorsque X → A est dans F+ et A n’est pas
dans X, soit X est une clé primaire, soit A est un attribut clé.
Il existe deux cas dans lesquels X → A ne respecte pas la 3NF:
Cas 1: X est un sous-‐-ensemble d’une clé minimale. X → A est une dépendance partielle.
Cas 2: X n’est pas un sous-‐-ensemble de toutes les clés minimales. X → A est une dépendance
transitive. Elle crée une chaîne non triviale de DF Z → X → A pour une clé minimale Z.
Autrement dit, une relation est dite en 3NF ssi:
• elle est en 2NF,
• il n’existe pas de dépendance entre attributs non clé.
EXEMPLE 1
R=ABCD
F = {AB → C,B → D,BC → A}
AB et BC sont des clés minimales et ce sont les seules. A, B et C sont des attributs clés. D est
un attribut non clé.
EXEMPLE 2
R=VRC R(ville, rue, code)
F = {VR → C,C → V}
R est en 3NF.
EXEMPLE 3
R=SAIP
F = {SI → P ,S → A}
SI est la seule clé, et A est un attribut non clé.
S → A ne respecte pas la 3NF, étant donné que S n’est pas une clé primaire. De plus, S → A est
une dépendance partielle.
On remarque dans cet exemple que la dépendance S → A est dans F. Cependant, en général,
les dépendances non conformes à la forme normale étudiée sont dans F+ plutôt que dans F.
1.4.4 Forme normale de Boyce-‐-Codd (BCNF)
OBJECTIFS DE LA BCNF
1. élimination des dépendances partielles,
2. élimination des dépendances transitives,
3. élimination des anomalies non prises en compte par la 3NF.
DÉFINITION
On considère les définitions suivantes:
R: un schéma de relations,
F: un ensemble de DF sur R,
X: un sous-‐-ensemble de R,
A: un attribut.
R est en BCNF ssi lorsque X → A appartient à F+ et que A n’est pas dans X, alors X est une clé
de R.
Une relation en 3NF qui ne possède qu’un seule clé minimale est en BCNF.
EXEMPLE 1
M=NAC MEMBRE(nom,adresse,cotisation)
F = {n → a, n → c}
M est en BCNF.
11EXEMPLE 2
R=VRC R(ville,rue,code)
F = {VR → C,C → V}
R est en 3NF mais pas en BCNF. Dans R, on ne peut pas stocker la ville correspondante à un
code à moins de connaître une rue associée à ce code (anomalie d’insertion). En effet, C → V
est vraie et V n’appartient pas à C, alors que C ne contient aucune des clés minimales de R.
1.5 Dépendances fonctionnelles et conception de schémas
Nous l’avons déjà abordé au paragraphe 1.2.1, il existe deux méthodes pour concevoir un schéma de
bases de données qui soit en 3NF: la méthode dite synthétique, et la méthode par décomposition.
1.5.1 La méthode synthétique
L’algorithme dit de synthèse permet dʹobtenir une décomposition 3NF qui préserve les DF. Il est basé
sur le calcul de la couverture minimale (ou irredondante) dʹun ensemble de DF. Le point de départ de
cette méthode est la connaissance des attributs et d’un ensemble de dépendances fonctionnelles. On
construit le graphe des DF dans lequel chaque attribut constitue un noeud, et chaque DF est représen-‐-
tée par un arc. L’algorithme de synthèse va travailler sur ce graphe et construire un ensemble de rela-‐-
tions en 3NF.
ALGORITHME DE SYNTHÈSE
Pour obtenir un schéma de relations en 3NF, on applique l’algorithme suivant:
1. on construit une couverture minimale à partir de l’ensemble F des DF,
2. on en déduit les relations en 3NF en regroupant dans une même relation tous les attributs ayant
la même partie gauche dans le graphe des DF,
3. si aucune des relations obtenues à l’étape précédente ne contient pas (ou ne permet pas d’obte-‐-
nir) la clé de la relation initiale, on ajoute une relation composée uniquement des attributs de la
clé.
EXEMPLE
Soit la relation GESPROD (numEmp, nomEmp, numProj, budProj, emploi, taux, nbhr) qui décrit la
gestion de projet dans une entreprise. Les attributs sont les suivants: le numéro d’employé, le nom de
l’employé, le numéro du projet, le budget du projet, l’emploi occupé par l’employé, le taux de rému-‐-
nération de l’employé, et le nombre d’heures de travail de l’employé sur un projet donné. La seule clé
minimale de la relation est constituée des attributs {numEmp, numProj}. L’ensemble F des DF est le
suivant:
numEmp → nomEmp
numEmp → emploi
emploi → taux
numEmp → taux
numProj → budProj
numEmp,numProj → nbHr
Pour obtenir une décomposition de GESPROD muni de F en un ensemble de relations en 3NF, on ap-‐-
plique lʹalgorithme suivant:
1. construction de la couverture minimale: on élimine les dépendances transitives:
numEmp → taux est une DF transitive car numEmp → emploi et emploi → taux.
2. déduction des relations en 3NF en regroupant dans une même relation tous les attributs ayant
même partie gauche dans F.
EMPLOYÉ (numEmp, nomEmp, emploi)
PROJET (numProj, budProj)
RÉMUNÉRATION (emploi, taux)
OCCUPE (numEmp, numProj, nbHr)
3. on vérifie que la clé est présente dans au moins une relation. Dans notre exemple, la relation
OCCUPE possède la clé de la relation initiale.
121.5.2 La méthode par décomposition
Une autre manière de concevoir un schéma relationnel en troisième forme normale est de partir du
schéma complet (ensemble de tous les attributs) et de décomposer cette « grosse » relation (appelée
également relation universelle) en respectant les dépendances fonctionnelles. Cette approche est appelée
approche par décomposition. Le problème est dʹordonner lʹordre des décompositions de manière à
obtenir un schéma en 3ème forme normale. En effet, chaque relation produite ne conserve qu’un cer-‐-
tain nombre de DF (celles définies sur ses attributs propres) et nʹest donc pas forcément en 3ème forme
normale. De plus, lʹensemble des DF du schéma complet nʹest pas forcément préservé.
ALGORITHME DE DÉCOMPOSITION
entrée: un schéma relationnel (ensemble dʹattributs) et un ensemble E de DF entre ses attri-‐-
buts
sortie: une ou plusieurs relations en 3NF dont la jointure redonne la relation initiale (par con-‐-
tre des DF de E ont pu être perdues)
principe: lʹalgorithme peut se voir comme la construction dʹun arbre binaire. La racine de cet
arbre est la relation à décomposer. Lʹarbre se construit récursivement de la manière suivante:
1. on choisit une DF dfi dans lʹensemble E des DF,
2. le fils gauche du noeud racine est une relation composé de tous les attributs de dfi,
3. dfi est retirée de lʹensemble E,
4. le fils droit du noeud racine est une relation composée de tous les attributs de la racine ex-‐-
cepté ceux présents en partie droite de dfi.
Problèmes: la solution dépend du choix des DF selon lesquelles on choisit de décomposer et il ne pré-‐-
serve pas nécessairement les DF.
On sait néanmoins que toute relation admet une décomposition en 3NF qui préserve les DF.
EXEMPLE
Soit la relation universelle associée à la gestion de production définie au paragraphe 1.5.1:
GESPROD (numEmp, nomEmp, numProj, budProj, emploi, taux, nbhr)
On constate quʹelle n
ʹest pas en 2NF car
numEmp → nomEmp, taux, emploi
numProj → budProj
Ceci conduit à une décomposition de la relation GESPROD en trois relations en 2NF:
PROJET (numProj, budProj)
OCCUPE (numEmp, numProj, nbHr)
EMPREM (numEmp, nomEmp, emploi, taux)
On constate que la relation EMPREM n
ʹest pas en 3NF car
emploi → taux (un attribut non clé dépend fonctionnellement dʹun autre attribut non clé)
On décompose la relation EMPREM en deux relations en 3NF
EMPLOYÉ (numEmp, nomEmp, emploi)
RÉMUNÉRATION (emploi, taux)
On obtient finalement quatre relations en 3NF
PROJET (numProj, budProj)
OCCUPE (numEmp, numProj, nbHr)
RÉMUNÉRATION (emploi, taux)
EMPLOYÉ (numEmp, nomEmp, emploi)
EXEMPLE SUR LES FORMES NORMALES
Soit le schéma R = (P , H, N, Y , T), et F = {P → T | P , H → Y | H, N → P | H, Y → N}.
• ensemble des DFE engendrées:
H, N → T
P, H →N
H,N → Y
13H, Y → P
P, H →T
H, Y → T
• on a donc trois clés potentielles (H, N | P , H | H, Y):
H, N → P , T, Y
P , H → T, Y , N
H, Y → N, P , T
• les attributs clés sont donc: H, N, P , Y , et un attribut non clé est T.
• par définition le schéma est en 1ère forme normale. Est il en 2NF ?
Non, car P , H → T n
’est pas une DFE (on a P → T), R est donc en 1NF.
• application de l’algorithme de décomposition:
R(P, H, N, Y, T)
P ! T
R1(P, T) Clé P (3NF) R2(P, H, N, Y)
Clés H,N ou P,H ou H,Y (3NF) R =
R1 * R2 (pas de perte des DFs)
14 CHAPITRE 2: SÉCURITÉ DE FONCTIONNEMENT
1. Les transactions
2. La tolérance aux pannes
3. La gestion de la concurrence
4. Le verrouillage sous Oracle
5. JDBC et les transactions
2.1 Les transactions
2.1.1 Définition
L’objectif de ce chapitre est d’étudier les mécanismes que fournit un SGBD pour s’assurer que les don-‐-
nées demeurent dans un état cohérent, c’est-‐-à-‐-dire qu’elles ne sont pas mises en cause par un pro-‐-
blème logiciel ou matériel, ou par le fait que plusieurs utilisateurs manipulent les données simultané-‐-
ment. En effet, les SGBD sont utilisés par plusieurs utilisateurs simultanément, à la fois pour les requê-‐-
tes ou pour des modifications sur la base de données.
Par exemple, on suppose que deux personnes souhaitent retirer 100€ d’un même compte. Un SGBD
doit s’assurer qu’aucun des deux retraits ne soit perdu. Par comparaison avec un système d’exploita-‐-
tion, deux personnes peuvent très bien éditer le même fichier, mais c’est le dernier qui écrit qui voit
ses modifications conservées. Ce comportement n’est pas imaginable dans le contexte des bases de
données.
Pour résoudre ce problème, on a introduit le concept de transaction; Une transaction est un pro-‐-
gramme qui forme une unité logique de traitement. Elle est constituée d’une ou plusieurs opérations
d’accès aux objets de la base de données (insertion, suppression, modification ou lecture). Enfin, une
transaction fait passer la base d’un état cohérent E1 à un état cohérent E2. En particulier:
• une transaction doit commencer à partir d’un état cohérent de la base,
• pendant la transaction, la base peut éventuellement être dans un état incohérent,
• lorsque la transaction se termine avec succès, la base doit être dans un état cohérent,
• lorsqu’une transaction a été validée, les modifications sur la base sont persistantes, même en cas de
problèmes logiciels ou matériels,
• plusieurs transactions peuvent s’exécuter en parallèle.
On distingue deux problèmes à prendre en compte:
• la tolérance aux pannes: il faut restaurer la base dans l’état où elle se trouvait avant l’incident. Les mé-‐-
canismes utilisés sont les transactions, la tenue d’un journal, la reprise après panne.
• l'ʹexécution concurrente de plusieurs transactions: il faut veiller à ce que l’action simultanée de plusieurs
utilisateurs sur les mêmes données ne conduise pas à une incohérence de ces données. Les méca-‐-
nismes utilisés sont la gestion des accès concurrents, les transactions, le verrouillage et la gestion de
l’interblocage.
2.1.2 Propriétés ACID
Un SGBD supporte ce que l’on appelle des transactions ACID. Les propriétés ACID sont:
• atomicité : lors de l’exécution d’une transaction, soit toutes ses actions sont exécutées, soit aucune ne
l’est,
• cohérence : après une transaction, la base se trouve dans un état cohérent,
• isolation : il n’y a pas d’incohérence liée à la concurrence d’accès,
• durabilité : les effets d’une transaction correctement exécutée survivent à une panne ultérieure.
V oyons sur un exemple ce que cela signifie. On suppose une transaction qui effectue un transfert d’ar-‐-
gent (100€) d’un compte A vers un compte B:
1. lire(A) 4. lire(B)
2. A:= A –100 5. B := B + 100
3. écrire(A) 6. écrire(B)
15La propriété d’atomicité spécifie que si la transaction échoue après l’étape 3 et avant l’étape 6, le sys-‐-
tème doit s’assurer qu’aucune mise à jour n’aura été effectuée, sous peine de voir une incohérence
entre la balance des deux comptes.
La propriété de cohérence spécifie que la somme des soldes de A et B est inchangée après l’exécution
de la transaction.
La propriété d’isolation spécifie que si une autre transaction essaie d’accéder à la base entre les étapes
3 et 6, elle ne verra pas les modifications faites aux étapes 1 à 3. L’isolation peut être assurée de ma-‐-
nière triviale en exécutant les transactions en séquence (de manière sérialisable). Cependant, nous ver-‐-
rons que permettre l’exécution concurrente des plusieurs transactions apporte des avantages, à condi-‐-
tion de ne pas avoir d’interférences entre les transactions simultanées.
Enfin, la propriété de durabilité spécifie que lorsque l’utilisateur a validé la transaction, les mises à
jour doivent persister, quelques soient les défaillances logicielles ou matérielles qui pourraient surve-‐-
nir.
2.1.3 États d’une transaction
Une transaction est une unité atomique (au sens indivisible) de travail qui doit être soit totalement
terminée soit pas du tout (atomicité). Le système doit donc savoir quand la transaction commence, se
termine, est validée ou est abandonnée. Pour cela, une transaction peut se trouver dans plusieurs
états:
• active: l’état initial. La transaction entre dans cet état immédiatement après son début d’exécution, et
elle y reste durant son exécution,
• partiellement validée: lorsque la dernière instruction de la transaction a été exécutée,
• échouée: dès que l’exécution ne peut plus continuer normalement,
• annulée: après que la transaction a été annulée, et que la base ait été restaurée dans l’état cohérent
d’avant le début de la transaction. Il existe alors deux options après qu’une transaction ait été annu-‐-
lée, soit on redémarre la transaction, soit on tue la transaction.
• validée: après une exécution totalement terminée.
En fait, SQL supporte les transactions, souvent de manière invisible. En effet, chaque commande effec-‐-
tuée dans l’outil d’interrogation est une transaction. Ainsi, chaque fois que vous faites une (ou plu-‐-
sieurs) requête(s) dans SQL/Plus, vous débutez sans le savoir une transaction.
2.1.4 Commit, rollback
L’instruction SQL COMMIT permet de valider une transaction. Cette instruction peut être explicite dans
une transaction où, comme c’est souvent le cas, implicite et exécutée à la fin de la transaction par le
SGBD. Une fois l’instruction COMMIT exécutée, les modifications faites sont permanentes et la transac-‐-
tion s’achève.
L’instruction ROLLBACK permet également d’achever la transaction, mais en l’annulant. Il n’y alors au-‐-
cun effet sur la base, et le SGBD doit alors revenir à l’état précédent le début de la transaction puisque
c’est le dernier point garanti de cohérence de la base.
2.1.5 Exemple
V oyons sur un exemple l’interaction entre deux transactions. On suppose la relation BarÀBière(bar,
bière, prix), et on suppose que le bar Jo vend de la Chimay (3,00€) et de la Leffe (2,50€). Paul interroge
la base, et la relation BarÀBière pour connaître le prix minimum et le prix maximum du bar Jo. Entre-‐-
temps, Jo décide de cesser de vendre de la Chimay et de la Leffe, pour ne plus vendre que de la Kwak
à 3,50€.
Paul exécute les deux instructions SQL suivantes afin de connaître les prix minimum et maximum:
(max) SELECT MAX(prix) FROM BarÀBière
WHERE bar = ‘Jo’;
(min) SELECT MIN(prix) FROM BarÀBière
WHERE bar = ‘Jo’;
16Pendant ce temps, Jo exécute les instructions suivantes:
(del) DELETE FROM BarÀBière
WHERE bar = ‘Jo’;
(ins) INSERT INTO BarÀBière
VALUES(‘Jo’, ‘Kwak’, 3.50);
On a des instructions SQL qui peuvent être entrelacées, avec les contraintes suivantes: (max) doit être
exécuté avant (min), et (del) doit être exécuté avant (ins). Que se passe-‐-t-‐-il lorsque Jo et Paul mettent à
jour la base ? Si les instructions ont lieu dans l’ordre suivant: (max)(del)(ins)(min), on obtient:
Prix 2,50 | 3,00 2,50 | 3,00 3,50
Instruction (max) (del) (ins) (min)
Résultat 3,00 3,50
Ainsi, Paul voit que MAX < MIN !
Comment peut-‐-on résoudre le problème avec les transactions ? Si l’on regroupe les instructions
(max)(min) de Paul dans une seule transaction, alors il n’y aura plus de problèmes. En effet, soit la
transaction s’exécutera avant les modifications de Jo, et Paul verra alors les anciens prix, soit la trans-‐-
action s’exécute après la modification, et il n’y aura pas de problème. La transaction permet donc aux
deux instructions (max)(min) de s’exécuter sur les mêmes données.
Il existe cependant encore une possibilité de comportement étrange. Supposons que Jo exécute sa mo-‐-
dification de prix, mais qu’au dernier moment, il change d’avis et exécute un ROLLBACK. Si Paul
exécute sa transaction après l’instruction (ins), mais avant l’annulation, il va voir une valeur 3,50 qui
n’existe pas dans la base. Pour résoudre ce problème, on va donc exécuter les instructions de Jo dans
une transaction. Ainsi, les effets de (del)(ins) dans une transaction ne pourront être vus par d’autres
transactions que lorsque la transaction aura été validée. Si la transaction venait à être annulée, ses ef-‐-
fets ne seraient pas vus par les autres transactions.
2.1.6 Gestion des transactions dans Oracle
Une transaction débute avec la première instruction SQL exécutable et se termine lors de l’exécution
d’un commit ou d’un rollback, lors de la déconnexion de l’utilisateur (commit), ou lors d’un arrêt
anormal du processus utilisateur (rollback).
Les mises à jour faites par une transaction ne sont visibles pour les autres utilisateurs qu’après la vali-‐-
dation de la transaction (tant qu'ʹune transaction n'ʹest pas validée, les autres utilisateurs accèdent aux
anciennes valeurs des données modifiées).
2.2 La tolérance aux pannes
2.2.1 Journal
Il existe plusieurs types d’incidents qui peuvent survenir sur une base de données :
• échec d’une transaction: une erreur logique dans le programme l'ʹempêche de se poursuivre norma-‐-
lement (erreur lors d'ʹune insertion, suppression ou mise à jour), ou une erreur système arrête le dé-‐-
roulement normal du programme (verrouillage, saturation, processus tué),
• crash système: il entraîne la perte des données en mémoire centrale,
• panne disque: elle provoque la perte physique des données.
Les algorithmes de récupération (recovery) sont des techniques qui permettent aux SGBD d’assurer la
cohérence, l’atomicité et la durabilité malgré les incidents qui peuvent survenir. En général, les algo-‐-
rithmes de récupération possèdent deux parties: la première prend en charge les actions qui ont lieu
lors du déroulement normal de la transaction afin d’avoir assez d’informations pour permettre la ré-‐-
cupération en cas de problème, et la deuxième qui prend en charge les actions à effectuer après un
problème afin de pouvoir récupérer la base dans un état cohérent.
17Pour assurer la reprise sur panne, les SGBD et Oracle en particulier utilisent la notion de journal. Un
journal est un fichier texte dans lequel le SGBD inscrit, dans l’ordre d’exécution, toutes les actions de
mise à jour qu’il effectue. Ainsi, le journal est une séquence d’enregistrements qui mémorise les mises
à jour faites sur la base. Lorsqu’une transaction Ti démarre, elle s’enregistre dans le journal sous la
forme <début transaction, Ti >. Avant que la transaction Ti exécute une instruction écrire(X), un enregis-‐-
trement <Ti, X, V1, V2> est écrit dans le journal (V1 est la valeur de X avant l’écriture, et V2 est la valeur
de X après l’écriture). Lorsque la transaction Ti a lu une valeur, un enregistrement <lecture, Ti, X> est
écrit dans le journal. Enfin, <valider, Ti> ou <annuler, Ti> sont écrits dans le journal suivant que la
transaction a été validée ou annulée.
En Oracle, la gestion des transactions utilise deux fichiers :
• un fichier journal redo log: il enregistre toutes les modifications effectuées (insert, update, delete)
dans les tables de la base par chaque transaction.
• un fichier rollback segment: il enregistre les anciennes valeurs des lignes des tables modifiées par
une transaction.
Le système affecte à chaque transaction un numéro chronologique (SCN – System Control Number) qui
permet de l’identifier de manière unique. Toute opération modifiant une donnée de la base est enregis-‐-
trée dans le fichier rollback segment et dans le fichier journal redo log avant mise à jour de la base. Le
journal redo log est chronologique.
Lors du commit d'ʹune transaction, il faut :
• enregistrer le commit de la transaction dans les fichiers redo log et rollback segment,
• débloquer les lignes des tables verrouillées par la transaction.
Lors du rollback d'ʹune transaction, il faut :
• redonner les anciennes valeurs à toutes les lignes des tables modifiées par la transaction (à partir des
rollback segment),
• débloquer les lignes des tables verrouillées par la transaction.
2.2.2 Reprise après incident
Elle est disponible uniquement pour les incidents sans perte de données sur disque. L’objectif est de
restaurer la base dans un état cohérent telle qu'ʹelle se trouvait juste avant la panne. Le mécanisme de
reprise est le suivant:
• appliquer toutes les modifications enregistrées dans le fichier redo log à la base de données (roll-‐-
forward)
• pour toutes les transactions sans commit, on remet les lignes des tables concernées aux anciennes
valeurs (rollback). Ceci est fait à partir des rollback segment.
Après un incident, on ne traite que les modifications effectuées après le point de reprise (ou point de
contrôle). Un point de reprise consiste à 1) écrire les buffers du fichier redo log sur disque, 2) écrire les
buffers de la base de données sur disque, 3) écrire un article point de reprise dans le fichier redo log.
On peut préciser un point de reprise en utilisant la commande SAVEPOINT pdr ;. Par la suite, on
pourra revenir à ce point en utilisant la commande ROLLBACK TO pdr; qui permet de retrouver l’envi-‐-
ronnement tel qu’il était lors de la déclaration du point de reprise.
SQL Résultats
SA VEPOINT a; Premier point de reprise de la transaction
DELETE …; Modification de la base
SA VEPOINT b; Deuxième point de reprise de la transaction
INSERT INTO…; Modification de la base
SA VEPOINT c; Troisième point de reprise de la transaction
UPDATE …; Modification de la base
18ROLLBACK TO c; L’ordre UPDATE est annulé, le point C reste défini
ROLLBACK TO b; L’ordre INSERT est annulé, le point C est perdu, le point B reste défini
ROLLBACK TO c; ORA-‐-01086 error; savepoint C no longer defined
INSERT TO…; Modification de la base
COMMIT; Valide toutes les actions effectuées par le DELETE (première modification)
et le INSERT (dernière modification). Toutes les autres modifications ont été
annulées avant le COMMIT. Le point A n’est plus actif.
EXEMPLE: traitement des transactions
La mise en œuvre du mécanisme de reprise s’effectue comme ceci. Soient les 5 transactions suivantes
au moment d'ʹun incident :
T1
T2
T3
T4
T5
Point de reprise Incident
• T1 est achevée lors du point de reprise, elle n'ʹest pas traitée.
• T2 et T4 sont validées (commit) lorsque survient l'ʹincident: on applique toutes les modifications en-‐-
registrées dans le fichier redo log à la base de données (rollforward); pour T2, on repart du point de
reprise.
• T3 et T5 ne sont pas validées (pas de commit) lorsque survient l'ʹincident, on remet les lignes des
tables concernées aux anciennes valeurs (rollback).
2.3 La gestion de la concurrence
La gestion des accès concurrents aux données permet d’éviter que la mise à jour simultanée des mê-‐-
mes données par plusieurs utilisateurs n’introduise pas des incohérences dans la base de données. On
dit que deux transactions sont concurrentes si elles accèdent simultanément aux mêmes données.
2.3.1 Accès concurrents et incohérence des données
V oici quelques problèmes classiques qui peuvent survenir avec des transactions concurrentes.
La perte de mise à jour
Il y a perte de mise à jour quand une transaction T2 vient écraser une écriture effectuée par T1.
Temps t1
t2
t3
t4
t5
t6
t7
Transaction T1 État de la base Transaction T2
lire(A)
…
A = A + 10
…
…
écrire(A)
…
A = 10
A = 20
A = 60
…
lire(A)
…
…
A = A+50
…
écrire(A)
Après une exécution séquentielle de T1 et T2 ou T2 et T1, on obtient A=70. Si les transactions sont exé-‐-
cutées de manière concurrentes, on obtient alors A=60. On a donc perdu la première mise à jour.
19Les lectures impropres
Supposons une transaction T2 qui lit une donnée A modifiée par T1. La transaction T1 est annulée et
les modifications effectuées par cette transaction sont défaites. La valeur lue et traitée par T2 est alors
incorrecte.
Temps Transaction T1 État de la base Transaction T2
t1
t2
t3
t4
t5
lire(A)
A = A +20
écrire(A)
…
rollback
A = 10
A = 30
A = 10
…
…
…
lire(A)
…
Les lectures non reproductibles
La transaction T2 lit la même donnée A à deux instants différents et n'ʹobtient pas la même valeur. En-‐-
tre les deux lectures, une autre transaction a modifié la valeur de A.
Temps Transaction T1 État de la base Transaction T2
t1
t2
t3
t4
t5
A = 10
…
lire(A)
A = A + 10
écrire(A)
commit
A = 20
lire(A)
…
…
…
lire(A)
2.3.2 Le mécanisme de verrouillage
Les principales techniques mises en œuvre pour le contrôle de l’exécution concurrente des transac-‐-
tions reposent sur le concept de verrouillage des données. Un verrou est une variable associée à une
donnée qui décrit l’état de la donnée, compte tenu des opérations qui peuvent lui être appliquées.
Ainsi, avant d'ʹaccéder à une donnée pour modifier sa valeur, la transaction T1 doit la verrouiller pour
éviter son accès par une autre transaction. Une fois terminée, la transaction T1 libère alors les données
verrouillées pour les rendre disponibles à d'ʹautres transactions.
Nous reprenons l'ʹexemple du transfert d'ʹune somme d'ʹargent entre deux comptes: T1 fait un transfert
de c1 vers c2, T2 de c1 vers c3.
T1 T2
lock(c1)
read(c1) for update
c1:=c1-‐-m1 T2 attend la libération de c1
écrire(c1) (demande accès pour update de c1)
lock(c2) "ʺ
read(c2) for update "ʺ
c2:=c2+m1 "ʺ
écrire(c2) "ʺ
unlock(c1,c2) lock(c1)
read(c1) for update
c1:=c1-‐-m2
écrire(c1)
lock(c3)
read(c3) for update
c3:=c3+m2
écrire(c3)
20unlock(c1,c3)
Le verrouillage tel qu'ʹil est appliqué ci-‐-dessus permet d'ʹéliminer les pertes de mise à jour et les lectu-‐-
res impropres. Par contre, il ne permet pas d'ʹéliminer les lectures non reproductibles.
Les verrous classiques sont les verrous binaires, c’est-‐-à-‐-dire des verrous qui peuvent avoir deux va-‐-
leurs distinctes: verrouillé ou non verrouillé (1 ou 0). Un verrou est associé à chaque élément X. Si la
valeur du verrou sur X est 0, alors il est possible d’accéder à l’élément. Le verrouillage binaire utilise
deux opérations: verrouillerÉlément et déverrouillerÉlément. Une transaction demande l’accès à
un élément X en exécutant pour commencer l’opération verrouillerÉlément(X). Si le verrou est à 1,
la transaction doit attendre. Si le verrou est à 0, le verrou est mis à 1, et la transaction est autorisée à
accéder à l’élément X. Lorsque la transaction n’a plus besoin d’utiliser l’élément, elle exécute une opé-‐-
ration déverrouillerÉlément(X) qui positionne le verrou à 0 afin que les autres transactions puis-‐-
sent accéder à X. Un verrou binaire applique donc une exclusion mutuelle sur une donnée.
On se rend compte rapidement que les verrous binaires sont trop restrictifs pour les bases de données,
car certaines transactions ne veulent que lire certaines données. On distingue donc deux types de ver-‐-
rous, les verrous partagés, qui permettent à plusieurs transactions de lire une donnée verrouillée par
une transaction, et les verrous exclusifs, qui permettent à la transaction qui a posé le verrou d’effec-‐-
tuer une opération d’écriture.
2.3.3 Le risque d'ʹinterblocage
Un interblocage (ou verrou mortel) survient lorsque chaque transaction T d’un ensemble de n (n ≥ 2)
transactions attend une donnée verrouillée par une autre transaction T’ de l’ensemble. Autrement dit,
T1 attend une donnée verrouillée par T2, et T2 attend une donnée verrouillée par T1.
EXEMPLE : transfert entre deux comptes.
T1 transfère une somme m d’un compte c1 vers un compte c2, et T2 transfère une somme n de c2 vers
c1. L'ʹexécution simultanée des deux transactions conduit à la situation suivante :
T1 T2
lock(c1)
read(c1)
c1:=c1+m lock(c2)
écrire(c1) read(c2)
c2:=c2+n
T1 attend libération de c2 "ʺ écrire(c2)
T2 attend libération de c1
"ʺ "ʺ
"ʺ "ʺ
Les données sont verrouillées en fonction des demandes de mises à jour, mais ne sont libérées qu’en
fin de transaction
2.3.4 Résolution de l'ʹinterblocage (deadlock)
Une approche pratique de la gestion des interblocages repose sur la détection de ceux-‐-ci: le système
vérifie s’il y a une situation d’interblocage. Un procédé pour détecter une situation d’interblocage con-‐-
siste pour le système à construire et à maintenir un graphe d’attente des ressources (wait-‐-for graph).
Dans ce graphe, un nœud est créé pour chaque transaction en cours d’exécution. Chaque fois qu’une
transaction Ti attend de pouvoir verrouiller une donnée X verrouillé par une transaction Tj, un arc est
créé entre les deux transactions. Il y a situation d’interblocage si et seulement si il existe un cycle dans
le graphe. Il se pose alors le problème de savoir quand le système doit vérifier la présence d’un inter-‐-
blocage (nombre de transactions, durée d’attente de plusieurs transactions,…). Si le système détecte
l’interblocage, il tue une (ou plusieurs) des transactions impliquées. Il existe différentes solutions pour
le choix de la transaction à tuer : la plus récente, celle qui a fait le moins de mises à jour … D’autres
solutions plus élaborées peuvent être utilisées, mais ne seront pas traitées dans le cadre de ce cours.
Une autre possibilité pour gérer les interblocages consiste à employer des mises hors délais (timeouts).
21Cette méthode est pratique en raison du peu d’activité qu’elle implique sur le système. Si une transac-‐-
tion attend plus longtemps que la durée spécifiée pour la mise hors délai, le système suppose qu’elle
est bloquée et il tue cette transactions, qu’il y ait ou non interblocage.
La détection des interblocages
Pour détecter les interblocages, on construit le graphe d’attente des ressources :
X
T1 T2
Y
X, Y ,… représentent des éléments des tables de la base. T1, T2 …. identifient des transactions. Un arc
orienté étiqueté X ou Y entre Ti et Tj signifie que la transaction Ti attend la libération de X ou Y . L'ʹin-‐-
terblocage se traduit par un circuit dans le graphe d’attente des ressources, comme dans la figure ci-‐-
dessus.
RAPPEL: l'ʹinterblocage peut mettre en jeu n (n≥2) transactions.
X T2
T1
Y
Z
T3
2.3.5 Niveaux d'ʹisolation
SQL définit quatre niveaux d’isolation qui permettent de choisir quelles sont les types d’interactions
autorisées pour les transactions qui s’exécutent simultanément (concurrentes). Ainsi, dans une trans-‐-
action, on peut utiliser l’instruction suivante:
SET TRANSACTION ISOLATION LEVEL X
où X = SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED
T ransactions de niveau serializable
Si on reprend l’exemple de la section 4.1.5, et si on suppose que Paul = (max)(min) et Jo = (del)(ins)
sont des transactions, et si Paul utilise le niveau d’isolation SERIALIZABLE, alors il verra la base dans
l’état soit avant les modifications de Jo, soit après, mais pas entre les deux opérations de la transaction
de Jo.
Le niveau d'ʹisolation est un choix qui affecte uniquement la vue de la base de la transaction que le
spécifie. Si on reprend notre exemple (cf section 4.1.5), si Jo choisit le niveau SERIALIZABLE, mais pas
Paul, alors Paul peut éventuellement ne voir aucun prix si la requête est exécutée entre (del) et (ins).
T ransactions de niveau repeatable read
Seules les données validées peuvent être lues, ce qui implique que les lectures répétées dans une
même transaction retourne les mêmes valeurs (pas de phénomène de lectures non reproductibles).
Cependant, une transaction pourra voir apparaître au cours des lectures répétées de nouveaux n-‐-u-‐-
plets (ou des n-‐-uplets qui ont disparu).
Sur notre exemple, si Paul a choisi le niveau REPEATABLE READ, et que l’ordre d’exécution est
(max)(del)(ins)(min), alors (max) verra les prix 2,50 et 3,00, et (min) verra 3,50, mais également 2,50 et
3,00 car ils ont été vus par la lecture précédente de (max) dans la transaction.
T ransactions de niveau read committed
Seules les données validées peuvent être lues, mais des lectures successives peuvent renvoyer des va-‐-
leurs (validées) différentes. Cela permet de voir les modifications apportées par d’autres transactions.
22Sur notre exemple, si Paul a choisi le niveau READ COMMITTED, alors il peut voir les valeurs validées,
mais pas nécessairement les mêmes à chaque requête. Ainsi, avec READ COMMITTED, l’entrelacement
(max)(del)(ins)(min) est autorisé, aussi longtemps que Jo valide (mais Paul peut voir MAX < MIN).
T ransactions de niveau read uncommitted
Une transaction qui s’exécute en niveau d’isolation READ UNCOMMITTED peut voir des données dans la
base qui ne sont pas validées par une autre transaction (et qui ne le seront peut-‐-être jamais).
Sur notre exemple, si Paul a choisi le niveau READ UNCOMMITTED, il pourra voir le prix 3,50, même si Jo
abandonne la transaction.
2.3.6 V errouillage et niveaux de granularité
Les performances du contrôle de la concurrence est affectée par la taille des éléments à verrouiller. Par
exemple, dans une base de données, on a la valeur d’un attribut d’un n-‐-uplet, un n-‐-uplet, une table, ou
toute la base. Selon que l’on pose un verrou sur un élément particulier, on peut bloquer ou non plu-‐-
sieurs transactions. En particulier, il faut remarquer que plus la taille des éléments à verrouiller est
importante, plus le degré de concurrence autorisé est faible. Par exemple, si une transaction veut blo-‐-
quer toute une table (et si elle ne souhaite accéder qu’à un n-‐-uplet particulier), toutes les autres trans-‐-
actions seront mises en attente alors qu’il n’est peut être pas nécessaire de bloquer toute la table. In-‐-
versement, si on verrouille des éléments de taille plus petite, il peut y avoir beaucoup d’éléments à
verrouiller, et donc le gestionnaire de verrouillage devra gérer un plus grand nombre de verrous
(beaucoup d’opérations de verrouillage/déverrouillage). La nature des verrous à poser dépend donc
de la nature des transactions. Par exemple, si une transaction accède à un petit nombre d’enregistre-‐-
ments, il est préférable que la granularité soit l’enregistrement. Par contre, si une transaction accède à
de nombreux enregistrements d’une même table, alors la granularité qui semble la plus appropriée
semble être la table.
2.4 Le verrouillage sous Oracle
2.4.1 Principe
Oracle implante un verrouillage au niveau de la ligne, et utilise un mécanisme appelé Read consistency
(lecture cohérente). Grâce à ce mécanisme, les mises à jour et les lectures ne se bloquent pas mutuel-‐-
lement. Toutes les données retournées par un SELECT proviennent d’un seul point dans le temps. On
ne voit que les données validées au moment du SELECT. Pour les données non validées, on voit les
anciennes valeurs (grâce au Rollback segment). Les données modifiées par une autre transaction après
le début du SELECT ne sont pas vues.
Il existe une concurrence d’accès en mise à jour: la première transaction qui accède à une donnée posi-‐-
tionne un verrou sur les données accédées (n-‐-uplets ou tables), les autres transactions souhaitant accé-‐-
der les mêmes données seront mises en attente.
Ce mécanisme ne prend pas en compte les lectures non reproductibles. On peut, pour résoudre ce
problème, utiliser une transaction spéciale appelée une transaction à lecture seulement (Read Only
T ransaction). Cette transaction conserve, lorsqu'ʹelle démarre, l’état de la base et travaille ensuite uni-‐-
quement sur cet état, jusqu'ʹà la fin de la transaction. Une telle transaction ne doit comporter que des
lectures de la base, et les modifications des données de la base sont interdites. La syntaxe est:
SET TRANSACTION READ ONLY
instruction 1
…
instruction n
COMMIT
2.4.2 Niveaux d’isolation
En fixant le niveau d’isolation des transactions, on définit le mode de fonctionnement en parallèle des
différentes transactions qui s’exécutent au même moment. La commande suivante indique le niveau
d’isolation de la transaction qui vient de commencer :
23SET TRANSACTION ISOLATION LEVEL {SERIALIZABLE | READ COMMITTED}
Oracle permet deux niveaux d’isolation des transactions les unes par rapport aux autres :
• READ COMMITTED : c’est le mode par défaut des transactions d’Oracle. Il empêche les principaux
problèmes de concurrence mais pas les lectures non reproductibles. Tout d’abord, les modifications
effectuées par une transaction ne sont connues des autres transactions que lorsque la transaction a
été confirmée (COMMIT). Oracle gère automatiquement les accès concurrents de plusieurs transac-‐-
tions sur les mêmes n-‐-uplets de table. Si une transaction est en train de modifier des n-‐-uplets d’une
table, les autres transactions peuvent lire les données telles qu’elles étaient avant ces dernières mo-‐-
difications, mais les autres transactions sont bloquées automatiquement par Oracle si elles souhai-‐-
tent modifier ces mêmes lignes.
• SERIALIZABLE : si une transaction SERIALIZABLE essaie de modifier une donnée qui pourrait avoir
été modifiée par une autre transaction non validée au début de la transaction SERIALIZABLE, alors
l’ordre de modification échoue (résolution du problème de lecture non reproductibles). Ce mode est
coûteux puisqu’il limite le fonctionnement en parallèle des transactions (les transactions s’exécutent
concurremment comme si elles s’exécutaient les unes après les autres).
2.4.3 Différents niveau de verrouillage
V errouillage de niveau n-‐-uplet
Par défaut, Oracle met en œuvre un verrouillage de niveau n-‐-uplet, c’est-‐-à-‐-dire une stratégie de ver-‐-
rouillage au niveau des n-‐-uplets, chaque n-‐-uplet d’une table pouvant être verrouillé individuellement.
Les n-‐-uplets verrouillés peuvent alors être mis à jour uniquement par la transaction qui les a ver-‐-
rouillés. Tous les autres n-‐-uplets de la table peuvent être mis à jour par d’autres transactions. De plus,
les autres transactions gardent également la possibilité de lire les n-‐-uplets, y compris ceux qui sont mis
à jour. Pour ces derniers, les transactions ont accès à l’ancienne valeur (grâce au rollback segment) jus-‐-
qu’à ce que la transaction soit validée (lecture cohérente).
Lorsqu’une transaction pose un verrou sur un n-‐-uplet, Oracle effectue les opérations suivantes:
• Premièrement, un verrou DML (data manipulation language) est posé. Ce verrou évite que d’autres
transactions puissent mettre à jour (ou poser un verrou) sur le n-‐-uplet. Ce verrou ne sera relâché que
lorsque la transaction qui a posé le verrou aura été validée ou annulée,
• Deuxièmement, un verrou DDL (data dictionary language) est posé sur la table afin d’éviter les modifi-‐-
cations structurelles de la table (suppression de la table, retrait ou ajout d’un attribut,…). Ce verrou
ne sera relâché que lorsque la transaction qui a posé le verrou aura été validée ou annulée.
V errouillage de niveau T able
Avec le verrouillage au niveau table, la table entière est verrouillée. Dès qu’une transaction a ver-‐-
rouillé une table, seule cette transaction peut mettre à jour (ou verrouiller) n’importe quel n-‐-uplet de la
table. Aucun des n-‐-uplets de la table ne peut être mis à jour par une autre transaction. Cependant, les
autres transactions peuvent malgré tout lire n’importe quel n-‐-uplet, y compris ceux qui sont mis à
jour.
Relâcher les verrous
Souvent, les utilisateurs pensent être seuls au monde. C’est précisément ce genre de comportement
qui crée les problèmes de blocage. Souvenez-‐-vous que poser un verrou (sur un n-‐-uplet ou sur une ta-‐-
ble) n’est pas une opération anodine, et que cela peut bloquer beaucoup d’autres transactions. C’est
pourquoi il faut veiller à verrouiller de manière approprié, c’est-‐-à-‐-dire qu’il faut protéger uniquement
la partie de votre transaction qui est critique (mise à jour, calcul d’une moyenne, somme,…), et qu’il
faut également relâcher le verrou. Il faut donc être conscient que l’on relâche un verrou en validant
(COMMIT) ou en annulant (ROLLBACK) la transaction.
2.4.4 Les différents modes de verrouillage
Oracle propose deux modes de verrouillage:
24• le mode exclusif (X) qui empêche les ressources verrouillées d’être partagées. C’est le mode
privilé-‐- gié pour mettre à jour des données. La transaction qui pose un verrou exclusif la
première est la seule transaction qui peut modifier la table, et ce jusqu’à ce que le verrou soit
relâché.
• le mode partagé (S) permet à une ressource d’être partagée. Plusieurs transactions peuvent avoir
un verrou partagé et peuvent ainsi éviter qu’une autre transaction obtienne un verrou exclusif.
Oracle gère les types de verrous suivants: row share (RS), row exclusive (RX), share (S), share
row exclusive (SRX), et exclusive (X).
V errous exclusifs
SQL V errou
SELECT … FROM table… pas de verrou
INSERT INTO table… RX
UPDATE table… RX
DELETE FROM table… RX
LOCK TABLE table IN ROW EXCLUSIVE MODE RX
LOCK TABLE table IN SHARE ROW EXCLUSIVE MODE SRX
LOCK TABLE table IN EXCLUSIVE MODE X
V errous partagés
SQL V errou
SELECT … FROM table FOR UPDATE OF… RS
LOCK TABLE table IN ROW SHARE MODE RS
LOCK TABLE table IN SHARE MODE S
LOCK TABLE table IN SHARE ROW EXCLUSIVE MODE SRX
2.5 JDBC et les transactions
2.5.1 JDBC = Java DataBase Connectivity
JDBC est une API d’accès aux systèmes de gestion de base de données relationnelles qui permet
d’exécuter des requêtes SQL au sein d’un programme Java et de récupérer les résultats, ce qui
représente une alternative aux solutions propriétaires. C’est de plus une tentative de standardiser
l’accès aux bases de données car l’API est indépendante du SGBD choisi, pourvu que le pilote
JDBC existe pour ce SGBD, et qu’il implémente les classes et interfaces de l’API JDBC.
Pour effectuer un traitement avec une base de données, il faut :
1. charger un pilote en mémoire,
2. établir une connexion avec la base de données,
3. récupérer les informations relatives à la connexion,
4. exécuter des requêtes SQL et/ou des procédures stockées,
5. récupérer les informations renvoyées par la base de données (si nécessaire),
6. fermer la connexion.
Pour plus de détails, consulter le polycopié sur JDBC.
252.5.2 Gestion des transactions
L’instance de l’objet Connection fournit les méthodes pour :
Activer/désactiver la validation automatique de chaque requête passée (activé par défaut) :
public void setAutoCommit(boolean autoCommit) throws SQLException;
Valider manuellement la/les requête(s) passée(s) :
public void commit() throws SQLException;
Annuler les dernières modifications faites par la/les requête(s) passée(s) :
public void roolback() throws SQLException;
Exemple :
String sql1 = "UPDATE vendeur SET sal = 1215 WHERE sal < 1215";
String sql2 = "DELETE FROM vendeur WHERE sal < 1215";
try {
[Link](false);
Statement state = [Link]();
[Link](sql1);
Statement state2 = [Link]();
[Link](sql2);
[Link]();
...
} catch (Exception e) {
try{
[Link]();
} catch (SQLExection e) {
...
}
...
}
JDBC supporte le mode transactionnel qui consiste à valider tout ou une partie d’un ensemble
d’instructions. Nous avons déjà décrit à la section « Interface Connection » les méthodes qui
permettent à un programme Java de coder des transactions (setAutoCommit, commit et rollback).
Par défaut, chaque instruction SQL est validée (on parle d’autocommit). Lorsque ce mode est
désactivé, il faut gérer manuellement les transactions avec commit ou rollback.
Quand le mode autocommit est désactivé :
La déconnexion d’un objet Connection (par la méthode close) valide implicitement la
transaction (même si commit n’a pas été invoqué avant la déconnexion).
Chaque instruction (CREATE, ALTER, DROP) valide implicitement la transaction.
26
CHAPITRE 1: BASES DE DONNÉES RELATIONNELLES
1. Les Systèmes de Gestion de Bases de Données (SGBD)
2. Introduction à la conception de bases de données relationnelles
3. Décomposition de schémas relationnels
4. Normalisation des relations
5. Dépendances fonctionnelles et conception de schémas
1.1 Les Systèmes de Gestion de Bases de Données (SGBD)
Un système de base de données peut être décrit par l’équation suivante:
Système de Base de Données = Base de Données + SGBD
Un SGBD est un système permettant de gérer et de manipuler la base de données, et une base de
données est une collection de données en relation qui sont:
1. partagées par de multiples applications (utilisateurs et/ou programmes),
2. stockées avec une redondance minimum,
3. indépendantes des applications,
4. organisées afin d’être une fondation pour de futures applications.
Le modèle de données est le formalisme qui décrit la structure logique de la base de données et les
opérations sur celle-‐-ci.
Le schéma de base de données est la structure de la base de données. L’instance de la base de don-‐-
nées est le contenu actuel de la base de données.
Une base de données est donc constituée d’une part d’un schéma de base de données et d’une instance de
la base de données d’autre part. On peut, par analogie avec les langages de programmation, définir les
correspondances suivantes:
modèle de données schéma ↔ ↔ instance ↔ variable
langage de programmation
déclaration d’une structure de données
1.1.1 Modèle de Données Relationnel
Une instance de la base de données peut être considérée comme une collection de relations mathéma-‐-
tiques. Chaque relation est représentée par une table dont chaque colonne est appelée un attribut et
chaque ligne est appelée un tuple ou n-‐-uplet. On associe à chaque attribut un ensemble de valeur, ap-‐-
pelé domaine.
Un schéma de relations est alors défini comme un ensemble d’attributs.
EXEMPLE
EMPLOYÉ = {nom, nosécu, nomdépartement, salaire, datenaissance}
CONVENTION DE NOTATION
EMPLOYÉ (nom, nosécu, nomdépartement, salaire, datenaissance)
Un schéma de base de données est une collection de schémas de relations.
EXEMPLE
{ EMPLOYÉ, DÉPARTEMENT, PROJET }
NOTATIONS
schéma de relations R R(A1,A2,...,An)
n-‐-uplet <v1,v2,...,vn>
valeur de l’attribut Ai t[Ai]
valeurs des attributs t[Au,Aw,...Az]
attribut A du schéma R R.A
11.1.2 Contraintes d’intégrité
Il existe un certain nombre de propriétés qui doivent être respectées pour chaque instance d’un sché-‐-
ma de relations ou d’un schéma de base de données afin de préserver la cohérence des informations
stockées dans la base. Ces propriétés sont appelées contraintes d’intégrité.
Les dépendances entre données sont des contraintes d’intégrité qui spécifient les relations entre les
valeurs des attributs. Elles sont très utiles dans la conception de bases de données.
1.2 Introduction à la conception de bases de données relationnelles
1.2.1 Deux approches pour concevoir un schéma de base de données
Il existe deux approches pour concevoir un schéma de base de données: une approche descendante,
également appelée méthode par décomposition, et une approche ascendante, également appelée mé-‐-
thode synthétique. Nous présentons rapidement pourquoi la conception d’un schéma de base de don-‐-
nées peut être présenter des anomalies. Les dépendances fonctionnelles sont un outil théorique qui
permet de vérifier la qualité de conception d’un schéma et de comprendre les conséquences de la re-‐-
dondance de données.
1. Conception descendante (top-‐-down design)
On part d’un schéma de relations unique…
décomposition basée sur les dépendance entre données
(par exemple, les dépendances fonctionnelles)
…pour obtenir une collection de schémas de relations.
2. Conception ascendante (bottom-‐-up design)
On part d’une collection d’attributs…
synthèse (regroupement)
…pour obtenir une collection de schémas de relations.
QUESTIONS
• Quelles sont les propriétés intéressantes d’un schéma de base de données relationnelles ?
– mesure de la qualité du schéma,
– méthodologie de conception.
• Quels sont les algorithmes permettant d’obtenir un schéma possédant les bonnes propriétés ?
– outil dédié à la conception,
– conception automatique.
MESURE DE LA QUALITÉ
1. sémantique des attributs
Plus il est facile d’expliquer la sémantique des attributs d’une relation, plus la conception du
schéma de relations est bonne.
PRINCIPE 1: concevoir un schéma de relations de telle sorte qu’il soit simple d’expliquer ce
qu’il représente.
EXEMPLE
Que signifie FOURNIT (f#, nom, adresse, p#, produit, prix, couleur, nomproj, dép) ?
Ce schéma de relations doit être décomposé comme suit:
PROD(p#, produit, couleur)
FOURNITPROD(f#, nom, adresse,p#, produit, prix)
PROJET(nomproj, dép)
UTILISE(nomproj, p#)
Chaque schéma de relations et chaque attribut ont une sémantique précise.
22. les informations redondantes
Les informations redondantes, à l’origine de problèmes, doivent être supprimées dans la me-‐-
sure du possible.
PRINCIPE 2: concevoir un schéma de relations de telle manière que les insertions, les suppres-‐-
sions et les mises à jour ne posent pas de problèmes.
EXEMPLE
Si on utilise la relation suivante FOURNITPROD(f#, nom, adresse, p#, produit, prix) plutôt
que le schéma de relations suivant:
FOURNISSEUR(f#, nom, adresse)
FOURNIT(f#, p#, prix)
alors le nom et l’adresse d’un fournisseur sont stockés plusieurs fois dans les n-‐-uplets corres-‐-
pondant aux produits vendus par le fournisseur.
QUAND Y-‐-A-‐-T-‐-IL REDONDANCE D’INFORMATION ?
On constate assez facilement que la même adresse apparaît autant de fois qu’il y aura de produits si
l’on utilise la relation FOURNITPROD(f#, nom, adresse, p#, produit, prix). Or on sait qu’un fournis-‐-
seur ne possède qu’une seule adresse et cela même s’il vend plusieurs produits. On appelle cette
propriété une dépendance fonctionnelle. Un mauvais schéma relationnel peut alors entraîner des
anomalies lors des manipulations.
f# nom Labaleine Lemelon adresse p# produit prix
F1 Paris P1 parapluie 110
F2 Lyon P2 chapeau 50
F3 Toutcuir Lyon P3 sac à main 650
F1 Labaleine Paris P4 parasol 150
F1 Labaleine Paris P5 ombrelle 70
F4 Letour Nantes P6 ceinture 55
F5 P3 650
Legrand Paris sac à main Dans la relation ci-‐-dessus, il existe des redondances qui peuvent engendrer les difficultés
suivantes:
• anomalie d’insertion. Telle qu’elle se présente, cette relation ne permet pas de mémoriser dans
la base un produit dont le fournisseur n’existe pas.
• anomalie de suppression. La disparition d’un fournisseur, qui est l’unique fournisseur d’un
produit, entraîne également la disparition des informations concernant ce produit (exemple:
Letour).
• anomalie de mise à jour. Toute modification sur le prix d’un produit qui apparaît plusieurs fois
dans la relation doit être répercutée sur tous les n-‐-uplets correspondants (exemple: sac à main).
Cela augmente le temps de mise à jour et les risques d’incohérence.
On résout ces problèmes en étudiant les dépendances entre les données, et en décomposant et norma-‐-
lisant les relations. On obtient ainsi des schémas de relations qui évitent les anomalies citées ci-‐-dessus.
Attention cependant à ne pas voir la normalisation comme un dogme. Il arrive parfois que, pour des
raisons d’efficacité notamment, on soit obligé de dénormaliser.
1.2.2 Dépendance Fonctionnelle (DF)
Soient R un schéma de relations, et X=A1,A2,…,An et Y=B1,B2,…,Bm des sous-‐-ensembles de R.
X détermine fonctionnellement Y , noté X → Y , ssi pour chaque instance r de la relation R, pour chaque
paire de n-‐-uplets t et s appartenant à r, t[X] = s[X] implique t[Y] = s[Y] (où t[X] désigne la projection du
n-‐-uplet t sur les attributs X).
Autrement dit, X → Y signifie qu’une valeur de X détermine au plus une valeur de Y.
3Une dépendance fonctionnelle est une propriété définie sur l'ʹintention du schéma et non son extension
(elle est donc invariante dans le temps et ne peut être extraite à partir d'ʹexemples). C'ʹest une propriété
qui doit être extraite de la connaissance que l'ʹon a de l'ʹapplication à modéliser et qui permet d’élimi-‐-
ner la redondance.
EXEMPLES
Considérons la relation suivante
FILM (titre, année, durée, type, studio, acteurPrincipal)
avec une instance de la relation contenant les n-‐-uplets suivants:
titre année durée type studio acteurPrincipal
StarWars 1977 124 couleur Fox Carrie Fisher
StarWars 1977 124 couleur Fox Mark Hamill
StarWars 1977 124 couleur Fox Harrison Ford
1991 104 couleur Disney Emilio Estevez
1991 95 couleur Paramount Dana Carvey
1992 95 couleur Paramount Mike Meyers
Mighty Ducks Wayne’s World Wayne’s World On peut en déduire les trois DF suivantes:
{titre, année} → durée
{titre, année} → type
{titre, année} → studio
Par contre, la dépendance suivante n’est pas une DF:
{titre, année} → acteurPrincipal
En effet, étant donné un film, il peut exister dans la base (telle qu’elle est modélisée) plusieurs acteurs
principaux.
Enfin, la DF {titre, année} → durée signifie qu’il ne peut exister dans une instance de FILM les deux n-‐-
uplets suivants:
titre année durée type studio acteurPrincipal
Farenheit, 9/11 2004 124 couleur Fox Georges Bush
Farenheit, 9/11 2004 130 couleur Fox Dick Cheney
CONVENTIONS
• L’ensemble de DF suivant:
{A1,A2,…,An} → B1
{A1,A2,…,An} → B2
…
{A1,A2,…,An} → Bm
est équivalent à {A1,A2,…,An} → B1,B2,...,Bm.
41.2.3 Propriétés des DF
Les trois premières propriétés (réflexivité, augmentation et transitivité) sont également appelés axio-‐-
mes d’Armstrong. De ces trois axiomes, on peut en déduire trois autres propriétés (pseudo-‐-transitivité,
union et décomposition).
Si Y ⊆ X, alors on a X → Y
RÉFLEXIVITÉ
Si X → Y , alors on a X ∪ Z → Y ∪ Z
AUGMENTATION
TRANSITIVITÉ
PSEUDO-‐-TRANSITIVITÉ
Si X → Y et Y ∪ W → Z, alors X ∪ W → Z
Si X → Y et Y → Z, alors on a X → Z
Si X → Y et X → Z, alors X → Y ∪ Z
UNION
Si X → Y et Z ⊆ Y , alors X → Z
DÉCOMPOSITION
• les n-‐-uplets de la relation S sont la projection sur {B1,B2,…,Bm} de tous les n-‐-uplets de R. La pro-‐-
jection est l’opération qui consiste à construire la nouvelle relation S à partir de R en prenant
pour chaque n-‐-uplet t de R uniquement les attributs {B1,B2,…,Bm} et en éliminant les n-‐-uplets en
double,
• de manière similaire, les n-‐-uplets de la relation T sont la projection sur {C1,C2,…,Ck} de tous les n-‐-
uplets de R.
La décomposition de la relation R en R1,R2,…,Rn est sans perte si la jointure des relations R1,R2,…,Rn
permet de retrouver tous les n-‐-uplets de la relation R d’origine. La jointure est l’opération qui permet
de construire une nouvelle relation à partir de deux relations ayant au moins un attribut commun.
EXEMPLE
On peut décomposer la relation FILM définie précédemment en deux relations FILM1 et FILM2 telles
que:
FILM1 = (titre, année, durée, type, studio)
FILM2 = (titre, année, acteurPrincipal)
7Si on utilise la décomposition telle qu’elle est définie, on obtient au niveau des n-‐-uplets pour FILM1 et
FILM2 les résultats suivants:
titre année durée type studio
StarWars 1977 124 couleur Fox
Mighty Ducks 1991 104 couleur Disney
titre année acteurPrincipal
StarWars 1977 Carrie Fisher
StarWars 1977 Mark Hamill
StarWars 1977 Harrison Ford
1991 Emilio Estevez
1991 Dana Carvey
1992 Mike Meyers
Mighty Ducks Wayne’s World Wayne’s World On peut remarquer que cette décomposition élimine les problèmes
soulevés au paragraphe 1.2.1. La
redondance est éliminée, par exemple la durée de chaque film n’apparaît qu’une fois, dans la relation
FILM1. Le risque d’anomalie de mise à jour a ainsi disparu. De même, le risque d’anomalie de sup-‐-
pression a disparu. Si on supprime tous les acteurs du film Wayne’s World, le film disparaît égale-‐-
ment. Il apparaît que FILM2 possède malgré tout de la redondance, puisque titre et année apparais-‐-
sent plusieurs fois. Cependant, ces deux attributs forment une clé, et il n’est pas possible de représen-‐-
ter plus succinctement un film.
1.4 Normalisation des relations
Les formes normales de schémas de relations sont des propriétés souhaitables que doit posséder cha-‐-
que schéma de relations. Elles sont nécessaires (mais non suffisantes) pour une « bonne » conception.
Historiquement, les formes normales suivantes ont été proposées (de la moins restrictive à la plus res-‐-
trictive).
Première Forme Normale (1NF)
Deuxième Forme Normale (2NF)
Troisième Forme Normale (3NF)
Forme Normale de Boyce and Codd (BCNF)
Quatrième Forme Normale (4NF)
Cinquième Forme Normale (5NF)
Les formes normales définissent un ordre partiel sur les schémas de relation. On peut donc voir une
forme normale comme une classe d'ʹéquivalence (on peut comparer deux schémas dans deux classes
d'ʹéquivalence différentes mais pas dans la même). Il faut aussi noter que le seul élément qui est pris en
compte par les formes normales est la non redondance d'ʹinformations d'ʹun schéma. Selon les formes
normales, un « bon » schéma est un schéma sans redondance (ce qui ne veut pas forcément dire qu'ʹil
est efficace par exemple). Un schéma relationnel sans qualité particulière est appelé schéma en 1ère
forme normale (on note 1NF) et si on rajoute certaines qualités on obtient les deuxième et troisième
formes normales (on note 2NF et 3NF).
On ne présente ici que les formes normales dont la définition utilise exclusivement les dépendances
fonctionnelles. Si on prend en compte d'ʹautres dépendances entre données comme les dépendances
multivaluées, on obtient alors les 4NF et 5NF. La BCNF reste cependant l'ʹobjectif de normalisation le
plus « classique ».
1NF: une relation est en première forme normale ssi tout attribut a une valeur atomique (vrai par défi-‐-
nition du modèle relationnel).
82NF : une relation est en deuxième forme normale ssi elle est en 1NF et si tous les attributs non clés
sont pleinement dépendants des clés (toutes les dépendance entre une clé et un attribut non clé sont
des dépendances fonctionnelles élémentaires).
3NF : une relation est en troisième forme normale ssi elle est en 2NF et si tous les attributs non clés
sont directement et pleinement dépendants des clés (si tout attribut non clé ne dépend pas d'ʹun autre
attribut non clé).
BCNF (Boyce-‐-Codd) : une relation est en BCNF ssi elle est en 3NF et si les seules DFE sont celles de la
forme C → X avec C clé (seules les clés sont en partie gauche de DF).
1.4.1 Première forme normale (1NF)
Une relation R est dite en première forme normale (1NF) si tous ses attributs sont atomiques et qu’il
n’existe pas d’attributs répétitifs. De plus, chaque attribut doit avoir une sémantique précise. V oyons
pourquoi la relation suivante n’est pas en première forme normale.
titre année durée type studio
StarWars 1977 124 couleur Fox, Los Angeles
Mighty Ducks 1991 104 couleur Disney , San Francisco
Wayne’s World 1992 95 couleur Paramount, Los Angeles
Les attributs de cette relation ne sont pas atomiques. En effet, l’attribut studio contient à la fois le nom
et la ville, ce qui est gênant si l’on souhaite extraire tous les studios situés à Los Angeles.
Analysons maintenant un deuxième exemple. La relation suivante n’est pas non plus en 1NF.
titre année acteur1 acteur2 acteur3
StarWars 1977 Carrie Fisher Mark Hamill Harrison Ford
Mighty Ducks 1991 Emilio Estevez
Wayne’s World 1992 Dana Carvey Mike Meyers
En effet, la première forme normale stipule que les attributs ne doivent pas être répétitifs. Or, la liste
des acteurs ne respecte pas cette propriété. Si on veut rechercher dans quel film a joué Harrison Ford,
on est obligé non seulement de parcourir tous les n-‐-uplets, mais également toutes les colonnes. De
plus, si l’on souhaite rajouter un quatrième acteur, il faut modifier la relation toute entière.
Enfin, que pensez-‐-vous de la relation suivante:
titre année durée type studio
StarWars 1977 124 SF Fox
Mighty Ducks 1991 104 couleur Disney
Wayne’s World 1992 95 couleur Paramount
Il semble que cette relation soit en 1NF. Les attributs sont atomiques, il n’y a pas d’attributs répétitifs.
Malgré tout, l’attribut type ne possède pas une sémantique claire, représentant soit un genre (SF), soit
le type de la pellicule. Cette relation n’est donc pas en 1NF.
1.4.2 Deuxième forme normale (2NF)
Une relation R est dite en deuxième forme normale (2NF) ssi
• elle est en 1NF,
• tout attribut n’appartenant pas à une clé ne dépend pas d’une partie de cette clé (pas de dépen-‐-
dances partielles).
Autrement dit, dès qu’un attribut non clé dépend d’une partie d’une clé, la relation n’est pas en 2NF.
9V oyons dans un premier temps un exemple abstrait. La relation R(A,B,C) munie de l’ensemble F des
dépendances est en 1NF mais pas en 2NF.
A,B → C
B →C
Regardons maintenant sur un exemple concret. Considérons la relation suivante:
numSalarié nom numProjet heures
20036 Durand 1 18,5
20036 Durand 2 6,7
36900 Leroux 2 8,5
45002 Franck 3 23,5
45002 Franck 1 4,8
L’ensemble F des DF est:
numSalarié → nom
numSalarié,numProjet → heures
La relation n’est pas en 2NF. En effet, la clé minimale de cette relation est {numSalarié,numProjet}.
L’attribut non clé heure est en totale dépendance fonctionnelle avec la totalité de la clé. Par contre,
l’attribut non clé nom dépend d’une partie de la clé, à savoir numSalarié. Pour que la relation soit en
2NF, il est nécessaire de scinder la relation initiale en deux relations, comme ceci:
numSalarié numProjet heures
20036 1 18,5
20036 2 6,7
36900 2 8,5
45002 3 23,5
45002 1 4,8
numSalarié nom
20036 Durand
36900 Leroux
45002 Franck
Chacune de ces deux relations répond désormais aux exigences de la première et de la deuxième
forme normale. La première relation a pour clé primaire l’attribut numSalarié, et la deuxième relation
a pour clé {numSalarié,numProjet}.
1.4.3 T roisième forme normale (3NF)
OBJECTIFS DE LA 3NF
1. élimination des dépendances partielles
S’il existe une dépendance partielle Y → A, où X est une clé minimale et Y un sous-‐-ensemble
de X, alors chaque n-‐-uplet utilisé pour associer une valeur X aux valeurs de A sera répété pour
les valeurs de Y (d’où redondance des informations).
La condition de la 3NF élimine cette possibilité, évitant ainsi les mises à jour incorrectes et la
redondance.
2. élimination des dépendances transitives
S’il existe une dépendance transitive X → Y → A, alors on ne peut associer une valeur Y à une
valeur X que s’il existe une valeur A associée à une valeur Y . Cela conduit à des problèmes
d’insertion et de suppression.
DÉFINITION
On considère les définitions suivantes:
R: un schéma de relations,
F: un ensemble de DF sur R,
X: un sous-‐-ensemble de R,
A: un attribut.
10On rappelle que A est un attribut clé ssi il fait partie d’une clé minimale de R et que dans le cas con-‐-
traire, A est appelé un attribut non clé.
La relation R est dite en troisième forme normale (3NF) ssi lorsque X → A est dans F+ et A n’est pas
dans X, soit X est une clé primaire, soit A est un attribut clé.
Il existe deux cas dans lesquels X → A ne respecte pas la 3NF:
Cas 1: X est un sous-‐-ensemble d’une clé minimale. X → A est une dépendance partielle.
Cas 2: X n’est pas un sous-‐-ensemble de toutes les clés minimales. X → A est une dépendance
transitive. Elle crée une chaîne non triviale de DF Z → X → A pour une clé minimale Z.
Autrement dit, une relation est dite en 3NF ssi:
• elle est en 2NF,
• il n’existe pas de dépendance entre attributs non clé.
EXEMPLE 1
R=ABCD
F = {AB → C,B → D,BC → A}
AB et BC sont des clés minimales et ce sont les seules. A, B et C sont des attributs clés. D est
un attribut non clé.
EXEMPLE 2
R=VRC R(ville, rue, code)
F = {VR → C,C → V}
R est en 3NF.
EXEMPLE 3
R=SAIP
F = {SI → P ,S → A}
SI est la seule clé, et A est un attribut non clé.
S → A ne respecte pas la 3NF, étant donné que S n’est pas une clé primaire. De plus, S → A est
une dépendance partielle.
On remarque dans cet exemple que la dépendance S → A est dans F. Cependant, en général,
les dépendances non conformes à la forme normale étudiée sont dans F+ plutôt que dans F.
1.4.4 Forme normale de Boyce-‐-Codd (BCNF)
OBJECTIFS DE LA BCNF
1. élimination des dépendances partielles,
2. élimination des dépendances transitives,
3. élimination des anomalies non prises en compte par la 3NF.
DÉFINITION
On considère les définitions suivantes:
R: un schéma de relations,
F: un ensemble de DF sur R,
X: un sous-‐-ensemble de R,
A: un attribut.
R est en BCNF ssi lorsque X → A appartient à F+ et que A n’est pas dans X, alors X est une clé
de R.
Une relation en 3NF qui ne possède qu’un seule clé minimale est en BCNF.
EXEMPLE 1
M=NAC MEMBRE(nom,adresse,cotisation)
F = {n → a, n → c}
M est en BCNF.
11EXEMPLE 2
R=VRC R(ville,rue,code)
F = {VR → C,C → V}
R est en 3NF mais pas en BCNF. Dans R, on ne peut pas stocker la ville correspondante à un
code à moins de connaître une rue associée à ce code (anomalie d’insertion). En effet, C → V
est vraie et V n’appartient pas à C, alors que C ne contient aucune des clés minimales de R.
1.5 Dépendances fonctionnelles et conception de schémas
Nous l’avons déjà abordé au paragraphe 1.2.1, il existe deux méthodes pour concevoir un schéma de
bases de données qui soit en 3NF: la méthode dite synthétique, et la méthode par décomposition.
1.5.1 La méthode synthétique
L’algorithme dit de synthèse permet dʹobtenir une décomposition 3NF qui préserve les DF. Il est basé
sur le calcul de la couverture minimale (ou irredondante) dʹun ensemble de DF. Le point de départ de
cette méthode est la connaissance des attributs et d’un ensemble de dépendances fonctionnelles. On
construit le graphe des DF dans lequel chaque attribut constitue un noeud, et chaque DF est représen-‐-
tée par un arc. L’algorithme de synthèse va travailler sur ce graphe et construire un ensemble de rela-‐-
tions en 3NF.
ALGORITHME DE SYNTHÈSE
Pour obtenir un schéma de relations en 3NF, on applique l’algorithme suivant:
1. on construit une couverture minimale à partir de l’ensemble F des DF,
2. on en déduit les relations en 3NF en regroupant dans une même relation tous les attributs ayant
la même partie gauche dans le graphe des DF,
3. si aucune des relations obtenues à l’étape précédente ne contient pas (ou ne permet pas d’obte-‐-
nir) la clé de la relation initiale, on ajoute une relation composée uniquement des attributs de la
clé.
EXEMPLE
Soit la relation GESPROD (numEmp, nomEmp, numProj, budProj, emploi, taux, nbhr) qui décrit la
gestion de projet dans une entreprise. Les attributs sont les suivants: le numéro d’employé, le nom de
l’employé, le numéro du projet, le budget du projet, l’emploi occupé par l’employé, le taux de rému-‐-
nération de l’employé, et le nombre d’heures de travail de l’employé sur un projet donné. La seule clé
minimale de la relation est constituée des attributs {numEmp, numProj}. L’ensemble F des DF est le
suivant:
numEmp → nomEmp
numEmp → emploi
emploi → taux
numEmp → taux
numProj → budProj
numEmp,numProj → nbHr
Pour obtenir une décomposition de GESPROD muni de F en un ensemble de relations en 3NF, on ap-‐-
plique lʹalgorithme suivant:
1. construction de la couverture minimale: on élimine les dépendances transitives:
numEmp → taux est une DF transitive car numEmp → emploi et emploi → taux.
2. déduction des relations en 3NF en regroupant dans une même relation tous les attributs ayant
même partie gauche dans F.
EMPLOYÉ (numEmp, nomEmp, emploi)
PROJET (numProj, budProj)
RÉMUNÉRATION (emploi, taux)
OCCUPE (numEmp, numProj, nbHr)
3. on vérifie que la clé est présente dans au moins une relation. Dans notre exemple, la relation
OCCUPE possède la clé de la relation initiale.
121.5.2 La méthode par décomposition
Une autre manière de concevoir un schéma relationnel en troisième forme normale est de partir du
schéma complet (ensemble de tous les attributs) et de décomposer cette « grosse » relation (appelée
également relation universelle) en respectant les dépendances fonctionnelles. Cette approche est appelée
approche par décomposition. Le problème est dʹordonner lʹordre des décompositions de manière à
obtenir un schéma en 3ème forme normale. En effet, chaque relation produite ne conserve qu’un cer-‐-
tain nombre de DF (celles définies sur ses attributs propres) et nʹest donc pas forcément en 3ème forme
normale. De plus, lʹensemble des DF du schéma complet nʹest pas forcément préservé.
ALGORITHME DE DÉCOMPOSITION
entrée: un schéma relationnel (ensemble dʹattributs) et un ensemble E de DF entre ses attri-‐-
buts
sortie: une ou plusieurs relations en 3NF dont la jointure redonne la relation initiale (par con-‐-
tre des DF de E ont pu être perdues)
principe: lʹalgorithme peut se voir comme la construction dʹun arbre binaire. La racine de cet
arbre est la relation à décomposer. Lʹarbre se construit récursivement de la manière suivante:
1. on choisit une DF dfi dans lʹensemble E des DF,
2. le fils gauche du noeud racine est une relation composé de tous les attributs de dfi,
3. dfi est retirée de lʹensemble E,
4. le fils droit du noeud racine est une relation composée de tous les attributs de la racine ex-‐-
cepté ceux présents en partie droite de dfi.
Problèmes: la solution dépend du choix des DF selon lesquelles on choisit de décomposer et il ne pré-‐-
serve pas nécessairement les DF.
On sait néanmoins que toute relation admet une décomposition en 3NF qui préserve les DF.
EXEMPLE
Soit la relation universelle associée à la gestion de production définie au paragraphe 1.5.1:
GESPROD (numEmp, nomEmp, numProj, budProj, emploi, taux, nbhr)
On constate quʹelle n
ʹest pas en 2NF car
numEmp → nomEmp, taux, emploi
numProj → budProj
Ceci conduit à une décomposition de la relation GESPROD en trois relations en 2NF:
PROJET (numProj, budProj)
OCCUPE (numEmp, numProj, nbHr)
EMPREM (numEmp, nomEmp, emploi, taux)
On constate que la relation EMPREM n
ʹest pas en 3NF car
emploi → taux (un attribut non clé dépend fonctionnellement dʹun autre attribut non clé)
On décompose la relation EMPREM en deux relations en 3NF
EMPLOYÉ (numEmp, nomEmp, emploi)
RÉMUNÉRATION (emploi, taux)
On obtient finalement quatre relations en 3NF
PROJET (numProj, budProj)
OCCUPE (numEmp, numProj, nbHr)
RÉMUNÉRATION (emploi, taux)
EMPLOYÉ (numEmp, nomEmp, emploi)
EXEMPLE SUR LES FORMES NORMALES
Soit le schéma R = (P , H, N, Y , T), et F = {P → T | P , H → Y | H, N → P | H, Y → N}.
• ensemble des DFE engendrées:
H, N → T
P, H →N
H,N → Y
13H, Y → P
P, H →T
H, Y → T
• on a donc trois clés potentielles (H, N | P , H | H, Y):
H, N → P , T, Y
P , H → T, Y , N
H, Y → N, P , T
• les attributs clés sont donc: H, N, P , Y , et un attribut non clé est T.
• par définition le schéma est en 1ère forme normale. Est il en 2NF ?
Non, car P , H → T n
’est pas une DFE (on a P → T), R est donc en 1NF.
• application de l’algorithme de décomposition:
R(P, H, N, Y, T)
P ! T
R1(P, T) Clé P (3NF) R2(P, H, N, Y)
Clés H,N ou P,H ou H,Y (3NF) R =
R1 * R2 (pas de perte des DFs)
14CHAPITRE 2: SÉCURITÉ DE FONCTIONNEMENT
1. Les transactions
2. La tolérance aux pannes
3. La gestion de la concurrence
4. Le verrouillage sous Oracle
5. JDBC et les transactions
2.1 Les transactions
2.1.1 Définition
L’objectif de ce chapitre est d’étudier les mécanismes que fournit un SGBD pour s’assurer que les don-‐-
nées demeurent dans un état cohérent, c’est-‐-à-‐-dire qu’elles ne sont pas mises en cause par un pro-‐-
blème logiciel ou matériel, ou par le fait que plusieurs utilisateurs manipulent les données simultané-‐-
ment. En effet, les SGBD sont utilisés par plusieurs utilisateurs simultanément, à la fois pour les requê-‐-
tes ou pour des modifications sur la base de données.
Par exemple, on suppose que deux personnes souhaitent retirer 100€ d’un même compte. Un SGBD
doit s’assurer qu’aucun des deux retraits ne soit perdu. Par comparaison avec un système d’exploita-‐-
tion, deux personnes peuvent très bien éditer le même fichier, mais c’est le dernier qui écrit qui voit
ses modifications conservées. Ce comportement n’est pas imaginable dans le contexte des bases de
données.
Pour résoudre ce problème, on a introduit le concept de transaction; Une transaction est un pro-‐-
gramme qui forme une unité logique de traitement. Elle est constituée d’une ou plusieurs opérations
d’accès aux objets de la base de données (insertion, suppression, modification ou lecture). Enfin, une
transaction fait passer la base d’un état cohérent E1 à un état cohérent E2. En particulier:
• une transaction doit commencer à partir d’un état cohérent de la base,
• pendant la transaction, la base peut éventuellement être dans un état incohérent,
• lorsque la transaction se termine avec succès, la base doit être dans un état cohérent,
• lorsqu’une transaction a été validée, les modifications sur la base sont persistantes, même en cas de
problèmes logiciels ou matériels,
• plusieurs transactions peuvent s’exécuter en parallèle.
On distingue deux problèmes à prendre en compte:
• la tolérance aux pannes: il faut restaurer la base dans l’état où elle se trouvait avant l’incident. Les mé-‐-
canismes utilisés sont les transactions, la tenue d’un journal, la reprise après panne.
• l'ʹexécution concurrente de plusieurs transactions: il faut veiller à ce que l’action simultanée de plusieurs
utilisateurs sur les mêmes données ne conduise pas à une incohérence de ces données. Les méca-‐-
nismes utilisés sont la gestion des accès concurrents, les transactions, le verrouillage et la gestion de
l’interblocage.
2.1.2 Propriétés ACID
Un SGBD supporte ce que l’on appelle des transactions ACID. Les propriétés ACID sont:
• atomicité : lors de l’exécution d’une transaction, soit toutes ses actions sont exécutées, soit aucune ne
l’est,
• cohérence : après une transaction, la base se trouve dans un état cohérent,
• isolation : il n’y a pas d’incohérence liée à la concurrence d’accès,
• durabilité : les effets d’une transaction correctement exécutée survivent à une panne ultérieure.
V oyons sur un exemple ce que cela signifie. On suppose une transaction qui effectue un transfert d’ar-‐-
gent (100€) d’un compte A vers un compte B:
1. lire(A) 4. lire(B)
2. A:= A –100 5. B := B + 100
3. écrire(A) 6. écrire(B)
15La propriété d’atomicité spécifie que si la transaction échoue après l’étape 3 et avant l’étape 6, le sys-‐-
tème doit s’assurer qu’aucune mise à jour n’aura été effectuée, sous peine de voir une incohérence
entre la balance des deux comptes.
La propriété de cohérence spécifie que la somme des soldes de A et B est inchangée après l’exécution
de la transaction.
La propriété d’isolation spécifie que si une autre transaction essaie d’accéder à la base entre les étapes
3 et 6, elle ne verra pas les modifications faites aux étapes 1 à 3. L’isolation peut être assurée de ma-‐-
nière triviale en exécutant les transactions en séquence (de manière sérialisable). Cependant, nous ver-‐-
rons que permettre l’exécution concurrente des plusieurs transactions apporte des avantages, à condi-‐-
tion de ne pas avoir d’interférences entre les transactions simultanées.
Enfin, la propriété de durabilité spécifie que lorsque l’utilisateur a validé la transaction, les mises à
jour doivent persister, quelques soient les défaillances logicielles ou matérielles qui pourraient surve-‐-
nir.
2.1.3 États d’une transaction
Une transaction est une unité atomique (au sens indivisible) de travail qui doit être soit totalement
terminée soit pas du tout (atomicité). Le système doit donc savoir quand la transaction commence, se
termine, est validée ou est abandonnée. Pour cela, une transaction peut se trouver dans plusieurs
états:
• active: l’état initial. La transaction entre dans cet état immédiatement après son début d’exécution, et
elle y reste durant son exécution,
• partiellement validée: lorsque la dernière instruction de la transaction a été exécutée,
• échouée: dès que l’exécution ne peut plus continuer normalement,
• annulée: après que la transaction a été annulée, et que la base ait été restaurée dans l’état cohérent
d’avant le début de la transaction. Il existe alors deux options après qu’une transaction ait été annu-‐-
lée, soit on redémarre la transaction, soit on tue la transaction.
• validée: après une exécution totalement terminée.
En fait, SQL supporte les transactions, souvent de manière invisible. En effet, chaque commande effec-‐-
tuée dans l’outil d’interrogation est une transaction. Ainsi, chaque fois que vous faites une (ou plu-‐-
sieurs) requête(s) dans SQL/Plus, vous débutez sans le savoir une transaction.
2.1.4 Commit, rollback
L’instruction SQL COMMIT permet de valider une transaction. Cette instruction peut être explicite dans
une transaction où, comme c’est souvent le cas, implicite et exécutée à la fin de la transaction par le
SGBD. Une fois l’instruction COMMIT exécutée, les modifications faites sont permanentes et la transac-‐-
tion s’achève.
L’instruction ROLLBACK permet également d’achever la transaction, mais en l’annulant. Il n’y alors au-‐-
cun effet sur la base, et le SGBD doit alors revenir à l’état précédent le début de la transaction puisque
c’est le dernier point garanti de cohérence de la base.
2.1.5 Exemple
V oyons sur un exemple l’interaction entre deux transactions. On suppose la relation BarÀBière(bar,
bière, prix), et on suppose que le bar Jo vend de la Chimay (3,00€) et de la Leffe (2,50€). Paul interroge
la base, et la relation BarÀBière pour connaître le prix minimum et le prix maximum du bar Jo. Entre-‐-
temps, Jo décide de cesser de vendre de la Chimay et de la Leffe, pour ne plus vendre que de la Kwak
à 3,50€.
Paul exécute les deux instructions SQL suivantes afin de connaître les prix minimum et maximum:
(max) SELECT MAX(prix) FROM BarÀBière
WHERE bar = ‘Jo’;
(min) SELECT MIN(prix) FROM BarÀBière
WHERE bar = ‘Jo’;
16Pendant ce temps, Jo exécute les instructions suivantes:
(del) DELETE FROM BarÀBière
WHERE bar = ‘Jo’;
(ins) INSERT INTO BarÀBière
VALUES(‘Jo’, ‘Kwak’, 3.50);
On a des instructions SQL qui peuvent être entrelacées, avec les contraintes suivantes: (max) doit être
exécuté avant (min), et (del) doit être exécuté avant (ins). Que se passe-‐-t-‐-il lorsque Jo et Paul mettent à
jour la base ? Si les instructions ont lieu dans l’ordre suivant: (max)(del)(ins)(min), on obtient:
Prix 2,50 | 3,00 2,50 | 3,00 3,50
Instruction (max) (del) (ins) (min)
Résultat 3,00 3,50
Ainsi, Paul voit que MAX < MIN !
Comment peut-‐-on résoudre le problème avec les transactions ? Si l’on regroupe les instructions
(max)(min) de Paul dans une seule transaction, alors il n’y aura plus de problèmes. En effet, soit la
transaction s’exécutera avant les modifications de Jo, et Paul verra alors les anciens prix, soit la trans-‐-
action s’exécute après la modification, et il n’y aura pas de problème. La transaction permet donc aux
deux instructions (max)(min) de s’exécuter sur les mêmes données.
Il existe cependant encore une possibilité de comportement étrange. Supposons que Jo exécute sa mo-‐-
dification de prix, mais qu’au dernier moment, il change d’avis et exécute un ROLLBACK. Si Paul
exécute sa transaction après l’instruction (ins), mais avant l’annulation, il va voir une valeur 3,50 qui
n’existe pas dans la base. Pour résoudre ce problème, on va donc exécuter les instructions de Jo dans
une transaction. Ainsi, les effets de (del)(ins) dans une transaction ne pourront être vus par d’autres
transactions que lorsque la transaction aura été validée. Si la transaction venait à être annulée, ses ef-‐-
fets ne seraient pas vus par les autres transactions.
2.1.6 Gestion des transactions dans Oracle
Une transaction débute avec la première instruction SQL exécutable et se termine lors de l’exécution
d’un commit ou d’un rollback, lors de la déconnexion de l’utilisateur (commit), ou lors d’un arrêt
anormal du processus utilisateur (rollback).
Les mises à jour faites par une transaction ne sont visibles pour les autres utilisateurs qu’après la vali-‐-
dation de la transaction (tant qu'ʹune transaction n'ʹest pas validée, les autres utilisateurs accèdent aux
anciennes valeurs des données modifiées).
2.2 La tolérance aux pannes
2.2.1 Journal
Il existe plusieurs types d’incidents qui peuvent survenir sur une base de données :
• échec d’une transaction: une erreur logique dans le programme l'ʹempêche de se poursuivre norma-‐-
lement (erreur lors d'ʹune insertion, suppression ou mise à jour), ou une erreur système arrête le dé-‐-
roulement normal du programme (verrouillage, saturation, processus tué),
• crash système: il entraîne la perte des données en mémoire centrale,
• panne disque: elle provoque la perte physique des données.
Les algorithmes de récupération (recovery) sont des techniques qui permettent aux SGBD d’assurer la
cohérence, l’atomicité et la durabilité malgré les incidents qui peuvent survenir. En général, les algo-‐-
rithmes de récupération possèdent deux parties: la première prend en charge les actions qui ont lieu
lors du déroulement normal de la transaction afin d’avoir assez d’informations pour permettre la ré-‐-
cupération en cas de problème, et la deuxième qui prend en charge les actions à effectuer après un
problème afin de pouvoir récupérer la base dans un état cohérent.
17Pour assurer la reprise sur panne, les SGBD et Oracle en particulier utilisent la notion de journal. Un
journal est un fichier texte dans lequel le SGBD inscrit, dans l’ordre d’exécution, toutes les actions de
mise à jour qu’il effectue. Ainsi, le journal est une séquence d’enregistrements qui mémorise les mises
à jour faites sur la base. Lorsqu’une transaction Ti démarre, elle s’enregistre dans le journal sous la
forme <début transaction, Ti >. Avant que la transaction Ti exécute une instruction écrire(X), un enregis-‐-
trement <Ti, X, V1, V2> est écrit dans le journal (V1 est la valeur de X avant l’écriture, et V2 est la valeur
de X après l’écriture). Lorsque la transaction Ti a lu une valeur, un enregistrement <lecture, Ti, X> est
écrit dans le journal. Enfin, <valider, Ti> ou <annuler, Ti> sont écrits dans le journal suivant que la
transaction a été validée ou annulée.
En Oracle, la gestion des transactions utilise deux fichiers :
• un fichier journal redo log: il enregistre toutes les modifications effectuées (insert, update, delete)
dans les tables de la base par chaque transaction.
• un fichier rollback segment: il enregistre les anciennes valeurs des lignes des tables modifiées par
une transaction.
Le système affecte à chaque transaction un numéro chronologique (SCN – System Control Number) qui
permet de l’identifier de manière unique. Toute opération modifiant une donnée de la base est enregis-‐-
trée dans le fichier rollback segment et dans le fichier journal redo log avant mise à jour de la base. Le
journal redo log est chronologique.
Lors du commit d'ʹune transaction, il faut :
• enregistrer le commit de la transaction dans les fichiers redo log et rollback segment,
• débloquer les lignes des tables verrouillées par la transaction.
Lors du rollback d'ʹune transaction, il faut :
• redonner les anciennes valeurs à toutes les lignes des tables modifiées par la transaction (à partir des
rollback segment),
• débloquer les lignes des tables verrouillées par la transaction.
2.2.2 Reprise après incident
Elle est disponible uniquement pour les incidents sans perte de données sur disque. L’objectif est de
restaurer la base dans un état cohérent telle qu'ʹelle se trouvait juste avant la panne. Le mécanisme de
reprise est le suivant:
• appliquer toutes les modifications enregistrées dans le fichier redo log à la base de données (roll-‐-
forward)
• pour toutes les transactions sans commit, on remet les lignes des tables concernées aux anciennes
valeurs (rollback). Ceci est fait à partir des rollback segment.
Après un incident, on ne traite que les modifications effectuées après le point de reprise (ou point de
contrôle). Un point de reprise consiste à 1) écrire les buffers du fichier redo log sur disque, 2) écrire les
buffers de la base de données sur disque, 3) écrire un article point de reprise dans le fichier redo log.
On peut préciser un point de reprise en utilisant la commande SAVEPOINT pdr ;. Par la suite, on
pourra revenir à ce point en utilisant la commande ROLLBACK TO pdr; qui permet de retrouver l’envi-‐-
ronnement tel qu’il était lors de la déclaration du point de reprise.
SQL Résultats
SA VEPOINT a; Premier point de reprise de la transaction
DELETE …; Modification de la base
SA VEPOINT b; Deuxième point de reprise de la transaction
INSERT INTO…; Modification de la base
SA VEPOINT c; Troisième point de reprise de la transaction
UPDATE …; Modification de la base
18ROLLBACK TO c; L’ordre UPDATE est annulé, le point C reste défini
ROLLBACK TO b; L’ordre INSERT est annulé, le point C est perdu, le point B reste défini
ROLLBACK TO c; ORA-‐-01086 error; savepoint C no longer defined
INSERT TO…; Modification de la base
COMMIT; Valide toutes les actions effectuées par le DELETE (première modification)
et le INSERT (dernière modification). Toutes les autres modifications ont été
annulées avant le COMMIT. Le point A n’est plus actif.
EXEMPLE: traitement des transactions
La mise en œuvre du mécanisme de reprise s’effectue comme ceci. Soient les 5 transactions suivantes
au moment d'ʹun incident :
T1
T2
T3
T4
T5
Point de reprise Incident
• T1 est achevée lors du point de reprise, elle n'ʹest pas traitée.
• T2 et T4 sont validées (commit) lorsque survient l'ʹincident: on applique toutes les modifications en-‐-
registrées dans le fichier redo log à la base de données (rollforward); pour T2, on repart du point de
reprise.
• T3 et T5 ne sont pas validées (pas de commit) lorsque survient l'ʹincident, on remet les lignes des
tables concernées aux anciennes valeurs (rollback).
2.3 La gestion de la concurrence
La gestion des accès concurrents aux données permet d’éviter que la mise à jour simultanée des mê-‐-
mes données par plusieurs utilisateurs n’introduise pas des incohérences dans la base de données. On
dit que deux transactions sont concurrentes si elles accèdent simultanément aux mêmes données.
2.3.1 Accès concurrents et incohérence des données
V oici quelques problèmes classiques qui peuvent survenir avec des transactions concurrentes.
La perte de mise à jour
Il y a perte de mise à jour quand une transaction T2 vient écraser une écriture effectuée par T1.
Temps t1
t2
t3
t4
t5
t6
t7
Transaction T1 État de la base Transaction T2
lire(A)
…
A = A + 10
…
…
écrire(A)
…
A = 10
A = 20
A = 60
…
lire(A)
…
…
A = A+50
…
écrire(A)
Après une exécution séquentielle de T1 et T2 ou T2 et T1, on obtient A=70. Si les transactions sont exé-‐-
cutées de manière concurrentes, on obtient alors A=60. On a donc perdu la première mise à jour.
19Les lectures impropres
Supposons une transaction T2 qui lit une donnée A modifiée par T1. La transaction T1 est annulée et
les modifications effectuées par cette transaction sont défaites. La valeur lue et traitée par T2 est alors
incorrecte.
Temps Transaction T1 État de la base Transaction T2
t1
t2
t3
t4
t5
lire(A)
A = A +20
écrire(A)
…
rollback
A = 10
A = 30
A = 10
…
…
…
lire(A)
…
Les lectures non reproductibles
La transaction T2 lit la même donnée A à deux instants différents et n'ʹobtient pas la même valeur. En-‐-
tre les deux lectures, une autre transaction a modifié la valeur de A.
Temps Transaction T1 État de la base Transaction T2
t1
t2
t3
t4
t5
A = 10
…
lire(A)
A = A + 10
écrire(A)
commit
A = 20
lire(A)
…
…
…
lire(A)
2.3.2 Le mécanisme de verrouillage
Les principales techniques mises en œuvre pour le contrôle de l’exécution concurrente des transac-‐-
tions reposent sur le concept de verrouillage des données. Un verrou est une variable associée à une
donnée qui décrit l’état de la donnée, compte tenu des opérations qui peuvent lui être appliquées.
Ainsi, avant d'ʹaccéder à une donnée pour modifier sa valeur, la transaction T1 doit la verrouiller pour
éviter son accès par une autre transaction. Une fois terminée, la transaction T1 libère alors les données
verrouillées pour les rendre disponibles à d'ʹautres transactions.
Nous reprenons l'ʹexemple du transfert d'ʹune somme d'ʹargent entre deux comptes: T1 fait un transfert
de c1 vers c2, T2 de c1 vers c3.
T1 T2
lock(c1)
read(c1) for update
c1:=c1-‐-m1 T2 attend la libération de c1
écrire(c1) (demande accès pour update de c1)
lock(c2) "ʺ
read(c2) for update "ʺ
c2:=c2+m1 "ʺ
écrire(c2) "ʺ
unlock(c1,c2) lock(c1)
read(c1) for update
c1:=c1-‐-m2
écrire(c1)
lock(c3)
read(c3) for update
c3:=c3+m2
écrire(c3)
20unlock(c1,c3)
Le verrouillage tel qu'ʹil est appliqué ci-‐-dessus permet d'ʹéliminer les pertes de mise à jour et les lectu-‐-
res impropres. Par contre, il ne permet pas d'ʹéliminer les lectures non reproductibles.
Les verrous classiques sont les verrous binaires, c’est-‐-à-‐-dire des verrous qui peuvent avoir deux va-‐-
leurs distinctes: verrouillé ou non verrouillé (1 ou 0). Un verrou est associé à chaque élément X. Si la
valeur du verrou sur X est 0, alors il est possible d’accéder à l’élément. Le verrouillage binaire utilise
deux opérations: verrouillerÉlément et déverrouillerÉlément. Une transaction demande l’accès à
un élément X en exécutant pour commencer l’opération verrouillerÉlément(X). Si le verrou est à 1,
la transaction doit attendre. Si le verrou est à 0, le verrou est mis à 1, et la transaction est autorisée à
accéder à l’élément X. Lorsque la transaction n’a plus besoin d’utiliser l’élément, elle exécute une opé-‐-
ration déverrouillerÉlément(X) qui positionne le verrou à 0 afin que les autres transactions puis-‐-
sent accéder à X. Un verrou binaire applique donc une exclusion mutuelle sur une donnée.
On se rend compte rapidement que les verrous binaires sont trop restrictifs pour les bases de données,
car certaines transactions ne veulent que lire certaines données. On distingue donc deux types de ver-‐-
rous, les verrous partagés, qui permettent à plusieurs transactions de lire une donnée verrouillée par
une transaction, et les verrous exclusifs, qui permettent à la transaction qui a posé le verrou d’effec-‐-
tuer une opération d’écriture.
2.3.3 Le risque d'ʹinterblocage
Un interblocage (ou verrou mortel) survient lorsque chaque transaction T d’un ensemble de n (n ≥ 2)
transactions attend une donnée verrouillée par une autre transaction T’ de l’ensemble. Autrement dit,
T1 attend une donnée verrouillée par T2, et T2 attend une donnée verrouillée par T1.
EXEMPLE : transfert entre deux comptes.
T1 transfère une somme m d’un compte c1 vers un compte c2, et T2 transfère une somme n de c2 vers
c1. L'ʹexécution simultanée des deux transactions conduit à la situation suivante :
T1 T2
lock(c1)
read(c1)
c1:=c1+m lock(c2)
écrire(c1) read(c2)
c2:=c2+n
T1 attend libération de c2 "ʺ écrire(c2)
T2 attend libération de c1
"ʺ "ʺ
"ʺ "ʺ
Les données sont verrouillées en fonction des demandes de mises à jour, mais ne sont libérées qu’en
fin de transaction
2.3.4 Résolution de l'ʹinterblocage (deadlock)
Une approche pratique de la gestion des interblocages repose sur la détection de ceux-‐-ci: le système
vérifie s’il y a une situation d’interblocage. Un procédé pour détecter une situation d’interblocage con-‐-
siste pour le système à construire et à maintenir un graphe d’attente des ressources (wait-‐-for graph).
Dans ce graphe, un nœud est créé pour chaque transaction en cours d’exécution. Chaque fois qu’une
transaction Ti attend de pouvoir verrouiller une donnée X verrouillé par une transaction Tj, un arc est
créé entre les deux transactions. Il y a situation d’interblocage si et seulement si il existe un cycle dans
le graphe. Il se pose alors le problème de savoir quand le système doit vérifier la présence d’un inter-‐-
blocage (nombre de transactions, durée d’attente de plusieurs transactions,…). Si le système détecte
l’interblocage, il tue une (ou plusieurs) des transactions impliquées. Il existe différentes solutions pour
le choix de la transaction à tuer : la plus récente, celle qui a fait le moins de mises à jour … D’autres
solutions plus élaborées peuvent être utilisées, mais ne seront pas traitées dans le cadre de ce cours.
Une autre possibilité pour gérer les interblocages consiste à employer des mises hors délais (timeouts).
21Cette méthode est pratique en raison du peu d’activité qu’elle implique sur le système. Si une transac-‐-
tion attend plus longtemps que la durée spécifiée pour la mise hors délai, le système suppose qu’elle
est bloquée et il tue cette transactions, qu’il y ait ou non interblocage.
La détection des interblocages
Pour détecter les interblocages, on construit le graphe d’attente des ressources :
X
T1 T2
Y
X, Y ,… représentent des éléments des tables de la base. T1, T2 …. identifient des transactions. Un arc
orienté étiqueté X ou Y entre Ti et Tj signifie que la transaction Ti attend la libération de X ou Y . L'ʹin-‐-
terblocage se traduit par un circuit dans le graphe d’attente des ressources, comme dans la figure ci-‐-
dessus.
RAPPEL: l'ʹinterblocage peut mettre en jeu n (n≥2) transactions.
X T2
T1
Y
Z
T3
2.3.5 Niveaux d'ʹisolation
SQL définit quatre niveaux d’isolation qui permettent de choisir quelles sont les types d’interactions
autorisées pour les transactions qui s’exécutent simultanément (concurrentes). Ainsi, dans une trans-‐-
action, on peut utiliser l’instruction suivante:
SET TRANSACTION ISOLATION LEVEL X
où X = SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED
T ransactions de niveau serializable
Si on reprend l’exemple de la section 4.1.5, et si on suppose que Paul = (max)(min) et Jo = (del)(ins)
sont des transactions, et si Paul utilise le niveau d’isolation SERIALIZABLE, alors il verra la base dans
l’état soit avant les modifications de Jo, soit après, mais pas entre les deux opérations de la transaction
de Jo.
Le niveau d'ʹisolation est un choix qui affecte uniquement la vue de la base de la transaction que le
spécifie. Si on reprend notre exemple (cf section 4.1.5), si Jo choisit le niveau SERIALIZABLE, mais pas
Paul, alors Paul peut éventuellement ne voir aucun prix si la requête est exécutée entre (del) et (ins).
T ransactions de niveau repeatable read
Seules les données validées peuvent être lues, ce qui implique que les lectures répétées dans une
même transaction retourne les mêmes valeurs (pas de phénomène de lectures non reproductibles).
Cependant, une transaction pourra voir apparaître au cours des lectures répétées de nouveaux n-‐-u-‐-
plets (ou des n-‐-uplets qui ont disparu).
Sur notre exemple, si Paul a choisi le niveau REPEATABLE READ, et que l’ordre d’exécution est
(max)(del)(ins)(min), alors (max) verra les prix 2,50 et 3,00, et (min) verra 3,50, mais également 2,50 et
3,00 car ils ont été vus par la lecture précédente de (max) dans la transaction.
T ransactions de niveau read committed
Seules les données validées peuvent être lues, mais des lectures successives peuvent renvoyer des va-‐-
leurs (validées) différentes. Cela permet de voir les modifications apportées par d’autres transactions.
22Sur notre exemple, si Paul a choisi le niveau READ COMMITTED, alors il peut voir les valeurs validées,
mais pas nécessairement les mêmes à chaque requête. Ainsi, avec READ COMMITTED, l’entrelacement
(max)(del)(ins)(min) est autorisé, aussi longtemps que Jo valide (mais Paul peut voir MAX < MIN).
T ransactions de niveau read uncommitted
Une transaction qui s’exécute en niveau d’isolation READ UNCOMMITTED peut voir des données dans la
base qui ne sont pas validées par une autre transaction (et qui ne le seront peut-‐-être jamais).
Sur notre exemple, si Paul a choisi le niveau READ UNCOMMITTED, il pourra voir le prix 3,50, même si Jo
abandonne la transaction.
2.3.6 V errouillage et niveaux de granularité
Les performances du contrôle de la concurrence est affectée par la taille des éléments à verrouiller. Par
exemple, dans une base de données, on a la valeur d’un attribut d’un n-‐-uplet, un n-‐-uplet, une table, ou
toute la base. Selon que l’on pose un verrou sur un élément particulier, on peut bloquer ou non plu-‐-
sieurs transactions. En particulier, il faut remarquer que plus la taille des éléments à verrouiller est
importante, plus le degré de concurrence autorisé est faible. Par exemple, si une transaction veut blo-‐-
quer toute une table (et si elle ne souhaite accéder qu’à un n-‐-uplet particulier), toutes les autres trans-‐-
actions seront mises en attente alors qu’il n’est peut être pas nécessaire de bloquer toute la table. In-‐-
versement, si on verrouille des éléments de taille plus petite, il peut y avoir beaucoup d’éléments à
verrouiller, et donc le gestionnaire de verrouillage devra gérer un plus grand nombre de verrous
(beaucoup d’opérations de verrouillage/déverrouillage). La nature des verrous à poser dépend donc
de la nature des transactions. Par exemple, si une transaction accède à un petit nombre d’enregistre-‐-
ments, il est préférable que la granularité soit l’enregistrement. Par contre, si une transaction accède à
de nombreux enregistrements d’une même table, alors la granularité qui semble la plus appropriée
semble être la table.
2.4 Le verrouillage sous Oracle
2.4.1 Principe
Oracle implante un verrouillage au niveau de la ligne, et utilise un mécanisme appelé Read consistency
(lecture cohérente). Grâce à ce mécanisme, les mises à jour et les lectures ne se bloquent pas mutuel-‐-
lement. Toutes les données retournées par un SELECT proviennent d’un seul point dans le temps. On
ne voit que les données validées au moment du SELECT. Pour les données non validées, on voit les
anciennes valeurs (grâce au Rollback segment). Les données modifiées par une autre transaction après
le début du SELECT ne sont pas vues.
Il existe une concurrence d’accès en mise à jour: la première transaction qui accède à une donnée posi-‐-
tionne un verrou sur les données accédées (n-‐-uplets ou tables), les autres transactions souhaitant accé-‐-
der les mêmes données seront mises en attente.
Ce mécanisme ne prend pas en compte les lectures non reproductibles. On peut, pour résoudre ce
problème, utiliser une transaction spéciale appelée une transaction à lecture seulement (Read Only
T ransaction). Cette transaction conserve, lorsqu'ʹelle démarre, l’état de la base et travaille ensuite uni-‐-
quement sur cet état, jusqu'ʹà la fin de la transaction. Une telle transaction ne doit comporter que des
lectures de la base, et les modifications des données de la base sont interdites. La syntaxe est:
SET TRANSACTION READ ONLY
instruction 1
…
instruction n
COMMIT
2.4.2 Niveaux d’isolation
En fixant le niveau d’isolation des transactions, on définit le mode de fonctionnement en parallèle des
différentes transactions qui s’exécutent au même moment. La commande suivante indique le niveau
d’isolation de la transaction qui vient de commencer :
23SET TRANSACTION ISOLATION LEVEL {SERIALIZABLE | READ COMMITTED}
Oracle permet deux niveaux d’isolation des transactions les unes par rapport aux autres :
• READ COMMITTED : c’est le mode par défaut des transactions d’Oracle. Il empêche les principaux
problèmes de concurrence mais pas les lectures non reproductibles. Tout d’abord, les modifications
effectuées par une transaction ne sont connues des autres transactions que lorsque la transaction a
été confirmée (COMMIT). Oracle gère automatiquement les accès concurrents de plusieurs transac-‐-
tions sur les mêmes n-‐-uplets de table. Si une transaction est en train de modifier des n-‐-uplets d’une
table, les autres transactions peuvent lire les données telles qu’elles étaient avant ces dernières mo-‐-
difications, mais les autres transactions sont bloquées automatiquement par Oracle si elles souhai-‐-
tent modifier ces mêmes lignes.
• SERIALIZABLE : si une transaction SERIALIZABLE essaie de modifier une donnée qui pourrait avoir
été modifiée par une autre transaction non validée au début de la transaction SERIALIZABLE, alors
l’ordre de modification échoue (résolution du problème de lecture non reproductibles). Ce mode est
coûteux puisqu’il limite le fonctionnement en parallèle des transactions (les transactions s’exécutent
concurremment comme si elles s’exécutaient les unes après les autres).
2.4.3 Différents niveau de verrouillage
V errouillage de niveau n-‐-uplet
Par défaut, Oracle met en œuvre un verrouillage de niveau n-‐-uplet, c’est-‐-à-‐-dire une stratégie de ver-‐-
rouillage au niveau des n-‐-uplets, chaque n-‐-uplet d’une table pouvant être verrouillé individuellement.
Les n-‐-uplets verrouillés peuvent alors être mis à jour uniquement par la transaction qui les a ver-‐-
rouillés. Tous les autres n-‐-uplets de la table peuvent être mis à jour par d’autres transactions. De plus,
les autres transactions gardent également la possibilité de lire les n-‐-uplets, y compris ceux qui sont mis
à jour. Pour ces derniers, les transactions ont accès à l’ancienne valeur (grâce au rollback segment) jus-‐-
qu’à ce que la transaction soit validée (lecture cohérente).
Lorsqu’une transaction pose un verrou sur un n-‐-uplet, Oracle effectue les opérations suivantes:
• Premièrement, un verrou DML (data manipulation language) est posé. Ce verrou évite que d’autres
transactions puissent mettre à jour (ou poser un verrou) sur le n-‐-uplet. Ce verrou ne sera relâché que
lorsque la transaction qui a posé le verrou aura été validée ou annulée,
• Deuxièmement, un verrou DDL (data dictionary language) est posé sur la table afin d’éviter les modifi-‐-
cations structurelles de la table (suppression de la table, retrait ou ajout d’un attribut,…). Ce verrou
ne sera relâché que lorsque la transaction qui a posé le verrou aura été validée ou annulée.
V errouillage de niveau T able
Avec le verrouillage au niveau table, la table entière est verrouillée. Dès qu’une transaction a ver-‐-
rouillé une table, seule cette transaction peut mettre à jour (ou verrouiller) n’importe quel n-‐-uplet de la
table. Aucun des n-‐-uplets de la table ne peut être mis à jour par une autre transaction. Cependant, les
autres transactions peuvent malgré tout lire n’importe quel n-‐-uplet, y compris ceux qui sont mis à
jour.
Relâcher les verrous
Souvent, les utilisateurs pensent être seuls au monde. C’est précisément ce genre de comportement
qui crée les problèmes de blocage. Souvenez-‐-vous que poser un verrou (sur un n-‐-uplet ou sur une ta-‐-
ble) n’est pas une opération anodine, et que cela peut bloquer beaucoup d’autres transactions. C’est
pourquoi il faut veiller à verrouiller de manière approprié, c’est-‐-à-‐-dire qu’il faut protéger uniquement
la partie de votre transaction qui est critique (mise à jour, calcul d’une moyenne, somme,…), et qu’il
faut également relâcher le verrou. Il faut donc être conscient que l’on relâche un verrou en validant
(COMMIT) ou en annulant (ROLLBACK) la transaction.
2.4.4 Les différents modes de verrouillage
Oracle propose deux modes de verrouillage:
24• le mode exclusif (X) qui empêche les ressources verrouillées d’être partagées. C’est le mode
privilé-‐- gié pour mettre à jour des données. La transaction qui pose un verrou exclusif la
première est la seule transaction qui peut modifier la table, et ce jusqu’à ce que le verrou soit
relâché.
• le mode partagé (S) permet à une ressource d’être partagée. Plusieurs transactions peuvent avoir
un verrou partagé et peuvent ainsi éviter qu’une autre transaction obtienne un verrou exclusif.
Oracle gère les types de verrous suivants: row share (RS), row exclusive (RX), share (S), share
row exclusive (SRX), et exclusive (X).
V errous exclusifs
SQL V errou
SELECT … FROM table… pas de verrou
INSERT INTO table… RX
UPDATE table… RX
DELETE FROM table… RX
LOCK TABLE table IN ROW EXCLUSIVE MODE RX
LOCK TABLE table IN SHARE ROW EXCLUSIVE MODE SRX
LOCK TABLE table IN EXCLUSIVE MODE X
V errous partagés
SQL V errou
SELECT … FROM table FOR UPDATE OF… RS
LOCK TABLE table IN ROW SHARE MODE RS
LOCK TABLE table IN SHARE MODE S
LOCK TABLE table IN SHARE ROW EXCLUSIVE MODE SRX
2.5 JDBC et les transactions
2.5.1 JDBC = Java DataBase Connectivity
JDBC est une API d’accès aux systèmes de gestion de base de données relationnelles qui permet
d’exécuter des requêtes SQL au sein d’un programme Java et de récupérer les résultats, ce qui
représente une alternative aux solutions propriétaires. C’est de plus une tentative de standardiser
l’accès aux bases de données car l’API est indépendante du SGBD choisi, pourvu que le pilote
JDBC existe pour ce SGBD, et qu’il implémente les classes et interfaces de l’API JDBC.
Pour effectuer un traitement avec une base de données, il faut :
1. charger un pilote en mémoire,
2. établir une connexion avec la base de données,
3. récupérer les informations relatives à la connexion,
4. exécuter des requêtes SQL et/ou des procédures stockées,
5. récupérer les informations renvoyées par la base de données (si nécessaire),
6. fermer la connexion.
Pour plus de détails, consulter le polycopié sur JDBC.
252.5.2 Gestion des transactions
L’instance de l’objet Connection fournit les méthodes pour :
Activer/désactiver la validation automatique de chaque requête passée (activé par défaut) :
public void setAutoCommit(boolean autoCommit) throws SQLException;
Valider manuellement la/les requête(s) passée(s) :
public void commit() throws SQLException;
Annuler les dernières modifications faites par la/les requête(s) passée(s) :
public void roolback() throws SQLException;
Exemple :
String sql1 = "UPDATE vendeur SET sal = 1215 WHERE sal < 1215";
String sql2 = "DELETE FROM vendeur WHERE sal < 1215";
try {
[Link](false);
Statement state = [Link]();
[Link](sql1);
Statement state2 = [Link]();
[Link](sql2);
[Link]();
...
} catch (Exception e) {
try{
[Link]();
} catch (SQLExection e) {
...
}
...
}
JDBC supporte le mode transactionnel qui consiste à valider tout ou une partie d’un ensemble
d’instructions. Nous avons déjà décrit à la section « Interface Connection » les méthodes qui
permettent à un programme Java de coder des transactions (setAutoCommit, commit et rollback).
Par défaut, chaque instruction SQL est validée (on parle d’autocommit). Lorsque ce mode est
désactivé, il faut gérer manuellement les transactions avec commit ou rollback.
Quand le mode autocommit est désactivé :
La déconnexion d’un objet Connection (par la méthode close) valide implicitement la
transaction (même si commit n’a pas été invoqué avant la déconnexion).
Chaque instruction (CREATE, ALTER, DROP) valide implicitement la transaction.
26
CHAPITRE 1: BASES DE DONNÉES RELATIONNELLES
1. Les Systèmes de Gestion de Bases de Données (SGBD)
2. Introduction à la conception de bases de données relationnelles
3. Décomposition de schémas relationnels
4. Normalisation des relations
5. Dépendances fonctionnelles et conception de schémas
1.1 Les Systèmes de Gestion de Bases de Données (SGBD)
Un système de base de données peut être décrit par l’équation suivante:
Système de Base de Données = Base de Données + SGBD
Un SGBD est un système permettant de gérer et de manipuler la base de données, et une base de
données est une collection de données en relation qui sont:
1. partagées par de multiples applications (utilisateurs et/ou programmes),
2. stockées avec une redondance minimum,
3. indépendantes des applications,
4. organisées afin d’être une fondation pour de futures applications.
Le modèle de données est le formalisme qui décrit la structure logique de la base de données et les
opérations sur celle-‐-ci.
Le schéma de base de données est la structure de la base de données. L’instance de la base de don-‐-
nées est le contenu actuel de la base de données.
Une base de données est donc constituée d’une part d’un schéma de base de données et d’une instance de
la base de données d’autre part. On peut, par analogie avec les langages de programmation, définir les
correspondances suivantes:
modèle de données schéma ↔ ↔ instance ↔ variable
langage de programmation
déclaration d’une structure de données
1.1.1 Modèle de Données Relationnel
Une instance de la base de données peut être considérée comme une collection de relations mathéma-‐-
tiques. Chaque relation est représentée par une table dont chaque colonne est appelée un attribut et
chaque ligne est appelée un tuple ou n-‐-uplet. On associe à chaque attribut un ensemble de valeur, ap-‐-
pelé domaine.
Un schéma de relations est alors défini comme un ensemble d’attributs.
EXEMPLE
EMPLOYÉ = {nom, nosécu, nomdépartement, salaire, datenaissance}
CONVENTION DE NOTATION
EMPLOYÉ (nom, nosécu, nomdépartement, salaire, datenaissance)
Un schéma de base de données est une collection de schémas de relations.
EXEMPLE
{ EMPLOYÉ, DÉPARTEMENT, PROJET }
NOTATIONS
schéma de relations R R(A1,A2,...,An)
n-‐-uplet <v1,v2,...,vn>
valeur de l’attribut Ai t[Ai]
valeurs des attributs t[Au,Aw,...Az]
attribut A du schéma R R.A
11.1.2 Contraintes d’intégrité
Il existe un certain nombre de propriétés qui doivent être respectées pour chaque instance d’un sché-‐-
ma de relations ou d’un schéma de base de données afin de préserver la cohérence des informations
stockées dans la base. Ces propriétés sont appelées contraintes d’intégrité.
Les dépendances entre données sont des contraintes d’intégrité qui spécifient les relations entre les
valeurs des attributs. Elles sont très utiles dans la conception de bases de données.
1.2 Introduction à la conception de bases de données relationnelles
1.2.1 Deux approches pour concevoir un schéma de base de données
Il existe deux approches pour concevoir un schéma de base de données: une approche descendante,
également appelée méthode par décomposition, et une approche ascendante, également appelée mé-‐-
thode synthétique. Nous présentons rapidement pourquoi la conception d’un schéma de base de don-‐-
nées peut être présenter des anomalies. Les dépendances fonctionnelles sont un outil théorique qui
permet de vérifier la qualité de conception d’un schéma et de comprendre les conséquences de la re-‐-
dondance de données.
1. Conception descendante (top-‐-down design)
On part d’un schéma de relations unique…
décomposition basée sur les dépendance entre données
(par exemple, les dépendances fonctionnelles)
…pour obtenir une collection de schémas de relations.
2. Conception ascendante (bottom-‐-up design)
On part d’une collection d’attributs…
synthèse (regroupement)
…pour obtenir une collection de schémas de relations.
QUESTIONS
• Quelles sont les propriétés intéressantes d’un schéma de base de données relationnelles ?
– mesure de la qualité du schéma,
– méthodologie de conception.
• Quels sont les algorithmes permettant d’obtenir un schéma possédant les bonnes propriétés ?
– outil dédié à la conception,
– conception automatique.
MESURE DE LA QUALITÉ
1. sémantique des attributs
Plus il est facile d’expliquer la sémantique des attributs d’une relation, plus la conception du
schéma de relations est bonne.
PRINCIPE 1: concevoir un schéma de relations de telle sorte qu’il soit simple d’expliquer ce
qu’il représente.
EXEMPLE
Que signifie FOURNIT (f#, nom, adresse, p#, produit, prix, couleur, nomproj, dép) ?
Ce schéma de relations doit être décomposé comme suit:
PROD(p#, produit, couleur)
FOURNITPROD(f#, nom, adresse,p#, produit, prix)
PROJET(nomproj, dép)
UTILISE(nomproj, p#)
Chaque schéma de relations et chaque attribut ont une sémantique précise.
22. les informations redondantes
Les informations redondantes, à l’origine de problèmes, doivent être supprimées dans la me-‐-
sure du possible.
PRINCIPE 2: concevoir un schéma de relations de telle manière que les insertions, les suppres-‐-
sions et les mises à jour ne posent pas de problèmes.
EXEMPLE
Si on utilise la relation suivante FOURNITPROD(f#, nom, adresse, p#, produit, prix) plutôt
que le schéma de relations suivant:
FOURNISSEUR(f#, nom, adresse)
FOURNIT(f#, p#, prix)
alors le nom et l’adresse d’un fournisseur sont stockés plusieurs fois dans les n-‐-uplets corres-‐-
pondant aux produits vendus par le fournisseur.
QUAND Y-‐-A-‐-T-‐-IL REDONDANCE D’INFORMATION ?
On constate assez facilement que la même adresse apparaît autant de fois qu’il y aura de produits si
l’on utilise la relation FOURNITPROD(f#, nom, adresse, p#, produit, prix). Or on sait qu’un fournis-‐-
seur ne possède qu’une seule adresse et cela même s’il vend plusieurs produits. On appelle cette
propriété une dépendance fonctionnelle. Un mauvais schéma relationnel peut alors entraîner des
anomalies lors des manipulations.
f# nom Labaleine Lemelon adresse p# produit prix
F1 Paris P1 parapluie 110
F2 Lyon P2 chapeau 50
F3 Toutcuir Lyon P3 sac à main 650
F1 Labaleine Paris P4 parasol 150
F1 Labaleine Paris P5 ombrelle 70
F4 Letour Nantes P6 ceinture 55
F5 P3 650
Legrand Paris sac à main Dans la relation ci-‐-dessus, il existe des redondances qui peuvent engendrer les difficultés
suivantes:
• anomalie d’insertion. Telle qu’elle se présente, cette relation ne permet pas de mémoriser dans
la base un produit dont le fournisseur n’existe pas.
• anomalie de suppression. La disparition d’un fournisseur, qui est l’unique fournisseur d’un
produit, entraîne également la disparition des informations concernant ce produit (exemple:
Letour).
• anomalie de mise à jour. Toute modification sur le prix d’un produit qui apparaît plusieurs fois
dans la relation doit être répercutée sur tous les n-‐-uplets correspondants (exemple: sac à main).
Cela augmente le temps de mise à jour et les risques d’incohérence.
On résout ces problèmes en étudiant les dépendances entre les données, et en décomposant et norma-‐-
lisant les relations. On obtient ainsi des schémas de relations qui évitent les anomalies citées ci-‐-dessus.
Attention cependant à ne pas voir la normalisation comme un dogme. Il arrive parfois que, pour des
raisons d’efficacité notamment, on soit obligé de dénormaliser.
1.2.2 Dépendance Fonctionnelle (DF)
Soient R un schéma de relations, et X=A1,A2,…,An et Y=B1,B2,…,Bm des sous-‐-ensembles de R.
X détermine fonctionnellement Y , noté X → Y , ssi pour chaque instance r de la relation R, pour chaque
paire de n-‐-uplets t et s appartenant à r, t[X] = s[X] implique t[Y] = s[Y] (où t[X] désigne la projection du
n-‐-uplet t sur les attributs X).
Autrement dit, X → Y signifie qu’une valeur de X détermine au plus une valeur de Y.
3Une dépendance fonctionnelle est une propriété définie sur l'ʹintention du schéma et non son extension
(elle est donc invariante dans le temps et ne peut être extraite à partir d'ʹexemples). C'ʹest une propriété
qui doit être extraite de la connaissance que l'ʹon a de l'ʹapplication à modéliser et qui permet d’élimi-‐-
ner la redondance.
EXEMPLES
Considérons la relation suivante
FILM (titre, année, durée, type, studio, acteurPrincipal)
avec une instance de la relation contenant les n-‐-uplets suivants:
titre année durée type studio acteurPrincipal
StarWars 1977 124 couleur Fox Carrie Fisher
StarWars 1977 124 couleur Fox Mark Hamill
StarWars 1977 124 couleur Fox Harrison Ford
1991 104 couleur Disney Emilio Estevez
1991 95 couleur Paramount Dana Carvey
1992 95 couleur Paramount Mike Meyers
Mighty Ducks Wayne’s World Wayne’s World On peut en déduire les trois DF suivantes:
{titre, année} → durée
{titre, année} → type
{titre, année} → studio
Par contre, la dépendance suivante n’est pas une DF:
{titre, année} → acteurPrincipal
En effet, étant donné un film, il peut exister dans la base (telle qu’elle est modélisée) plusieurs acteurs
principaux.
Enfin, la DF {titre, année} → durée signifie qu’il ne peut exister dans une instance de FILM les deux n-‐-
uplets suivants:
titre année durée type studio acteurPrincipal
Farenheit, 9/11 2004 124 couleur Fox Georges Bush
Farenheit, 9/11 2004 130 couleur Fox Dick Cheney
CONVENTIONS
• L’ensemble de DF suivant:
{A1,A2,…,An} → B1
{A1,A2,…,An} → B2
…
{A1,A2,…,An} → Bm
est équivalent à {A1,A2,…,An} → B1,B2,...,Bm.
41.2.3 Propriétés des DF
Les trois premières propriétés (réflexivité, augmentation et transitivité) sont également appelés axio-‐-
mes d’Armstrong. De ces trois axiomes, on peut en déduire trois autres propriétés (pseudo-‐-transitivité,
union et décomposition).
Si Y ⊆ X, alors on a X → Y
RÉFLEXIVITÉ
Si X → Y , alors on a X ∪ Z → Y ∪ Z
AUGMENTATION
TRANSITIVITÉ
PSEUDO-‐-TRANSITIVITÉ
Si X → Y et Y ∪ W → Z, alors X ∪ W → Z
Si X → Y et Y → Z, alors on a X → Z
Si X → Y et X → Z, alors X → Y ∪ Z
UNION
Si X → Y et Z ⊆ Y , alors X → Z
DÉCOMPOSITION
• les n-‐-uplets de la relation S sont la projection sur {B1,B2,…,Bm} de tous les n-‐-uplets de R. La pro-‐-
jection est l’opération qui consiste à construire la nouvelle relation S à partir de R en prenant
pour chaque n-‐-uplet t de R uniquement les attributs {B1,B2,…,Bm} et en éliminant les n-‐-uplets en
double,
• de manière similaire, les n-‐-uplets de la relation T sont la projection sur {C1,C2,…,Ck} de tous les n-‐-
uplets de R.
La décomposition de la relation R en R1,R2,…,Rn est sans perte si la jointure des relations R1,R2,…,Rn
permet de retrouver tous les n-‐-uplets de la relation R d’origine. La jointure est l’opération qui permet
de construire une nouvelle relation à partir de deux relations ayant au moins un attribut commun.
EXEMPLE
On peut décomposer la relation FILM définie précédemment en deux relations FILM1 et FILM2 telles
que:
FILM1 = (titre, année, durée, type, studio)
FILM2 = (titre, année, acteurPrincipal)
7Si on utilise la décomposition telle qu’elle est définie, on obtient au niveau des n-‐-uplets pour FILM1 et
FILM2 les résultats suivants:
titre année durée type studio
StarWars 1977 124 couleur Fox
Mighty Ducks 1991 104 couleur Disney
titre année acteurPrincipal
StarWars 1977 Carrie Fisher
StarWars 1977 Mark Hamill
StarWars 1977 Harrison Ford
1991 Emilio Estevez
1991 Dana Carvey
1992 Mike Meyers
Mighty Ducks Wayne’s World Wayne’s World On peut remarquer que cette décomposition élimine les problèmes
soulevés au paragraphe 1.2.1. La
redondance est éliminée, par exemple la durée de chaque film n’apparaît qu’une fois, dans la relation
FILM1. Le risque d’anomalie de mise à jour a ainsi disparu. De même, le risque d’anomalie de sup-‐-
pression a disparu. Si on supprime tous les acteurs du film Wayne’s World, le film disparaît égale-‐-
ment. Il apparaît que FILM2 possède malgré tout de la redondance, puisque titre et année apparais-‐-
sent plusieurs fois. Cependant, ces deux attributs forment une clé, et il n’est pas possible de représen-‐-
ter plus succinctement un film.
1.4 Normalisation des relations
Les formes normales de schémas de relations sont des propriétés souhaitables que doit posséder cha-‐-
que schéma de relations. Elles sont nécessaires (mais non suffisantes) pour une « bonne » conception.
Historiquement, les formes normales suivantes ont été proposées (de la moins restrictive à la plus res-‐-
trictive).
Première Forme Normale (1NF)
Deuxième Forme Normale (2NF)
Troisième Forme Normale (3NF)
Forme Normale de Boyce and Codd (BCNF)
Quatrième Forme Normale (4NF)
Cinquième Forme Normale (5NF)
Les formes normales définissent un ordre partiel sur les schémas de relation. On peut donc voir une
forme normale comme une classe d'ʹéquivalence (on peut comparer deux schémas dans deux classes
d'ʹéquivalence différentes mais pas dans la même). Il faut aussi noter que le seul élément qui est pris en
compte par les formes normales est la non redondance d'ʹinformations d'ʹun schéma. Selon les formes
normales, un « bon » schéma est un schéma sans redondance (ce qui ne veut pas forcément dire qu'ʹil
est efficace par exemple). Un schéma relationnel sans qualité particulière est appelé schéma en 1ère
forme normale (on note 1NF) et si on rajoute certaines qualités on obtient les deuxième et troisième
formes normales (on note 2NF et 3NF).
On ne présente ici que les formes normales dont la définition utilise exclusivement les dépendances
fonctionnelles. Si on prend en compte d'ʹautres dépendances entre données comme les dépendances
multivaluées, on obtient alors les 4NF et 5NF. La BCNF reste cependant l'ʹobjectif de normalisation le
plus « classique ».
1NF: une relation est en première forme normale ssi tout attribut a une valeur atomique (vrai par défi-‐-
nition du modèle relationnel).
82NF : une relation est en deuxième forme normale ssi elle est en 1NF et si tous les attributs non clés
sont pleinement dépendants des clés (toutes les dépendance entre une clé et un attribut non clé sont
des dépendances fonctionnelles élémentaires).
3NF : une relation est en troisième forme normale ssi elle est en 2NF et si tous les attributs non clés
sont directement et pleinement dépendants des clés (si tout attribut non clé ne dépend pas d'ʹun autre
attribut non clé).
BCNF (Boyce-‐-Codd) : une relation est en BCNF ssi elle est en 3NF et si les seules DFE sont celles de la
forme C → X avec C clé (seules les clés sont en partie gauche de DF).
1.4.1 Première forme normale (1NF)
Une relation R est dite en première forme normale (1NF) si tous ses attributs sont atomiques et qu’il
n’existe pas d’attributs répétitifs. De plus, chaque attribut doit avoir une sémantique précise. V oyons
pourquoi la relation suivante n’est pas en première forme normale.
titre année durée type studio
StarWars 1977 124 couleur Fox, Los Angeles
Mighty Ducks 1991 104 couleur Disney , San Francisco
Wayne’s World 1992 95 couleur Paramount, Los Angeles
Les attributs de cette relation ne sont pas atomiques. En effet, l’attribut studio contient à la fois le nom
et la ville, ce qui est gênant si l’on souhaite extraire tous les studios situés à Los Angeles.
Analysons maintenant un deuxième exemple. La relation suivante n’est pas non plus en 1NF.
titre année acteur1 acteur2 acteur3
StarWars 1977 Carrie Fisher Mark Hamill Harrison Ford
Mighty Ducks 1991 Emilio Estevez
Wayne’s World 1992 Dana Carvey Mike Meyers
En effet, la première forme normale stipule que les attributs ne doivent pas être répétitifs. Or, la liste
des acteurs ne respecte pas cette propriété. Si on veut rechercher dans quel film a joué Harrison Ford,
on est obligé non seulement de parcourir tous les n-‐-uplets, mais également toutes les colonnes. De
plus, si l’on souhaite rajouter un quatrième acteur, il faut modifier la relation toute entière.
Enfin, que pensez-‐-vous de la relation suivante:
titre année durée type studio
StarWars 1977 124 SF Fox
Mighty Ducks 1991 104 couleur Disney
Wayne’s World 1992 95 couleur Paramount
Il semble que cette relation soit en 1NF. Les attributs sont atomiques, il n’y a pas d’attributs répétitifs.
Malgré tout, l’attribut type ne possède pas une sémantique claire, représentant soit un genre (SF), soit
le type de la pellicule. Cette relation n’est donc pas en 1NF.
1.4.2 Deuxième forme normale (2NF)
Une relation R est dite en deuxième forme normale (2NF) ssi
• elle est en 1NF,
• tout attribut n’appartenant pas à une clé ne dépend pas d’une partie de cette clé (pas de dépen-‐-
dances partielles).
Autrement dit, dès qu’un attribut non clé dépend d’une partie d’une clé, la relation n’est pas en 2NF.
9V oyons dans un premier temps un exemple abstrait. La relation R(A,B,C) munie de l’ensemble F des
dépendances est en 1NF mais pas en 2NF.
A,B → C
B →C
Regardons maintenant sur un exemple concret. Considérons la relation suivante:
numSalarié nom numProjet heures
20036 Durand 1 18,5
20036 Durand 2 6,7
36900 Leroux 2 8,5
45002 Franck 3 23,5
45002 Franck 1 4,8
L’ensemble F des DF est:
numSalarié → nom
numSalarié,numProjet → heures
La relation n’est pas en 2NF. En effet, la clé minimale de cette relation est {numSalarié,numProjet}.
L’attribut non clé heure est en totale dépendance fonctionnelle avec la totalité de la clé. Par contre,
l’attribut non clé nom dépend d’une partie de la clé, à savoir numSalarié. Pour que la relation soit en
2NF, il est nécessaire de scinder la relation initiale en deux relations, comme ceci:
numSalarié numProjet heures
20036 1 18,5
20036 2 6,7
36900 2 8,5
45002 3 23,5
45002 1 4,8
numSalarié nom
20036 Durand
36900 Leroux
45002 Franck
Chacune de ces deux relations répond désormais aux exigences de la première et de la deuxième
forme normale. La première relation a pour clé primaire l’attribut numSalarié, et la deuxième relation
a pour clé {numSalarié,numProjet}.
1.4.3 T roisième forme normale (3NF)
OBJECTIFS DE LA 3NF
1. élimination des dépendances partielles
S’il existe une dépendance partielle Y → A, où X est une clé minimale et Y un sous-‐-ensemble
de X, alors chaque n-‐-uplet utilisé pour associer une valeur X aux valeurs de A sera répété pour
les valeurs de Y (d’où redondance des informations).
La condition de la 3NF élimine cette possibilité, évitant ainsi les mises à jour incorrectes et la
redondance.
2. élimination des dépendances transitives
S’il existe une dépendance transitive X → Y → A, alors on ne peut associer une valeur Y à une
valeur X que s’il existe une valeur A associée à une valeur Y . Cela conduit à des problèmes
d’insertion et de suppression.
DÉFINITION
On considère les définitions suivantes:
R: un schéma de relations,
F: un ensemble de DF sur R,
X: un sous-‐-ensemble de R,
A: un attribut.
10On rappelle que A est un attribut clé ssi il fait partie d’une clé minimale de R et que dans le cas con-‐-
traire, A est appelé un attribut non clé.
La relation R est dite en troisième forme normale (3NF) ssi lorsque X → A est dans F+ et A n’est pas
dans X, soit X est une clé primaire, soit A est un attribut clé.
Il existe deux cas dans lesquels X → A ne respecte pas la 3NF:
Cas 1: X est un sous-‐-ensemble d’une clé minimale. X → A est une dépendance partielle.
Cas 2: X n’est pas un sous-‐-ensemble de toutes les clés minimales. X → A est une dépendance
transitive. Elle crée une chaîne non triviale de DF Z → X → A pour une clé minimale Z.
Autrement dit, une relation est dite en 3NF ssi:
• elle est en 2NF,
• il n’existe pas de dépendance entre attributs non clé.
EXEMPLE 1
R=ABCD
F = {AB → C,B → D,BC → A}
AB et BC sont des clés minimales et ce sont les seules. A, B et C sont des attributs clés. D est
un attribut non clé.
EXEMPLE 2
R=VRC R(ville, rue, code)
F = {VR → C,C → V}
R est en 3NF.
EXEMPLE 3
R=SAIP
F = {SI → P ,S → A}
SI est la seule clé, et A est un attribut non clé.
S → A ne respecte pas la 3NF, étant donné que S n’est pas une clé primaire. De plus, S → A est
une dépendance partielle.
On remarque dans cet exemple que la dépendance S → A est dans F. Cependant, en général,
les dépendances non conformes à la forme normale étudiée sont dans F+ plutôt que dans F.
1.4.4 Forme normale de Boyce-‐-Codd (BCNF)
OBJECTIFS DE LA BCNF
1. élimination des dépendances partielles,
2. élimination des dépendances transitives,
3. élimination des anomalies non prises en compte par la 3NF.
DÉFINITION
On considère les définitions suivantes:
R: un schéma de relations,
F: un ensemble de DF sur R,
X: un sous-‐-ensemble de R,
A: un attribut.
R est en BCNF ssi lorsque X → A appartient à F+ et que A n’est pas dans X, alors X est une clé
de R.
Une relation en 3NF qui ne possède qu’un seule clé minimale est en BCNF.
EXEMPLE 1
M=NAC MEMBRE(nom,adresse,cotisation)
F = {n → a, n → c}
M est en BCNF.
11EXEMPLE 2
R=VRC R(ville,rue,code)
F = {VR → C,C → V}
R est en 3NF mais pas en BCNF. Dans R, on ne peut pas stocker la ville correspondante à un
code à moins de connaître une rue associée à ce code (anomalie d’insertion). En effet, C → V
est vraie et V n’appartient pas à C, alors que C ne contient aucune des clés minimales de R.
1.5 Dépendances fonctionnelles et conception de schémas
Nous l’avons déjà abordé au paragraphe 1.2.1, il existe deux méthodes pour concevoir un schéma de
bases de données qui soit en 3NF: la méthode dite synthétique, et la méthode par décomposition.
1.5.1 La méthode synthétique
L’algorithme dit de synthèse permet dʹobtenir une décomposition 3NF qui préserve les DF. Il est basé
sur le calcul de la couverture minimale (ou irredondante) dʹun ensemble de DF. Le point de départ de
cette méthode est la connaissance des attributs et d’un ensemble de dépendances fonctionnelles. On
construit le graphe des DF dans lequel chaque attribut constitue un noeud, et chaque DF est représen-‐-
tée par un arc. L’algorithme de synthèse va travailler sur ce graphe et construire un ensemble de rela-‐-
tions en 3NF.
ALGORITHME DE SYNTHÈSE
Pour obtenir un schéma de relations en 3NF, on applique l’algorithme suivant:
1. on construit une couverture minimale à partir de l’ensemble F des DF,
2. on en déduit les relations en 3NF en regroupant dans une même relation tous les attributs ayant
la même partie gauche dans le graphe des DF,
3. si aucune des relations obtenues à l’étape précédente ne contient pas (ou ne permet pas d’obte-‐-
nir) la clé de la relation initiale, on ajoute une relation composée uniquement des attributs de la
clé.
EXEMPLE
Soit la relation GESPROD (numEmp, nomEmp, numProj, budProj, emploi, taux, nbhr) qui décrit la
gestion de projet dans une entreprise. Les attributs sont les suivants: le numéro d’employé, le nom de
l’employé, le numéro du projet, le budget du projet, l’emploi occupé par l’employé, le taux de rému-‐-
nération de l’employé, et le nombre d’heures de travail de l’employé sur un projet donné. La seule clé
minimale de la relation est constituée des attributs {numEmp, numProj}. L’ensemble F des DF est le
suivant:
numEmp → nomEmp
numEmp → emploi
emploi → taux
numEmp → taux
numProj → budProj
numEmp,numProj → nbHr
Pour obtenir une décomposition de GESPROD muni de F en un ensemble de relations en 3NF, on ap-‐-
plique lʹalgorithme suivant:
1. construction de la couverture minimale: on élimine les dépendances transitives:
numEmp → taux est une DF transitive car numEmp → emploi et emploi → taux.
2. déduction des relations en 3NF en regroupant dans une même relation tous les attributs ayant
même partie gauche dans F.
EMPLOYÉ (numEmp, nomEmp, emploi)
PROJET (numProj, budProj)
RÉMUNÉRATION (emploi, taux)
OCCUPE (numEmp, numProj, nbHr)
3. on vérifie que la clé est présente dans au moins une relation. Dans notre exemple, la relation
OCCUPE possède la clé de la relation initiale.
121.5.2 La méthode par décomposition
Une autre manière de concevoir un schéma relationnel en troisième forme normale est de partir du
schéma complet (ensemble de tous les attributs) et de décomposer cette « grosse » relation (appelée
également relation universelle) en respectant les dépendances fonctionnelles. Cette approche est appelée
approche par décomposition. Le problème est dʹordonner lʹordre des décompositions de manière à
obtenir un schéma en 3ème forme normale. En effet, chaque relation produite ne conserve qu’un cer-‐-
tain nombre de DF (celles définies sur ses attributs propres) et nʹest donc pas forcément en 3ème forme
normale. De plus, lʹensemble des DF du schéma complet nʹest pas forcément préservé.
ALGORITHME DE DÉCOMPOSITION
entrée: un schéma relationnel (ensemble dʹattributs) et un ensemble E de DF entre ses attri-‐-
buts
sortie: une ou plusieurs relations en 3NF dont la jointure redonne la relation initiale (par con-‐-
tre des DF de E ont pu être perdues)
principe: lʹalgorithme peut se voir comme la construction dʹun arbre binaire. La racine de cet
arbre est la relation à décomposer. Lʹarbre se construit récursivement de la manière suivante:
1. on choisit une DF dfi dans lʹensemble E des DF,
2. le fils gauche du noeud racine est une relation composé de tous les attributs de dfi,
3. dfi est retirée de lʹensemble E,
4. le fils droit du noeud racine est une relation composée de tous les attributs de la racine ex-‐-
cepté ceux présents en partie droite de dfi.
Problèmes: la solution dépend du choix des DF selon lesquelles on choisit de décomposer et il ne pré-‐-
serve pas nécessairement les DF.
On sait néanmoins que toute relation admet une décomposition en 3NF qui préserve les DF.
EXEMPLE
Soit la relation universelle associée à la gestion de production définie au paragraphe 1.5.1:
GESPROD (numEmp, nomEmp, numProj, budProj, emploi, taux, nbhr)
On constate quʹelle n
ʹest pas en 2NF car
numEmp → nomEmp, taux, emploi
numProj → budProj
Ceci conduit à une décomposition de la relation GESPROD en trois relations en 2NF:
PROJET (numProj, budProj)
OCCUPE (numEmp, numProj, nbHr)
EMPREM (numEmp, nomEmp, emploi, taux)
On constate que la relation EMPREM n
ʹest pas en 3NF car
emploi → taux (un attribut non clé dépend fonctionnellement dʹun autre attribut non clé)
On décompose la relation EMPREM en deux relations en 3NF
EMPLOYÉ (numEmp, nomEmp, emploi)
RÉMUNÉRATION (emploi, taux)
On obtient finalement quatre relations en 3NF
PROJET (numProj, budProj)
OCCUPE (numEmp, numProj, nbHr)
RÉMUNÉRATION (emploi, taux)
EMPLOYÉ (numEmp, nomEmp, emploi)
EXEMPLE SUR LES FORMES NORMALES
Soit le schéma R = (P , H, N, Y , T), et F = {P → T | P , H → Y | H, N → P | H, Y → N}.
• ensemble des DFE engendrées:
H, N → T
P, H →N
H,N → Y
13H, Y → P
P, H →T
H, Y → T
• on a donc trois clés potentielles (H, N | P , H | H, Y):
H, N → P , T, Y
P , H → T, Y , N
H, Y → N, P , T
• les attributs clés sont donc: H, N, P , Y , et un attribut non clé est T.
• par définition le schéma est en 1ère forme normale. Est il en 2NF ?
Non, car P , H → T n
’est pas une DFE (on a P → T), R est donc en 1NF.
• application de l’algorithme de décomposition:
R(P, H, N, Y, T)
P ! T
R1(P, T) Clé P (3NF) R2(P, H, N, Y)
Clés H,N ou P,H ou H,Y (3NF) R =
R1 * R2 (pas de perte des DFs)
14CHAPITRE 2: SÉCURITÉ DE FONCTIONNEMENT
1. Les transactions
2. La tolérance aux pannes
3. La gestion de la concurrence
4. Le verrouillage sous Oracle
5. JDBC et les transactions
2.1 Les transactions
2.1.1 Définition
L’objectif de ce chapitre est d’étudier les mécanismes que fournit un SGBD pour s’assurer que les don-‐-
nées demeurent dans un état cohérent, c’est-‐-à-‐-dire qu’elles ne sont pas mises en cause par un pro-‐-
blème logiciel ou matériel, ou par le fait que plusieurs utilisateurs manipulent les données simultané-‐-
ment. En effet, les SGBD sont utilisés par plusieurs utilisateurs simultanément, à la fois pour les requê-‐-
tes ou pour des modifications sur la base de données.
Par exemple, on suppose que deux personnes souhaitent retirer 100€ d’un même compte. Un SGBD
doit s’assurer qu’aucun des deux retraits ne soit perdu. Par comparaison avec un système d’exploita-‐-
tion, deux personnes peuvent très bien éditer le même fichier, mais c’est le dernier qui écrit qui voit
ses modifications conservées. Ce comportement n’est pas imaginable dans le contexte des bases de
données.
Pour résoudre ce problème, on a introduit le concept de transaction; Une transaction est un pro-‐-
gramme qui forme une unité logique de traitement. Elle est constituée d’une ou plusieurs opérations
d’accès aux objets de la base de données (insertion, suppression, modification ou lecture). Enfin, une
transaction fait passer la base d’un état cohérent E1 à un état cohérent E2. En particulier:
• une transaction doit commencer à partir d’un état cohérent de la base,
• pendant la transaction, la base peut éventuellement être dans un état incohérent,
• lorsque la transaction se termine avec succès, la base doit être dans un état cohérent,
• lorsqu’une transaction a été validée, les modifications sur la base sont persistantes, même en cas de
problèmes logiciels ou matériels,
• plusieurs transactions peuvent s’exécuter en parallèle.
On distingue deux problèmes à prendre en compte:
• la tolérance aux pannes: il faut restaurer la base dans l’état où elle se trouvait avant l’incident. Les mé-‐-
canismes utilisés sont les transactions, la tenue d’un journal, la reprise après panne.
• l'ʹexécution concurrente de plusieurs transactions: il faut veiller à ce que l’action simultanée de plusieurs
utilisateurs sur les mêmes données ne conduise pas à une incohérence de ces données. Les méca-‐-
nismes utilisés sont la gestion des accès concurrents, les transactions, le verrouillage et la gestion de
l’interblocage.
2.1.2 Propriétés ACID
Un SGBD supporte ce que l’on appelle des transactions ACID. Les propriétés ACID sont:
• atomicité : lors de l’exécution d’une transaction, soit toutes ses actions sont exécutées, soit aucune ne
l’est,
• cohérence : après une transaction, la base se trouve dans un état cohérent,
• isolation : il n’y a pas d’incohérence liée à la concurrence d’accès,
• durabilité : les effets d’une transaction correctement exécutée survivent à une panne ultérieure.
V oyons sur un exemple ce que cela signifie. On suppose une transaction qui effectue un transfert d’ar-‐-
gent (100€) d’un compte A vers un compte B:
1. lire(A) 4. lire(B)
2. A:= A –100 5. B := B + 100
3. écrire(A) 6. écrire(B)
15La propriété d’atomicité spécifie que si la transaction échoue après l’étape 3 et avant l’étape 6, le sys-‐-
tème doit s’assurer qu’aucune mise à jour n’aura été effectuée, sous peine de voir une incohérence
entre la balance des deux comptes.
La propriété de cohérence spécifie que la somme des soldes de A et B est inchangée après l’exécution
de la transaction.
La propriété d’isolation spécifie que si une autre transaction essaie d’accéder à la base entre les étapes
3 et 6, elle ne verra pas les modifications faites aux étapes 1 à 3. L’isolation peut être assurée de ma-‐-
nière triviale en exécutant les transactions en séquence (de manière sérialisable). Cependant, nous ver-‐-
rons que permettre l’exécution concurrente des plusieurs transactions apporte des avantages, à condi-‐-
tion de ne pas avoir d’interférences entre les transactions simultanées.
Enfin, la propriété de durabilité spécifie que lorsque l’utilisateur a validé la transaction, les mises à
jour doivent persister, quelques soient les défaillances logicielles ou matérielles qui pourraient surve-‐-
nir.
2.1.3 États d’une transaction
Une transaction est une unité atomique (au sens indivisible) de travail qui doit être soit totalement
terminée soit pas du tout (atomicité). Le système doit donc savoir quand la transaction commence, se
termine, est validée ou est abandonnée. Pour cela, une transaction peut se trouver dans plusieurs
états:
• active: l’état initial. La transaction entre dans cet état immédiatement après son début d’exécution, et
elle y reste durant son exécution,
• partiellement validée: lorsque la dernière instruction de la transaction a été exécutée,
• échouée: dès que l’exécution ne peut plus continuer normalement,
• annulée: après que la transaction a été annulée, et que la base ait été restaurée dans l’état cohérent
d’avant le début de la transaction. Il existe alors deux options après qu’une transaction ait été annu-‐-
lée, soit on redémarre la transaction, soit on tue la transaction.
• validée: après une exécution totalement terminée.
En fait, SQL supporte les transactions, souvent de manière invisible. En effet, chaque commande effec-‐-
tuée dans l’outil d’interrogation est une transaction. Ainsi, chaque fois que vous faites une (ou plu-‐-
sieurs) requête(s) dans SQL/Plus, vous débutez sans le savoir une transaction.
2.1.4 Commit, rollback
L’instruction SQL COMMIT permet de valider une transaction. Cette instruction peut être explicite dans
une transaction où, comme c’est souvent le cas, implicite et exécutée à la fin de la transaction par le
SGBD. Une fois l’instruction COMMIT exécutée, les modifications faites sont permanentes et la transac-‐-
tion s’achève.
L’instruction ROLLBACK permet également d’achever la transaction, mais en l’annulant. Il n’y alors au-‐-
cun effet sur la base, et le SGBD doit alors revenir à l’état précédent le début de la transaction puisque
c’est le dernier point garanti de cohérence de la base.
2.1.5 Exemple
V oyons sur un exemple l’interaction entre deux transactions. On suppose la relation BarÀBière(bar,
bière, prix), et on suppose que le bar Jo vend de la Chimay (3,00€) et de la Leffe (2,50€). Paul interroge
la base, et la relation BarÀBière pour connaître le prix minimum et le prix maximum du bar Jo. Entre-‐-
temps, Jo décide de cesser de vendre de la Chimay et de la Leffe, pour ne plus vendre que de la Kwak
à 3,50€.
Paul exécute les deux instructions SQL suivantes afin de connaître les prix minimum et maximum:
(max) SELECT MAX(prix) FROM BarÀBière
WHERE bar = ‘Jo’;
(min) SELECT MIN(prix) FROM BarÀBière
WHERE bar = ‘Jo’;
16Pendant ce temps, Jo exécute les instructions suivantes:
(del) DELETE FROM BarÀBière
WHERE bar = ‘Jo’;
(ins) INSERT INTO BarÀBière
VALUES(‘Jo’, ‘Kwak’, 3.50);
On a des instructions SQL qui peuvent être entrelacées, avec les contraintes suivantes: (max) doit être
exécuté avant (min), et (del) doit être exécuté avant (ins). Que se passe-‐-t-‐-il lorsque Jo et Paul mettent à
jour la base ? Si les instructions ont lieu dans l’ordre suivant: (max)(del)(ins)(min), on obtient:
Prix 2,50 | 3,00 2,50 | 3,00 3,50
Instruction (max) (del) (ins) (min)
Résultat 3,00 3,50
Ainsi, Paul voit que MAX < MIN !
Comment peut-‐-on résoudre le problème avec les transactions ? Si l’on regroupe les instructions
(max)(min) de Paul dans une seule transaction, alors il n’y aura plus de problèmes. En effet, soit la
transaction s’exécutera avant les modifications de Jo, et Paul verra alors les anciens prix, soit la trans-‐-
action s’exécute après la modification, et il n’y aura pas de problème. La transaction permet donc aux
deux instructions (max)(min) de s’exécuter sur les mêmes données.
Il existe cependant encore une possibilité de comportement étrange. Supposons que Jo exécute sa mo-‐-
dification de prix, mais qu’au dernier moment, il change d’avis et exécute un ROLLBACK. Si Paul
exécute sa transaction après l’instruction (ins), mais avant l’annulation, il va voir une valeur 3,50 qui
n’existe pas dans la base. Pour résoudre ce problème, on va donc exécuter les instructions de Jo dans
une transaction. Ainsi, les effets de (del)(ins) dans une transaction ne pourront être vus par d’autres
transactions que lorsque la transaction aura été validée. Si la transaction venait à être annulée, ses ef-‐-
fets ne seraient pas vus par les autres transactions.
2.1.6 Gestion des transactions dans Oracle
Une transaction débute avec la première instruction SQL exécutable et se termine lors de l’exécution
d’un commit ou d’un rollback, lors de la déconnexion de l’utilisateur (commit), ou lors d’un arrêt
anormal du processus utilisateur (rollback).
Les mises à jour faites par une transaction ne sont visibles pour les autres utilisateurs qu’après la vali-‐-
dation de la transaction (tant qu'ʹune transaction n'ʹest pas validée, les autres utilisateurs accèdent aux
anciennes valeurs des données modifiées).
2.2 La tolérance aux pannes
2.2.1 Journal
Il existe plusieurs types d’incidents qui peuvent survenir sur une base de données :
• échec d’une transaction: une erreur logique dans le programme l'ʹempêche de se poursuivre norma-‐-
lement (erreur lors d'ʹune insertion, suppression ou mise à jour), ou une erreur système arrête le dé-‐-
roulement normal du programme (verrouillage, saturation, processus tué),
• crash système: il entraîne la perte des données en mémoire centrale,
• panne disque: elle provoque la perte physique des données.
Les algorithmes de récupération (recovery) sont des techniques qui permettent aux SGBD d’assurer la
cohérence, l’atomicité et la durabilité malgré les incidents qui peuvent survenir. En général, les algo-‐-
rithmes de récupération possèdent deux parties: la première prend en charge les actions qui ont lieu
lors du déroulement normal de la transaction afin d’avoir assez d’informations pour permettre la ré-‐-
cupération en cas de problème, et la deuxième qui prend en charge les actions à effectuer après un
problème afin de pouvoir récupérer la base dans un état cohérent.
17Pour assurer la reprise sur panne, les SGBD et Oracle en particulier utilisent la notion de journal. Un
journal est un fichier texte dans lequel le SGBD inscrit, dans l’ordre d’exécution, toutes les actions de
mise à jour qu’il effectue. Ainsi, le journal est une séquence d’enregistrements qui mémorise les mises
à jour faites sur la base. Lorsqu’une transaction Ti démarre, elle s’enregistre dans le journal sous la
forme <début transaction, Ti >. Avant que la transaction Ti exécute une instruction écrire(X), un enregis-‐-
trement <Ti, X, V1, V2> est écrit dans le journal (V1 est la valeur de X avant l’écriture, et V2 est la valeur
de X après l’écriture). Lorsque la transaction Ti a lu une valeur, un enregistrement <lecture, Ti, X> est
écrit dans le journal. Enfin, <valider, Ti> ou <annuler, Ti> sont écrits dans le journal suivant que la
transaction a été validée ou annulée.
En Oracle, la gestion des transactions utilise deux fichiers :
• un fichier journal redo log: il enregistre toutes les modifications effectuées (insert, update, delete)
dans les tables de la base par chaque transaction.
• un fichier rollback segment: il enregistre les anciennes valeurs des lignes des tables modifiées par
une transaction.
Le système affecte à chaque transaction un numéro chronologique (SCN – System Control Number) qui
permet de l’identifier de manière unique. Toute opération modifiant une donnée de la base est enregis-‐-
trée dans le fichier rollback segment et dans le fichier journal redo log avant mise à jour de la base. Le
journal redo log est chronologique.
Lors du commit d'ʹune transaction, il faut :
• enregistrer le commit de la transaction dans les fichiers redo log et rollback segment,
• débloquer les lignes des tables verrouillées par la transaction.
Lors du rollback d'ʹune transaction, il faut :
• redonner les anciennes valeurs à toutes les lignes des tables modifiées par la transaction (à partir des
rollback segment),
• débloquer les lignes des tables verrouillées par la transaction.
2.2.2 Reprise après incident
Elle est disponible uniquement pour les incidents sans perte de données sur disque. L’objectif est de
restaurer la base dans un état cohérent telle qu'ʹelle se trouvait juste avant la panne. Le mécanisme de
reprise est le suivant:
• appliquer toutes les modifications enregistrées dans le fichier redo log à la base de données (roll-‐-
forward)
• pour toutes les transactions sans commit, on remet les lignes des tables concernées aux anciennes
valeurs (rollback). Ceci est fait à partir des rollback segment.
Après un incident, on ne traite que les modifications effectuées après le point de reprise (ou point de
contrôle). Un point de reprise consiste à 1) écrire les buffers du fichier redo log sur disque, 2) écrire les
buffers de la base de données sur disque, 3) écrire un article point de reprise dans le fichier redo log.
On peut préciser un point de reprise en utilisant la commande SAVEPOINT pdr ;. Par la suite, on
pourra revenir à ce point en utilisant la commande ROLLBACK TO pdr; qui permet de retrouver l’envi-‐-
ronnement tel qu’il était lors de la déclaration du point de reprise.
SQL Résultats
SA VEPOINT a; Premier point de reprise de la transaction
DELETE …; Modification de la base
SA VEPOINT b; Deuxième point de reprise de la transaction
INSERT INTO…; Modification de la base
SA VEPOINT c; Troisième point de reprise de la transaction
UPDATE …; Modification de la base
18ROLLBACK TO c; L’ordre UPDATE est annulé, le point C reste défini
ROLLBACK TO b; L’ordre INSERT est annulé, le point C est perdu, le point B reste défini
ROLLBACK TO c; ORA-‐-01086 error; savepoint C no longer defined
INSERT TO…; Modification de la base
COMMIT; Valide toutes les actions effectuées par le DELETE (première modification)
et le INSERT (dernière modification). Toutes les autres modifications ont été
annulées avant le COMMIT. Le point A n’est plus actif.
EXEMPLE: traitement des transactions
La mise en œuvre du mécanisme de reprise s’effectue comme ceci. Soient les 5 transactions suivantes
au moment d'ʹun incident :
T1
T2
T3
T4
T5
Point de reprise Incident
• T1 est achevée lors du point de reprise, elle n'ʹest pas traitée.
• T2 et T4 sont validées (commit) lorsque survient l'ʹincident: on applique toutes les modifications en-‐-
registrées dans le fichier redo log à la base de données (rollforward); pour T2, on repart du point de
reprise.
• T3 et T5 ne sont pas validées (pas de commit) lorsque survient l'ʹincident, on remet les lignes des
tables concernées aux anciennes valeurs (rollback).
2.3 La gestion de la concurrence
La gestion des accès concurrents aux données permet d’éviter que la mise à jour simultanée des mê-‐-
mes données par plusieurs utilisateurs n’introduise pas des incohérences dans la base de données. On
dit que deux transactions sont concurrentes si elles accèdent simultanément aux mêmes données.
2.3.1 Accès concurrents et incohérence des données
V oici quelques problèmes classiques qui peuvent survenir avec des transactions concurrentes.
La perte de mise à jour
Il y a perte de mise à jour quand une transaction T2 vient écraser une écriture effectuée par T1.
Temps t1
t2
t3
t4
t5
t6
t7
Transaction T1 État de la base Transaction T2
lire(A)
…
A = A + 10
…
…
écrire(A)
…
A = 10
A = 20
A = 60
…
lire(A)
…
…
A = A+50
…
écrire(A)
Après une exécution séquentielle de T1 et T2 ou T2 et T1, on obtient A=70. Si les transactions sont exé-‐-
cutées de manière concurrentes, on obtient alors A=60. On a donc perdu la première mise à jour.
19Les lectures impropres
Supposons une transaction T2 qui lit une donnée A modifiée par T1. La transaction T1 est annulée et
les modifications effectuées par cette transaction sont défaites. La valeur lue et traitée par T2 est alors
incorrecte.
Temps Transaction T1 État de la base Transaction T2
t1
t2
t3
t4
t5
lire(A)
A = A +20
écrire(A)
…
rollback
A = 10
A = 30
A = 10
…
…
…
lire(A)
…
Les lectures non reproductibles
La transaction T2 lit la même donnée A à deux instants différents et n'ʹobtient pas la même valeur. En-‐-
tre les deux lectures, une autre transaction a modifié la valeur de A.
Temps Transaction T1 État de la base Transaction T2
t1
t2
t3
t4
t5
A = 10
…
lire(A)
A = A + 10
écrire(A)
commit
A = 20
lire(A)
…
…
…
lire(A)
2.3.2 Le mécanisme de verrouillage
Les principales techniques mises en œuvre pour le contrôle de l’exécution concurrente des transac-‐-
tions reposent sur le concept de verrouillage des données. Un verrou est une variable associée à une
donnée qui décrit l’état de la donnée, compte tenu des opérations qui peuvent lui être appliquées.
Ainsi, avant d'ʹaccéder à une donnée pour modifier sa valeur, la transaction T1 doit la verrouiller pour
éviter son accès par une autre transaction. Une fois terminée, la transaction T1 libère alors les données
verrouillées pour les rendre disponibles à d'ʹautres transactions.
Nous reprenons l'ʹexemple du transfert d'ʹune somme d'ʹargent entre deux comptes: T1 fait un transfert
de c1 vers c2, T2 de c1 vers c3.
T1 T2
lock(c1)
read(c1) for update
c1:=c1-‐-m1 T2 attend la libération de c1
écrire(c1) (demande accès pour update de c1)
lock(c2) "ʺ
read(c2) for update "ʺ
c2:=c2+m1 "ʺ
écrire(c2) "ʺ
unlock(c1,c2) lock(c1)
read(c1) for update
c1:=c1-‐-m2
écrire(c1)
lock(c3)
read(c3) for update
c3:=c3+m2
écrire(c3)
20unlock(c1,c3)
Le verrouillage tel qu'ʹil est appliqué ci-‐-dessus permet d'ʹéliminer les pertes de mise à jour et les lectu-‐-
res impropres. Par contre, il ne permet pas d'ʹéliminer les lectures non reproductibles.
Les verrous classiques sont les verrous binaires, c’est-‐-à-‐-dire des verrous qui peuvent avoir deux va-‐-
leurs distinctes: verrouillé ou non verrouillé (1 ou 0). Un verrou est associé à chaque élément X. Si la
valeur du verrou sur X est 0, alors il est possible d’accéder à l’élément. Le verrouillage binaire utilise
deux opérations: verrouillerÉlément et déverrouillerÉlément. Une transaction demande l’accès à
un élément X en exécutant pour commencer l’opération verrouillerÉlément(X). Si le verrou est à 1,
la transaction doit attendre. Si le verrou est à 0, le verrou est mis à 1, et la transaction est autorisée à
accéder à l’élément X. Lorsque la transaction n’a plus besoin d’utiliser l’élément, elle exécute une opé-‐-
ration déverrouillerÉlément(X) qui positionne le verrou à 0 afin que les autres transactions puis-‐-
sent accéder à X. Un verrou binaire applique donc une exclusion mutuelle sur une donnée.
On se rend compte rapidement que les verrous binaires sont trop restrictifs pour les bases de données,
car certaines transactions ne veulent que lire certaines données. On distingue donc deux types de ver-‐-
rous, les verrous partagés, qui permettent à plusieurs transactions de lire une donnée verrouillée par
une transaction, et les verrous exclusifs, qui permettent à la transaction qui a posé le verrou d’effec-‐-
tuer une opération d’écriture.
2.3.3 Le risque d'ʹinterblocage
Un interblocage (ou verrou mortel) survient lorsque chaque transaction T d’un ensemble de n (n ≥ 2)
transactions attend une donnée verrouillée par une autre transaction T’ de l’ensemble. Autrement dit,
T1 attend une donnée verrouillée par T2, et T2 attend une donnée verrouillée par T1.
EXEMPLE : transfert entre deux comptes.
T1 transfère une somme m d’un compte c1 vers un compte c2, et T2 transfère une somme n de c2 vers
c1. L'ʹexécution simultanée des deux transactions conduit à la situation suivante :
T1 T2
lock(c1)
read(c1)
c1:=c1+m lock(c2)
écrire(c1) read(c2)
c2:=c2+n
T1 attend libération de c2 "ʺ écrire(c2)
T2 attend libération de c1
"ʺ "ʺ
"ʺ "ʺ
Les données sont verrouillées en fonction des demandes de mises à jour, mais ne sont libérées qu’en
fin de transaction
2.3.4 Résolution de l'ʹinterblocage (deadlock)
Une approche pratique de la gestion des interblocages repose sur la détection de ceux-‐-ci: le système
vérifie s’il y a une situation d’interblocage. Un procédé pour détecter une situation d’interblocage con-‐-
siste pour le système à construire et à maintenir un graphe d’attente des ressources (wait-‐-for graph).
Dans ce graphe, un nœud est créé pour chaque transaction en cours d’exécution. Chaque fois qu’une
transaction Ti attend de pouvoir verrouiller une donnée X verrouillé par une transaction Tj, un arc est
créé entre les deux transactions. Il y a situation d’interblocage si et seulement si il existe un cycle dans
le graphe. Il se pose alors le problème de savoir quand le système doit vérifier la présence d’un inter-‐-
blocage (nombre de transactions, durée d’attente de plusieurs transactions,…). Si le système détecte
l’interblocage, il tue une (ou plusieurs) des transactions impliquées. Il existe différentes solutions pour
le choix de la transaction à tuer : la plus récente, celle qui a fait le moins de mises à jour … D’autres
solutions plus élaborées peuvent être utilisées, mais ne seront pas traitées dans le cadre de ce cours.
Une autre possibilité pour gérer les interblocages consiste à employer des mises hors délais (timeouts).
21Cette méthode est pratique en raison du peu d’activité qu’elle implique sur le système. Si une transac-‐-
tion attend plus longtemps que la durée spécifiée pour la mise hors délai, le système suppose qu’elle
est bloquée et il tue cette transactions, qu’il y ait ou non interblocage.
La détection des interblocages
Pour détecter les interblocages, on construit le graphe d’attente des ressources :
X
T1 T2
Y
X, Y ,… représentent des éléments des tables de la base. T1, T2 …. identifient des transactions. Un arc
orienté étiqueté X ou Y entre Ti et Tj signifie que la transaction Ti attend la libération de X ou Y . L'ʹin-‐-
terblocage se traduit par un circuit dans le graphe d’attente des ressources, comme dans la figure ci-‐-
dessus.
RAPPEL: l'ʹinterblocage peut mettre en jeu n (n≥2) transactions.
X T2
T1
Y
Z
T3
2.3.5 Niveaux d'ʹisolation
SQL définit quatre niveaux d’isolation qui permettent de choisir quelles sont les types d’interactions
autorisées pour les transactions qui s’exécutent simultanément (concurrentes). Ainsi, dans une trans-‐-
action, on peut utiliser l’instruction suivante:
SET TRANSACTION ISOLATION LEVEL X
où X = SERIALIZABLE | REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED
T ransactions de niveau serializable
Si on reprend l’exemple de la section 4.1.5, et si on suppose que Paul = (max)(min) et Jo = (del)(ins)
sont des transactions, et si Paul utilise le niveau d’isolation SERIALIZABLE, alors il verra la base dans
l’état soit avant les modifications de Jo, soit après, mais pas entre les deux opérations de la transaction
de Jo.
Le niveau d'ʹisolation est un choix qui affecte uniquement la vue de la base de la transaction que le
spécifie. Si on reprend notre exemple (cf section 4.1.5), si Jo choisit le niveau SERIALIZABLE, mais pas
Paul, alors Paul peut éventuellement ne voir aucun prix si la requête est exécutée entre (del) et (ins).
T ransactions de niveau repeatable read
Seules les données validées peuvent être lues, ce qui implique que les lectures répétées dans une
même transaction retourne les mêmes valeurs (pas de phénomène de lectures non reproductibles).
Cependant, une transaction pourra voir apparaître au cours des lectures répétées de nouveaux n-‐-u-‐-
plets (ou des n-‐-uplets qui ont disparu).
Sur notre exemple, si Paul a choisi le niveau REPEATABLE READ, et que l’ordre d’exécution est
(max)(del)(ins)(min), alors (max) verra les prix 2,50 et 3,00, et (min) verra 3,50, mais également 2,50 et
3,00 car ils ont été vus par la lecture précédente de (max) dans la transaction.
T ransactions de niveau read committed
Seules les données validées peuvent être lues, mais des lectures successives peuvent renvoyer des va-‐-
leurs (validées) différentes. Cela permet de voir les modifications apportées par d’autres transactions.
22Sur notre exemple, si Paul a choisi le niveau READ COMMITTED, alors il peut voir les valeurs validées,
mais pas nécessairement les mêmes à chaque requête. Ainsi, avec READ COMMITTED, l’entrelacement
(max)(del)(ins)(min) est autorisé, aussi longtemps que Jo valide (mais Paul peut voir MAX < MIN).
T ransactions de niveau read uncommitted
Une transaction qui s’exécute en niveau d’isolation READ UNCOMMITTED peut voir des données dans la
base qui ne sont pas validées par une autre transaction (et qui ne le seront peut-‐-être jamais).
Sur notre exemple, si Paul a choisi le niveau READ UNCOMMITTED, il pourra voir le prix 3,50, même si Jo
abandonne la transaction.
2.3.6 V errouillage et niveaux de granularité
Les performances du contrôle de la concurrence est affectée par la taille des éléments à verrouiller. Par
exemple, dans une base de données, on a la valeur d’un attribut d’un n-‐-uplet, un n-‐-uplet, une table, ou
toute la base. Selon que l’on pose un verrou sur un élément particulier, on peut bloquer ou non plu-‐-
sieurs transactions. En particulier, il faut remarquer que plus la taille des éléments à verrouiller est
importante, plus le degré de concurrence autorisé est faible. Par exemple, si une transaction veut blo-‐-
quer toute une table (et si elle ne souhaite accéder qu’à un n-‐-uplet particulier), toutes les autres trans-‐-
actions seront mises en attente alors qu’il n’est peut être pas nécessaire de bloquer toute la table. In-‐-
versement, si on verrouille des éléments de taille plus petite, il peut y avoir beaucoup d’éléments à
verrouiller, et donc le gestionnaire de verrouillage devra gérer un plus grand nombre de verrous
(beaucoup d’opérations de verrouillage/déverrouillage). La nature des verrous à poser dépend donc
de la nature des transactions. Par exemple, si une transaction accède à un petit nombre d’enregistre-‐-
ments, il est préférable que la granularité soit l’enregistrement. Par contre, si une transaction accède à
de nombreux enregistrements d’une même table, alors la granularité qui semble la plus appropriée
semble être la table.
2.4 Le verrouillage sous Oracle
2.4.1 Principe
Oracle implante un verrouillage au niveau de la ligne, et utilise un mécanisme appelé Read consistency
(lecture cohérente). Grâce à ce mécanisme, les mises à jour et les lectures ne se bloquent pas mutuel-‐-
lement. Toutes les données retournées par un SELECT proviennent d’un seul point dans le temps. On
ne voit que les données validées au moment du SELECT. Pour les données non validées, on voit les
anciennes valeurs (grâce au Rollback segment). Les données modifiées par une autre transaction après
le début du SELECT ne sont pas vues.
Il existe une concurrence d’accès en mise à jour: la première transaction qui accède à une donnée posi-‐-
tionne un verrou sur les données accédées (n-‐-uplets ou tables), les autres transactions souhaitant accé-‐-
der les mêmes données seront mises en attente.
Ce mécanisme ne prend pas en compte les lectures non reproductibles. On peut, pour résoudre ce
problème, utiliser une transaction spéciale appelée une transaction à lecture seulement (Read Only
T ransaction). Cette transaction conserve, lorsqu'ʹelle démarre, l’état de la base et travaille ensuite uni-‐-
quement sur cet état, jusqu'ʹà la fin de la transaction. Une telle transaction ne doit comporter que des
lectures de la base, et les modifications des données de la base sont interdites. La syntaxe est:
SET TRANSACTION READ ONLY
instruction 1
…
instruction n
COMMIT
2.4.2 Niveaux d’isolation
En fixant le niveau d’isolation des transactions, on définit le mode de fonctionnement en parallèle des
différentes transactions qui s’exécutent au même moment. La commande suivante indique le niveau
d’isolation de la transaction qui vient de commencer :
23SET TRANSACTION ISOLATION LEVEL {SERIALIZABLE | READ COMMITTED}
Oracle permet deux niveaux d’isolation des transactions les unes par rapport aux autres :
• READ COMMITTED : c’est le mode par défaut des transactions d’Oracle. Il empêche les principaux
problèmes de concurrence mais pas les lectures non reproductibles. Tout d’abord, les modifications
effectuées par une transaction ne sont connues des autres transactions que lorsque la transaction a
été confirmée (COMMIT). Oracle gère automatiquement les accès concurrents de plusieurs transac-‐-
tions sur les mêmes n-‐-uplets de table. Si une transaction est en train de modifier des n-‐-uplets d’une
table, les autres transactions peuvent lire les données telles qu’elles étaient avant ces dernières mo-‐-
difications, mais les autres transactions sont bloquées automatiquement par Oracle si elles souhai-‐-
tent modifier ces mêmes lignes.
• SERIALIZABLE : si une transaction SERIALIZABLE essaie de modifier une donnée qui pourrait avoir
été modifiée par une autre transaction non validée au début de la transaction SERIALIZABLE, alors
l’ordre de modification échoue (résolution du problème de lecture non reproductibles). Ce mode est
coûteux puisqu’il limite le fonctionnement en parallèle des transactions (les transactions s’exécutent
concurremment comme si elles s’exécutaient les unes après les autres).
2.4.3 Différents niveau de verrouillage
V errouillage de niveau n-‐-uplet
Par défaut, Oracle met en œuvre un verrouillage de niveau n-‐-uplet, c’est-‐-à-‐-dire une stratégie de ver-‐-
rouillage au niveau des n-‐-uplets, chaque n-‐-uplet d’une table pouvant être verrouillé individuellement.
Les n-‐-uplets verrouillés peuvent alors être mis à jour uniquement par la transaction qui les a ver-‐-
rouillés. Tous les autres n-‐-uplets de la table peuvent être mis à jour par d’autres transactions. De plus,
les autres transactions gardent également la possibilité de lire les n-‐-uplets, y compris ceux qui sont mis
à jour. Pour ces derniers, les transactions ont accès à l’ancienne valeur (grâce au rollback segment) jus-‐-
qu’à ce que la transaction soit validée (lecture cohérente).
Lorsqu’une transaction pose un verrou sur un n-‐-uplet, Oracle effectue les opérations suivantes:
• Premièrement, un verrou DML (data manipulation language) est posé. Ce verrou évite que d’autres
transactions puissent mettre à jour (ou poser un verrou) sur le n-‐-uplet. Ce verrou ne sera relâché que
lorsque la transaction qui a posé le verrou aura été validée ou annulée,
• Deuxièmement, un verrou DDL (data dictionary language) est posé sur la table afin d’éviter les modifi-‐-
cations structurelles de la table (suppression de la table, retrait ou ajout d’un attribut,…). Ce verrou
ne sera relâché que lorsque la transaction qui a posé le verrou aura été validée ou annulée.
V errouillage de niveau T able
Avec le verrouillage au niveau table, la table entière est verrouillée. Dès qu’une transaction a ver-‐-
rouillé une table, seule cette transaction peut mettre à jour (ou verrouiller) n’importe quel n-‐-uplet de la
table. Aucun des n-‐-uplets de la table ne peut être mis à jour par une autre transaction. Cependant, les
autres transactions peuvent malgré tout lire n’importe quel n-‐-uplet, y compris ceux qui sont mis à
jour.
Relâcher les verrous
Souvent, les utilisateurs pensent être seuls au monde. C’est précisément ce genre de comportement
qui crée les problèmes de blocage. Souvenez-‐-vous que poser un verrou (sur un n-‐-uplet ou sur une ta-‐-
ble) n’est pas une opération anodine, et que cela peut bloquer beaucoup d’autres transactions. C’est
pourquoi il faut veiller à verrouiller de manière approprié, c’est-‐-à-‐-dire qu’il faut protéger uniquement
la partie de votre transaction qui est critique (mise à jour, calcul d’une moyenne, somme,…), et qu’il
faut également relâcher le verrou. Il faut donc être conscient que l’on relâche un verrou en validant
(COMMIT) ou en annulant (ROLLBACK) la transaction.
2.4.4 Les différents modes de verrouillage
Oracle propose deux modes de verrouillage:
24• le mode exclusif (X) qui empêche les ressources verrouillées d’être partagées. C’est le mode
privilé-‐- gié pour mettre à jour des données. La transaction qui pose un verrou exclusif la
première est la seule transaction qui peut modifier la table, et ce jusqu’à ce que le verrou soit
relâché.
• le mode partagé (S) permet à une ressource d’être partagée. Plusieurs transactions peuvent avoir
un verrou partagé et peuvent ainsi éviter qu’une autre transaction obtienne un verrou exclusif.
Oracle gère les types de verrous suivants: row share (RS), row exclusive (RX), share (S), share
row exclusive (SRX), et exclusive (X).
V errous exclusifs
SQL V errou
SELECT … FROM table… pas de verrou
INSERT INTO table… RX
UPDATE table… RX
DELETE FROM table… RX
LOCK TABLE table IN ROW EXCLUSIVE MODE RX
LOCK TABLE table IN SHARE ROW EXCLUSIVE MODE SRX
LOCK TABLE table IN EXCLUSIVE MODE X
V errous partagés
SQL V errou
SELECT … FROM table FOR UPDATE OF… RS
LOCK TABLE table IN ROW SHARE MODE RS
LOCK TABLE table IN SHARE MODE S
LOCK TABLE table IN SHARE ROW EXCLUSIVE MODE SRX
2.5 JDBC et les transactions
2.5.1 JDBC = Java DataBase Connectivity
JDBC est une API d’accès aux systèmes de gestion de base de données relationnelles qui permet
d’exécuter des requêtes SQL au sein d’un programme Java et de récupérer les résultats, ce qui
représente une alternative aux solutions propriétaires. C’est de plus une tentative de standardiser
l’accès aux bases de données car l’API est indépendante du SGBD choisi, pourvu que le pilote
JDBC existe pour ce SGBD, et qu’il implémente les classes et interfaces de l’API JDBC.
Pour effectuer un traitement avec une base de données, il faut :
1. charger un pilote en mémoire,
2. établir une connexion avec la base de données,
3. récupérer les informations relatives à la connexion,
4. exécuter des requêtes SQL et/ou des procédures stockées,
5. récupérer les informations renvoyées par la base de données (si nécessaire),
6. fermer la connexion.
Pour plus de détails, consulter le polycopié sur JDBC.
252.5.2 Gestion des transactions
L’instance de l’objet Connection fournit les méthodes pour :
Activer/désactiver la validation automatique de chaque requête passée (activé par défaut) :
public void setAutoCommit(boolean autoCommit) throws SQLException;
Valider manuellement la/les requête(s) passée(s) :
public void commit() throws SQLException;
Annuler les dernières modifications faites par la/les requête(s) passée(s) :
public void roolback() throws SQLException;
Exemple :
String sql1 = "UPDATE vendeur SET sal = 1215 WHERE sal < 1215";
String sql2 = "DELETE FROM vendeur WHERE sal < 1215";
try {
[Link](false);
Statement state = [Link]();
[Link](sql1);
Statement state2 = [Link]();
[Link](sql2);
[Link]();
...
} catch (Exception e) {
try{
[Link]();
} catch (SQLExection e) {
...
}
...
}
JDBC supporte le mode transactionnel qui consiste à valider tout ou une partie d’un ensemble
d’instructions. Nous avons déjà décrit à la section « Interface Connection » les méthodes qui
permettent à un programme Java de coder des transactions (setAutoCommit, commit et rollback).
Par défaut, chaque instruction SQL est validée (on parle d’autocommit). Lorsque ce mode est
désactivé, il faut gérer manuellement les transactions avec commit ou rollback.
Quand le mode autocommit est désactivé :
La déconnexion d’un objet Connection (par la méthode close) valide implicitement la
transaction (même si commit n’a pas été invoqué avant la déconnexion).
Chaque instruction (CREATE, ALTER, DROP) valide implicitement la transaction.
26