Vous êtes sur la page 1sur 21

Licence MI2E 2007-2008

Bases de Donnes : exercices corrigs

Maude Manouvrier

La reproduction de ce document par tout moyen que ce soit est interdite conformment aux articles L111-1 et L122-4 du code de la proprit intellectuelle

Attention, ce document peut comporter des erreurs, utiliser donc en connaissance de cause!!

Passage au relationnel
Exercice 1
Enonc de l'exercice
CLIENT SEANCECODE ClientID Nom Prnom Adresse DateNaissance 0:N 0:N ASSISTE_A NombreFautes 1:1 1:M SEANCEID DATE HEURE CLIENT SEANCECODE ClientID Nom Prnom Adresse DateNaissance EST_AUTORISE_A_PASSER 0..8 1..* ASSISTE_A * SEANCEID DATE HEURE * RESULTAT_SEANCE NombreFautes

EST_AUTORISE A PASSER NombreFautes

EST_DIFFUSE PENDANT

RESULTAT_EXAM NombreFautes CDROM * CdRomID Editeur SrieID EST_DIFFUSE_PENDANT 1

CDROM 0:8 EXAMEN_CODE PassageCodeID Date Heure LieuExamen CdRomID Editeur 6:6

EXAMEN_CODE PassageCodeID Date Heure LieuExamen

EST_COMPOSE_DE

EST COMPOSE 40 CONTIENT 1..* POSITION_QUESTION Numro MODELISATION UML

1 DE 6

QUESTION QuestionID Intitul Rponse NiveauDifficult Thme 1:N CONTIENT Numro

0:N 40:40

1:1 QUESTION SERIE SrieID QuestionID Intitul Rponse NiveauDifficult Thme

SERIE SrieID

MODELISATION ENTITE ASSOCIATION

Figure 1: Modlisation E/A et UML de la base de donnes d'une l'auto-cole. Une auto-cole souhaite construire une base de donnes pour grer les examens thoriques du code de la route de ses lves. Chaque lve est identi par un numro unique et est caractris par un nom, un prnom, une adresse et une date de naissance. Chaque lve assiste plusieurs sances de code (autant qu'il le souhaite). Chaque sance est caractrise par une date et une heure. A chaque sance de code, le directeur de l'auto-cole choisit une srie de questions sur un CD-ROM. Chaque CD-ROM est identi par un numro et est caractris par un nom d'diteur. Chaque CD-ROM est compos de 6 sries, numrotes de 1 6. Chaque srie est compose de 40 questions. Chaque question est identie par un intitul et est caractrise par une rponse, un niveau de dicult et un thme. Une mme question peut apparatre dans plusieurs sries avec un numro d'ordre pour chaque srie ; par exemple une mme question peut apparatre comme question N 2 dans la srie 5 du CD-ROM 15 et comme question N 12 dans la srie 3 du CD-ROM 4. Une mme srie peut tre projete plusieurs fois des sances direntes. Lorsqu'un lve assiste une sance, il obtient le nombre de fautes (une note sur 40) qu'il a fait pour la srie passe pendant la sance. 2

Lorsqu'un lve a obtenu, au cours des quatre dernires sances auxquelles il a assistes, un nombre de fautes infrieur ou gal 5, le directeur de l'auto-cole l'autorise passer l'examen thorique du code de la route une date donne (un seul examen pour une date donne). L'auto-cole ne peut prsenter que 8 lves maximum chaque date d'examen. Les lves ayant obtenu plus de 5 fautes l'examen sont recals et doivent assister de nouveau des sances de code avant de pouvoir se reprsenter l'examen. La base de donnes doit permettre de rpondre des requtes telles que "Quel est le nombre moyen de fautes pour la srie 5 du CD-ROM 14?", "Quels lves peuvent se prsenter au prochain examen du code de la route ?", "Quels lves ont chou au moins une fois l'examen ?" etc. La gure 1 prsente la modlisation Entit/Association (format Merise) et la modlisation UML de l'nonc. Les explications ne sont donnes que pour le schma E/A mais peuvent tre adaptes au schma UML. Pour une comprhension de la dirence entre une modlisation E/A ou UML et le passage au relationnel, vous pouvez vous reporter l'ouvrage [4]. Les schmas de modlisation ci-avant sont smantiquement clairs. Nanmoins, quels points ncessitent d'tre prciss.

L'ensemble d'entits Serie est un ensemble d'entits faibles de CD-ROM, au format Merise (ou une association qualie en UML). En eet, ce choix de modlisation a t fait pour reprsenter le fait que le numro d'une srie est relatif au CD-ROM auquel la srie appartient. Les cardinalits de l'association entre les ensembles d'entits Serie et CD-ROM sont 1:1-6:6, car une srie appartient un unique CD-ROM et un CR-ROM contient exactement 6 sries de questions. Le principe est le mme pour les cardinalits de l'association entre Serie et Question : une srie contient exactement 40 questions (cardinalit 40 : 40). En revanche, une mme question peut apparatre dans plusieurs sries avec un numro d'ordre dirent chaque fois, d'o la cardinalit 1 : N et l'attribut Numro qui caractrise l'assocation contient. L'attribut NombreFautes est un attribut de l'association entre les ensembles d'entits Client et Examen_Code et de l'association entre les ensembles d'entits Client et Seance_Code. En eet, cet attribut caractrise l'association et non pas un client, une sance de code ou encore un examen de code. Il caractrise le lien entre deux entits de ces ensembles.
Dduisez le schma relationnel de la base de donnes correspondante. Vous prciserez les cls primaires des relations en les soulignant ainsi que les cls trangres en les signalant par un # et en prcisant quoi elles font rfrence. Dans votre schma relationnel, chaque relation doit tre spcie de la manire suivante : N om(att1 ,...,attn ) o N om est le nom de la relation et att1 , ..., attn sont des noms d'attributs. Le nom de la relation doit obligatoirement avoir un lien avec les noms des ensembles d'entits (classes) ou des associations du schma de modlisation de la question 1. Vous donnerez des explications claires et concises du passage au relationnel. Vous prciserez notamment pourquoi et comment vous crez ou modiez certaines relations (1 ligne maximum par relation).

Correction de l'exercice 1
Le modle relationnel dduit de la modlisation ci-dessus est le suivant. Les cls primaires sont soulignes. Les cls trangres sont prcdes d'un '#'. Pour un rappel de ces notions, vous pouvez vous rfrer aux pages 56 60 de [2]. Le passage d'un schma de modlisation un modle relationnel est rappel aux pages 120 143 de [4].

Client(ClientID, Nom, Prnom, Adresse, DateNaissance) Cette relation est dduite du passage au relationnel de l'ensemble d'entits (ou classe) Client. CD-ROM(CdRomID, Editeur) Cette relation est dduite du passage au relationnel de l'ensemble d'entits (ou classe) CDROM.
3

Question(QuestionID, Intitul, Rponse, NiveauDicult, Thme) Cette relation est dduite du passage au relationnel de l'ensemble d'entits (ou classe) Question. Serie(SerieID, #CdRomID) Cette relation est issue du passage au relationnel de l'ensemble d'entits (classes) Serie. En modlisation E/A, l'ensemble d'entits Serie tant un ensemble d'entits faibles de CRROM, la cl primaire de la relation Serie est compose de l'identicateur de la srie et de l'identicateur du CD-ROM auquel la srie appartient. ContenuSerie(#QuestionID, SerieID, #CdRomID, Numro) Cette relation est dduite du passage au relationnel de l'association Contient. Le couple d'attributs #CdRomID,#SerieID fait rfrence la cl primaire de la relation Serie. L'attribut #QuestionID fait rfrence la cl primaire de la relation Question. Il ne faut pas oublier l'attribut Numro qui caractrise l'association contient. Seance_Code(SeanceID, Date, Heure, #CdRomID,#SerieID) Cette relation est issue du passage au relationnel de l'ensemble d'entits (classes) Seance_Code. Le couple d'attributs #CdRomID est une cl trangre qui fait rfrence la cl primaire de la relation Serie. Ce couple d'attributs a t ajout lors du passage au relationel de l'association est_diuse_pendant, une seule srie (d'un CR-ROM donn) tant diuse pendant une sance de code (cardinalit 1:1). Participation(#ClientID, #SeanceID, NombreFautes) Cette relation est issue du passage au relationnel de l'association assiste_. Les attributs #ClientID et #SeanceID sont des cls trangres qui font respectivement rfrences aux cls primaires des relations Client et Seance. En eet, un client peut assister plusieurs sances et, lors d'une sance, il y a plusieurs clients. Il ne faut pas oublier l'attribut NombreFautes qui caractrise l'association assiste_. Examen_Code(PassageCodeID, Date, Heure, LieuExamen) Cette relation est dduite du passage au relationnel de l'ensemble d'entits (ou classe) Examen_Code. PassageCode(#PassageCodeID, #ClientID, NombreFautes) Cette relation est dduite du passage au relationnel de l'association est_autoris__passer. Les attributs #PassageCodeID et #ClientID font rfrence aux cls primaires des relations Examen-Code et Client.

Exercice 2
Enonc de l'exercice
On souhaite construire une base de donnes grant des revues et les articles de ces revues. Une revue est caractrise par un nom et une priodicit. Chaque revue parait sous la forme de numros, chaque numro tant identi par un nombre relatif la revue et l'anne en cours (ex. le numro N 12 de Linux Magazine en 2003 est dirent du numro N 12 de Linux Magazine en 2004). Un numro est galement caractris par un nombre de pages. Chaque numro contient des articles crits par un ou plusieurs auteurs. Un auteur est caractris par un nom, un prnom, ainsi qu'un email. Chaque article possde un titre et un contenu. Un mme article peut apparatre dans plusieurs plusieurs numros d'une mme revue ou de direntes revues. Lorsqu'un article apparat dans un numro d'une revue, il a une page de dbut et une page de n. Un article peut faire rfrence d'autres articles, en prcisant le numro et la revue dans lesquels l'article rfrenc a t publi.

Revue Auteur Nom Priodicit 1:N ID Nom Prnom Email 1:N comporte crit comporte Revue Auteur Nom Priodicit NumroID 1 ID Nom Prnom Email 1..*

1:1 Numro ID Anne NbPages 1:N est publi dans PageDbut PageFin 1:M Article 1:M Titre Contenu 0:N fait rfrence ID Anne NbPages 0:M 1..* Numro 1..* est publi dans 1..* 1..* Article Titre Contenu * rfrence

Modlisation Entit / Association

Publication * PageDbut PageFin fait

Modlisation UML

Figure 2: Modlisation E/A et UML d'une base de donnes grant des revues. La base de donnes doit permettre de rpondre des requtes telles que "Combien de numros de Linux Magazine sont parus en 2004 ?", "Quels sont les titres des articles parus dans au moins deux revues direntes ?", "Quels sont les auteurs ayant publis dans le numro 3 de la revue L'Histoire en 2004 ?" etc. La gure 2 prsente la modlisation Entit/Association (format Merise) et la modlisation UML de l'nonc. Les explications ne sont donnes que pour le schma E/A mais peuvent tre adaptes au schma UML. Pour une comprhension de la dirence entre une modlisation E/A ou UML et le passage au relationnel, vous pouvez vous reporter l'ouvrage [4]. Les schmas de modlisation ci-avant sont smantiquement clairs. Nanmoins, quels points ncessitent d'tre prciss.

L'ensemble d'entits Numro est un ensemble d'entits faibles de Revue au format Merise (ou une association qualie en UML). En eet, ce choix de modlisation a t fait pour reprsenter le fait que l'identicateur d'un numro est relatif la revue laquelle le numro appartient. Un numro d'une revue donne tant identi par un nombre et une anne, ces deux attributs (ID et Anne) sont souligns. Les cardinalits de l'association entre les ensembles d'entits Numro et Article sont 1:N-1:M, car un article peut apparatre dans plusieurs numros et un numro contient plusieurs articles. Le principe est le mme pour les cardinalits de l'association entre Auteur et Article. Les attributs PageDbut et PageFin caractrisent l'association entre Article et Numro (un numro tant relatif une revue, il est inutile de faire une association avec Revue). En eet, la page de dbut et la page de n peuvent varier, pour un mme article, lorsqu'il parat dans plusieurs numros dirents. Un article peut faire rfrence un autre article. Le numro et la revue dans lesquels l'article rfrenc apparat doivent tre prciss dans l'article rfrenant. Par exemple, l'article intitul "Correction d'exercices en bases de donnes" peut faire rfrence l'article "Concepts gnraux en BD relationnelle" du numro 12 de l'anne 2004 de la revue "Informatique magazine". A cet eet, les ensembles d'entits Numro et Article ont t regroups au sein d'un agrgat au format Merise (ou d'une classe-association en UML). Cet agrgat (ou cette classeassociation) reprsente l'article rfrenc, c'est--dire l'article et le numro de la revue o il a t publi (il est inutile d'ajouter la revue l'agrgat puisque Numro est un ensemble d'entits faibles de Revue). Cet agrgrat (ou cette classe-association) est associe Article,
5

crit

c'est--dire l'article rfrenant, dont on ne prcise pas le numro et la revue. Les cardinalits ont pour borne infrieure 0 car un article peut ne rfrencer aucun autre article et un article peut ne jamais tre rfrenc. Pour plus de dtails sur l'agrgation, vous pouvez vous rfrer la page 37 de l'ouvrage [2] ou aux pages 55-56 de [3]. Dduisez le schma relationnel de la base de donnes correspondante. Vous prciserez les cls primaires des relations en les soulignant ainsi que les cls trangres en les signalant par un # et en prcisant quoi elles font rfrence. Dans votre schma relationnel, chaque relation doit tre spcie de la manire suivante : RN om (att1 ,...,attn ) o RN om est le nom de la relation et att1 , ..., attn sont des noms d'attributs. Le nom de la relation doit obligatoirement avoir un lien avec les noms des ensembles d'entits (classes) ou des associations du schma de modlisation de la question 1. Vous donnerez des explications claires et concises du passage au relationnel. Vous prciserez notamment pourquoi et comment vous crez ou modiez certaines relations (1 ligne maximum par relation).

Correction de l'exercice 2
Le modle relationnel dduit de la modlisation ci-dessus est le suivant. Les cls primaires sont soulignes. Les cls trangres sont prcdes d'un '#'. Pour un rappel de ces notions, vous pouvez vous rfrer aux pages 56 60 de [2]. Le passage d'un schma de modlisation un modle relationnel est rappel aux pages 120 143 de [4].

Revue(Nom, Priodicit) Cette relation est dduite du passage au relationnel de l'ensemble d'entits (ou classe) Revue. Numro(ID, Anne, #NomRevue, NbPages) Cette relation est issue du passage au relationnel de l'ensemble d'entits (classes) Numro, qui est un ensemble d'entits faibles (ou une association qualie) de Revue. La cl primaire de la relation Numro est donc compose du couple (ID, Anne) qui identie un numro pour une revue donne et de l'attribut #NomRevue, cl trangre faisant rfrence la cl primaire de la relation Revue (c'est--dire faisant rfrence la revue laquelle le numro est relatif). Auteur(ID, Nom, Prnom, Email) Cette relation est dduite du passage au relationnel de l'ensemble d'entits (ou classe) Auteur. Article(Titre, Contenu) Cette relation est dduite du passage au relationnel de l'ensemble d'entits (ou classe) Article. Ecriture(#Titre, #IDAuteur) Cette relation est dduite du passage au relationnel de l'association entre Article et Auteur. En eet, un article peut tre crit par plusieurs auteurs et un auteur peut crire plusieurs articles. L'attribut #Titre est une cl trangre qui fait rfrence la cl primaire de la relation Titre. L'attribut #IDAuteur est une cl trangre qui fait rfrence la cl primaire de la relation Auteur. Publication(#Titre, #NomRevue, #IDNumro, #AnneNumro, PageDbut, PageFin) Cette relation est dduite du passage au relationnel de l'association entre Article et Numros. La cl primaire de la relation est compose du titre de l'article publi (identi par #Titre) et du numro dans lequel l'article apparat (identi par le triplet #NomRevue, #IDNumro, #AnneNumro). L'attribut #Titre est une cl trangre qui fait rfrence la cl primaire de la relation Titre. Les attributs (#NomRevue, #IDNumro, #AnneNumro) forment une cl trangre qui fait rfrence la cl primaire de la relation Numro. Il faut bien noter, ici, qu'une cl trangre fait toujours rfrence la cl primaire d'une autre relation. Or, dans cet exemple, la cl primaire de la relation Numro est compose de trois attributs qui doivent galement apparatre dans toutes cls trangres y faisant rfrence. Il ne faut pas
6

non plus oublier d'ajouter dans la relation Publication les attributs PageDbut et PageFin qui caractrise l'association est_publi_dans.

Rfrence(#TitreArticleRfrenant, #TitreArticleRfrenc, #NomRevueArticleRfrenc, #IDNumroArticleRfrenc, #AnneNumroArticleRfrenc) Cette relation est dduite du passage au relationnel de l'association entre l'ensemble d'entits (ou la classe) Article et l'agrgat (ou la classe-association) regroupant Numro et Article. Les noms des attributs sont particulirement longs pour que la smantique soit claire. L'attribut #TitreArticleRfrenant est une cl trangre qui fait rfrence la cl primaire de la relation Article. Cet attribut reprsente le titre de l'article rfrenant (contenant une rfrence un article publi dans un numro). L'attribut #TitreArticleRfrenc est une cl trangre qui fait rfrence la cl primaire de la relation Article. Cet attribut reprsente le titre de l'article rfren. Les attributs (#NomRevueArticleRfrenc, #IDNumroArticleRfrenc, #AnneNumroArticleRfrenc) forment une cl trangre qui fait rfrence la cl primaire de la relation Numro. Ils reprsentent le numro de la revue dans lequel a t publi l'article rfrenc.

Langage d'interrogation
Exercice 3
Enonc de l'exercice
On suppose qu'une bibliothque gre une base de donnes dont le schma est le suivant (les cls primaires des relations sont soulignes) :

Emprunt(Personne, Livre, DateEmprunt, DateRetourPrevue, DateRetourEective) Retard(Personne, Livre, DateEmprunt, PenalitRetard)


Exprimer, lorsque cela est possible, les requtes suivantes en algbre relationnelle, en calcul variable nuplet et en SQL. 1. Quelles sont les personnes ayant emprunt le livre "Recueil Examens BD" ? 2. Quelles sont les personnes n'ayant jamais rendu de livre en retard ? 3. Quelles sont les personnes ayant emprunt tous les livres (emprunts au moins une fois) ? 4. Quels sont les livres ayant t emprunts par tout le monde (i.e. tous les emprunteurs) ? 5. Quelles sont les personnes ayant toujours rendu en retard les livres qu'elles ont emprunts ?

Correction de l'exercice 3
Dans cet exercice, le schma relationnel est particulirement simple, an que l'expression des requtes soit facile exprimer. Il s'agit nanmoins de requtes complexes. Vous pouvez vous entraner exprimer ces requtes en amliorant le schma, c'est--dire en ajoutant deux relations Personne et Livre et prcisant les cls trangres dans les relations Emprunt et Retard faisant rfrence une personne et un livre. 1. Quelles sont les personnes ayant emprunt le livre "Recueil Examens BD" ? En algbre relationnelle : P ersonne (Livre= Recueil... (Emprunt)) L'algbre relationnelle est un langage compos d'oprations ensemblistes. Il permet d'indiquer comment le rsultat de la requte est calcul en termes d'oprations ensemblistes sur des ensembles de nuplets (les relations). Dans cette requte par exemple, le rsultat est calcul en parcourant tous les nuplets de la relation Emprunt, en y slectionnant les nuplets dont l'attribut Livre a pour valeur 'Recueil...' et en prenant uniquement les valeurs de l'attribut Personne (i.e. en projetant sur l'attribut Personne). En calcul relationnel : {t.P ersonne | Emprunt(t) (u.Livre = Recueil... ) } Le calcul relationnel dcrit, sous forme logique, le rsultat de la requte (sans prciser comment on le calcule). Le rsultat de la requte contient les valeurs de l'attribut P ersonne des nuplets t de la relation Emprunt tels que l'attribut Livre corresponde 'Recueil Examens 8

BD'. En SQL:

SELECT Personne FROM Emprunt WHERE Livre = 'Recueil...'


Il aurait galement t possible de remplacer la clause WHERE par WHERE Livre LIKE 'Recueil%' indiquant que l'on recherche les emprunteurs des ouvrages dont le titre commence par 'Recueil'. 2. Quelles sont les personnes n'ayant jamais rendu de livre en retard ? En algbre relationnelle : P ersonne (Emprunt) P ersonne (Retard) La rsultat de la requte est calcul en prenant toutes les valeurs de l'attribut Personne dans la relation Emprunt et en liminant les valeurs de ce mme attribut apparaissant galement dans la relation Retard. Il s'agit d'une dirence entre deux ensembles. En calcul relationnel :

{t.P ersonne | Emprunt(t) [ u Retard(u) (u.P ersonne = t.P ersonne) )]}


Le rsultat de la requte contient les valeurs de l'attribut P ersonne des nuplets t de la relation Emprunt (donc des personnes empruntant) tels qu'il n'existe pas de nuplets u dans la relation Retard avec la mme valeur pour l'attribut P ersonne (donc telles qu'il n'existe pas de retards associs ces personnes). En SQL, deux manires possibles, par simple traduction en SQL de la requte en calcul relationnel (le calcul relationnel tant l'origine de la syntaxe de SQL) :

SELECT t.Personne FROM Emprunt t SELECT Personne FROM Emprunt WHERE NOT EXISTS (SELECT * FROM Retard u WHERE Personne NOT IN WHERE u.Personne=t.Personne (SELECT Personne FROM Retard) )
Les variables nuplet (ex. t et u) ne sont ncessaire que lorsqu'il y a ambigut au niveau des noms d'attributs (cf. requte de gauche). 3. Quelles sont les personnes ayant emprunt tous les livres (emprunts au moins

une fois) ?

En algbre relationnelle : P ersonne,Livre (Emprunt) Livre (Emprunt) Le rsultat de cette requte est calcul en utilisant l'oprateur de division. Pour une bonne comprhension de la division, vous pouvez vous reporter la page 99 de [2]. La sous-requte Livre (Emprunt) correspond la liste des livres emprunts. Le rsultat de la sous-requte P ersonne,Livre (Emprunt) contient tous les couples (Personne, Livre emprunt au moins une fois par cette personne). Le rsultat de la division sera donc la liste des personnes associes, dans le rsultat de P ersonne,Livre (Emprunt), chacun des livres apparaissant dans le rsultat de la requte Livre (Emprunt).

En calcul relationnel :

{t.P ersonne | Emprunt(t) [ u (Emprunt(u)) = ( v Emprunt(v) (v.P ersonne = t.P ersonne) (u.Livre = v.Livre) )]} Le rsultat de la requte contient les valeurs de l'attribut P ersonne des nuplets t de la relation Emprunt tels que quel que soit un nuplet s'il s'agit d'un livre emprunt (donc d'un nuplet u dans Emprunt) alors on trouve un nuplet v dans Emprunt associant cette personne ce livre (c'est--dire v.P ersonne = t.P ersonne et u.Livre = v.Livre).
On peut galement l'crire de la manire suivante : {t.P ersonne | Emprunt(t) [ u (Emprunt(u)) ( v Emprunt(v) (v.P ersonne = t.P ersonne) (u.Livre = v.Livre) )]} Ce qui signie que le rsultat de la requte contient les valeurs de l'attribut P ersonne des nuplets t de la relation Emprunt tels que quel que soit un nuplet u soit c'est n'est pas un nuplet de Emprunt soit (implicitement c'est un nuplet de Emprunt et) on trouve un nuplet v dans Emprunt associant cette personne ce livre (c'est--dire v.P ersonne = t.P ersonne et u.Livre = v.Livre). D'o dit de manire ngative : {t.P ersonne | Emprunt(t) [ u Emprunt(u) ( v Emprunt(v)(v.P ersonne = t.P ersonne) (u.Livre = v.Livre) )]} En SQL, simple traduction de la requte en calcul relationnel :

SELECT t.Personne FROM Emprunt t WHERE NOT EXISTS ( SELECT * FROM Emprunt u WHERE NOT EXISTS ( SELECT * FROM Emprunt v WHERE v.Personne=t.Personne AND v.Livre=u.Livre ) )
4. Quels sont les livres ayant t emprunts par tout le monde (i.e. tous les em-

prunteurs) ?

En algbre relationnelle : P ersonne,Livre (Emprunt) P ersonne (Emprunt) Le rsultat de cette requte est calcul en utilisant galement l'oprateur de division. La sous-requte P ersonne (Emprunt) correspond la liste des emprunteurs. Le rsultat de la sous-requte P ersonne,Livre (Emprunt) contient tous les couples (Personne ayant emprunt au moins une fois, Livre emprunt au moins une fois par cette personne). Le rsultat de la division sera donc la liste des livres associs, dans le rsultat de P ersonne,Livre (Emprunt), chacun des emprunteurs apparaissant dans le rsultat de la requte P ersonne (Emprunt). En calcul relationnel :

{t.Livre | Emprunt(t) [ u (Emprunt(u)) = ( v Emprunt(v) (u.Livre = t.Livre) (v.P ersonne = u.P ersonne) )]}
Le rsultat de la requte contient les valeurs de l'attribut Livre des nuplets t de la relation Emprunt tels que quel que soit un nuplet s'il s'agit d'un emprunteur (donc d'un nuplet u dans Emprunt) alors on trouve un nuplet v dans Emprunt associant ce livre cet emprunteur 10

(c'est--dire u.Livre = t.Livre et v.P ersonne = u.P ersonne ). On peut galement l'crire de la manire suivante : {t.Livre | Emprunt(t) [ u (Emprunt(u)) ( v Emprunt(v) (u.Livre = t.Livre) (v.P ersonne = u.P ersonne) )]} Ce qui signie que le rsultat de la requte contient les valeurs de l'attribut Livre des nuplets t de la relation Emprunt tels que quel que soit un nuplet soit il ne s'agit pas d'un nuplet u dans Emprunt soit (il s'agit d'un d'un nuplet u dans Emprunt et) il existe un nuplet v dans Emprunt associant ce livre cet emprunteur (c'est--dire u.Livre = t.Livre et v.P ersonne = u.P ersonne ). D'o dit de manire ngative : {t.Livre | Emprunt(t) [ u Emprunt(u) ( v Emprunt(v) (u.Livre = t.Livre) (v.P ersonne = u.P ersonne) )]} En SQL, simple traduction de la requte en calcul relationnel :

SELECT t.Livre FROM Emprunt t WHERE NOT EXISTS ( SELECT * FROM Emprunt u WHERE NOT EXISTS ( SELECT * FROM Emprunt v WHERE u.Livre=t.Livre AND v.Personne=u.Personne ) )
5. Quelles sont les personnes ayant toujours rendu en retard les livres qu'elles ont

emprunts ?

En algbre relationnelle : Il n'est pas possible d'exprimer cette requte par une division. La requte est donc dcompose en deux sous-requtes. La requte, R1 , ci-dessous, retourne la liste des personnes ayant emprunt au moins un livre sans le rendre en retard.

R1 = P ersonne [P ersonne,Livre,DateEmprunt (Emprunt) P ersonne,Livre,DateEmprunt (Retard)]


La requte ci-dessous enlve de la liste des personnes qui empruntent des livres (sous-requte de gauche) la liste des personnes ayant rendu au moins un livre sans retard (requte R1 ). Cela correspond comment calculer le rsultat de la requte que l'on recherche.

P ersonne (Emprunt) R1
En calcul relationnel :

{t.P ersonne | Emprunt(t) [ u [Emprunt(u) (u.P ersonne = t.P ersonne)] = ( v Retard(v) (v.P ersonne = u.P ersonne) (u.Livre = v.Livre) )]}
Le rsultat de la requte contient les valeurs de l'attribut P ersonne des nuplets t de la relation Emprunt tels que quel que soit un nuplet s'il s'agit d'un livre emprunt par cette personne (donc d'un nuplet u dans Emprunt tel que u.P ersonne = t.P ersonne) alors on trouve un nuplet v dans Retard associant cette personne ce livre (c'est--dire v.P ersonne = u.P ersonne et u.Livre = v.Livre). On peut galement cire : {t.P ersonne | Emprunt(t) [ u [Emprunt(u) (u.P ersonne = t.P ersonne)] ( v Retard(v) (v.P ersonne = u.P ersonne) (u.Livre = v.Livre) )]} Le rsultat de la requte contient les valeurs de l'attribut P ersonne des nuplets t de la relation Emprunt tels que quel que soit un nuplet soit il ne s'agit pas d'un livre emprunt par cette personne (donc d'un nuplet u dans Emprunt tel que u.P ersonne = t.P ersonne) 11

soit on trouve un nuplet v dans Retard associant cette personne ce livre (c'est--dire v.P ersonne = u.P ersonne et u.Livre = v.Livre). D'o dit de manire ngative : {t.P ersonne | Emprunt(t) [ u Emprunt(u)(u.P ersonne = t.personne) ( v Retard(v) (v.P ersonne = u.P ersonne) (u.Livre = v.Livre) )]} En SQL, l encore , simple traduction de la requte en calcul relationnel:

SELECT t.Personne FROM Emprunt t WHERE NOT EXISTS (SELECT * FROM Emprunt u WHERE u.Personne=t.Personne AND NOT EXISTS (SELECT * FROM Retard v WHERE v.Personne=u.Personne AND v.Livre=u.Livre ) )

Exercice 4
Enonc de l'exercice
Un organisme de gestion de spectacles, de salles de concert et de vente de billets de spectacles gre une base de donnes dont le schma relationnel est le suivant :

Spectacle(Spectacle_ID, Titre, DateDb, Dure, Salle_ID, Chanteur) Concert (Concert_ID, Date, Heure, Spectacle_ID) Salle (Salle_ID, Nom, Adresse, Capacit) Billet (Billet_ID, Concert_ID, Num_Place, Catgorie, Prix) Vente (Vente_ID, Date_Vente, Billet_ID, MoyenPaiement)
Les attributs souligns sont les attributs appartenant la cl primaire. Ils sont de type entier. L'attribut Salle_ID de la relation Spectacle est une cl trangre qui fait rfrence l'attribut de mme nom de la relation Salle. L'attribut Spectacle_ID de la relation Concert est une cl trangre qui fait rfrence l'attribut de mme nom de la relation Spectacle. L'attribut Concert_ID de la relation Billet est une cl trangre qui fait rfrence l'attribut de mme nom de la relation Concert. L'attribut Billet_ID de la relation Vente est une cl trangre qui fait rfrence l'attribut de mme nom de la relation Billet.

Exprimez, lorsque cela est possible, les requtes suivantes en algbre relationnelle, en calcul relationnel variable nuplet et en SQL.
1. Quelles sont les dates du concert de Corneille au Zenith ? 2. Quels sont les noms des salles ayant la plus grande capacit ? 3. Quels sont les chanteurs n'ayant jamais ralis de concert la Cygale ? 4. Quels sont les chanteurs ayant ralis au moins un concert dans toutes les salles ? 5. Quels sont les dates et les identicateurs des concerts pour lesquels il ne reste aucun billet invendu ?

Correction de l'exercice 4
1. Quelles sont les dates du concert de Corneille au Zenith ? En algbre relationnelle : Date [Concert

Chanteur= Corneille (Spectacle)

N om= Zenith (Salle)]

12

Cette requte comporte deux jointures naturelles. La premire jointure, entre les relations Concert et Spectacle, associe les nuplets de Spectacle, correspondant aux spectacles du chanteur `Corneille' (puisqu'il y a une slection avant), avec les nuplets de la relation Concert ayant la mme valeur pour l'attribut Spectacle_ID. La jointure se fait naturellement sur l'attribut de mme nom, Spectacle_ID. La deuxime jointure associe les nuplets rsultats de la premire jointure (donc les concerts des spectacles de 'Corneille') avec le nuplets correspondant la salle du 'Zenith' (rsultat de la requte de slection N om= Zenith (Salle)). La jointure se fait naturellement sur l'attribut commun Salle_ID. La projection nale se fait sur l'attribut Date. En calcul relationnel :

{t.Date | Concert(t) [ u, v Spectacle(u) Salle(v) (u.Spectacle_ID = t.Spectacle_ID) (u.Chanteur = Corneille ) (v.N om = Zenith ) (u.Salle_ID = v.Salle_ID) ] }
La requte retourne les dates des concerts pour lesquels il existe un spectacle de 'Corneille' associ la salle du 'Zenith'. Le rsultat de la requte contient donc les valeurs de l'attribut Date des nuplets t de la relation Concert tels qu'il existe un nuplet u dans Spectacle, correspondant un spectacle de 'Corneille' (c'est--dire dont l'attribut Chanteur a pour valeur 'Corneille'), avec la mme valeur pour l'attribut Spectacle_ID que le nuplet t et tels qu'il existe aussi un nuplet v dans la relation Salle, correspondant la salle du 'Zenith' (dont l'attribut Nom a pour valeur 'Zenith'), avec la mme valeur pour l'attribut Salle_ID que celle de l'attribut Salle_ID du nuplet u. En SQL, par traduction immdiate de la requte en calcul variable nuplet :

SELECT Date FROM Concert t, Spectacle u, Salle v WHERE t.Spectacle_ID = u.Spectacle_ID AND u.Chanteur = 'Corneille' AND u.Salle_ID = v.Salle_ID AND v.Nom = 'Zenith'
2. Quels sont les noms des salles ayant la plus grande capacit ? En algbre relationnelle : Cette requte ne peut pas s'crire en algbre relationnelle non tendue. Il faut un oprateur maximum. Pour plus de dtails sur l'algbre relationnelle tendue, vous pouvez vous reporter aux pages 103 111 de [3] ou aux pages 221 230 de [1]. En algbre relationnelle tendue1 , la requte s'exprime par: N om ((Capacite>=CapaciteM ax) Salle_ID,CapacitM ax [Salle(M AX(Capacite)CapaciteM ax) (Salle))]) La requte Salle_ID,CapacitM ax [Salle(M AX(Capacite)CapaciteM ax) (Salle))] retourne une relation temporaire de deux colonnes, la pemire contenant les valeurs de l'attribut Salle_ID de la relation Salle et la deuxime colonne contenant une seule valeur (repte pour toutes les valeurs de Salle_ID) correspondant la valeur maximale de l'attribut Capacit (calcule par la fonction d'agrgation MAX et renomme en CapaciteMAX). L'oprateur utilis est le produit cartsien (). Pour obtenir le nom des salles avec la plus grande capacit, il sut donc de joindre cette relation temporaire la relation Salle et de slectionner les nuplets ayant une valeur de Capacit superieure ou gale celle de l'attribut CapaciteMax. En calcul relationnel : {t.N om | Salle(t) [ u Salle(u) (u.Capacite >= t.Capacite) ] } Cette requte retourne les valeurs de l'attribut Nom des nuplets t de la relation Salle pour
1 L'algbre

relationnelle tendue n'est pas au programme de l'examen.

13

lesquels il n'existe pas de nuplets u dans Salle avec une valeur de l'attribut Capacit suprieure ou gale. En SQL: Il est possible de traduire directement la requte exprime en calcul relationnel, comme cidessous.

SELECT Nom FROM Salle t WHERE NOT EXISTS (SELECT * FROM Salle u WHERE u.Capacit >= t. Capacit)
Il est galement possible d'utiliser l'oprateur d'agrgation M AX , comme pour la requte suivante.

SELECT Nom FROM Salle WHERE Capacit >= ( SELECT (MAX(Capacit) FROM Salle )
Il est galement possible d'utiliser le mot-cl ALL :

SELECT Nom FROM Salle WHERE Capacit >= ALL ( SELECT Capacit FROM Salle )
3. Quels sont les chanteurs n'ayant jamais ralis de concert la Cygale ? En algbre relationnelle : Chanteur (Spectacle)Chanteur [Spectacle

(N om= Cygale ) (Salle)]

La requte Chanteur [Spectacle (N om= Cygale ) (Salle)] retourne les chanteurs ayant chant au moins une fois dans la salle de la 'Cygale'. Le rsultat de la requte fnale est obtenu en supprimant ces chanteurs de la liste de tous les chanteurs. En calcul relationnel :

{t.Chanteur | Spectacle(t) [ u, v Spectacle(u) Salle(v) (v.N om = Cygale ) (u.Chanteur = t.Chanteur) (u.Salle_ID = v.Salle_ID) ] }
La requte retourne les valeurs de l'attribut Chanteur des nuplets t de la relation Spectacle tels qu'il ne soit pas possible de trouver un spectacle de ce mme chanteur la 'Cygale' (i.e. de trouver un nuplet u dans Spectacle avec la mme valeur pour l'attribut Chanteur et un nuplet v dans Salle avec 'Cygale' comme valeur de l'attribut Nom et avec la mme valeur que u.Salle_ID pour l'attribut Salle_ID). En SQL:

SELECT Chanteur FROM Spectacle WHERE Chanteur NOT IN (SELECT Chanteur


14

FROM Spectacle u, Salle v WHERE u.Salle_ID=v.Salle_ID AND v.Nom='Cygale'

Cette requte peut aussi s'exprimer avec un NOT EXISTS en utilisant une variable nuplet t dans le premier F ROM , par une simple traduction du calcul relationnel :

SELECT Chanteur FROM Spectacle t WHERE Chanteur NOT EXISTS ( SELECT * FROM Spectacle u, Salle v WHERE u.Salle_ID=v.Salle_ID AND v.Nom='Cygale' AND t.CHanteur=u.Chanteur )
4. Quels sont les chanteurs ayant ralis au moins un concert dans toutes les salles

En algbre relationnelle : Chanteur,Salle_ID (Spectacle

Salle) Salle_ID (Salle)

La requte Salle_ID (Salle) retourne tous les identicateurs de salle. La requte Chanteur,Salle_ID (Spectacle Salle) retourne une relation associant chaque chanteur l'identicateur de la salle dans laquelle il a ralis au moins un spectacle. La division va donc retourner les chanteurs associs au moins une fois toutes les salles de la base. En calcul relationnel : {t.Chanteur | Spectacle(t) [ u (Salle(u)) = ( v Spectacle(v) (v.Chanteur = t.Chanteur) (u.Salle_ID = v.Salle_ID) ) ] } La requte retourne les valeurs de l'attribut Chanteur des nuplets t de la relation Spectacle tels que pour quel que soit un nuplet, s'il s'agit d'une salle (donc un nuplet u pris dans Salle), alors il existe un spectacle de ce chanteur dans cette salle (donc il existe un nuplet v dans Spectacle correspondant ce chanteur, avec v.Chanteur = t.Chanteur, et cette salle, avec u.Salle_ID = v.Salle_ID). On peut galement crire : {t.Chanteur | Spectacle(t) [ u (Salle(u)) ( v Spectacle(v) (v.Chanteur = t.Chanteur) (u.Salle_ID = v.Salle_ID) ) ] } La requte retourne les valeurs de l'attribut Chanteur des nuplets t de la relation Spectacle tels que pour quel que soit un nuplet, soit il ne s'agit pas d'une salle (donc il ne s'agit pas d'un nuplet u de Salle), soit (implicitement il s'agit d'un nuplet u de Salle et) il existe un spectacle de ce chanteur dans cette salle (donc il existe un nuplet v dans Spectacle correspondant ce chanteur, avec v.Chanteur = t.Chanteur, et cette salle, avec u.Salle_ID = v.Salle_ID). D'o dit de manire ngative :

{t.Chanteur | Spectacle(t) [ u Salle(u) ( v Spectacle(v) (v.Chanteur = t.Chanteur) (u.Salle_ID = v.Salle_ID) ) ] }


En SQL:

SELECT Chanteur FROM Spectacle t WHERE NOT EXISTS


15

( SELECT * FROM Salle u WHERE NOT EXISTS ( SELECT * FROM Spectacle v WHERE v.Chanteur = t. Chanteur AND u.Salle_ID = v.Salle_ID ) )
5. Quels sont les dates et les identicateurs des concerts pour lesquels il ne reste

aucun billet invendu ?

En algbre relationnelle : Cette requte tant complexe et ne peut pas s'exprimer l'aide d'une division. Il est plus simple de l'crire en la dcomposant. Une premire sous-requte R1 va permettre de dterminer les billets invendus :

R1 = Billet_ID (Billet) Billet_ID (V ente)


La requte R1 supprime de la liste des billets (Billet_ID (Billet)), ceux qui ont t vendus (Billet_ID (V ente)). Pour obtenir les concerts auxquels appartiennent ces billets invendus, il faut faire une jointure avec la relation Billet (pour obtenir la valeur de l'attribut Concert_ID associ au billet) puis avec Concert (pour obtenir la date du concert associ), soit :

R2 = Date,Concert_ID (Concert

Billet

[Billet_ID (Billet) Billet_ID (V ente)])


R1

Au nal, on supprime la liste des identicateurs de concerts et de leur date associe au rsultat de la requte R2 , soit :
R2

Date,Concert_ID (Concert)Date,Concert_ID (Concert


En calcul relationnel :

Billet

[Billet_ID (Billet) Billet_ID (V ente)])


R1

{t.Concert_ID, t.Date | Concert(t) [ u Billet(u) (u.Concert_ID = t.Concert_ID) ( v V ente(v) (v.Billet_ID = u.Billet_ID) ) ] }


La requte retourne les valeurs des attributs Concert_ID et Date des nuplets t de la relation Concert tels que pour tous les billets de ce concert (donc pour tous les nuplets u dans Billet tels que u.Concert_ID = t.Concert_ID), il existe une vente de ce billet (donc il existe un nuplet v dans Vente correspondant ce billet, i.e. tel que v.Billet_ID = u.Billet_ID). D'o dit de manire ngative : {t.Concert_ID, t.Date | Concert(t) [ u Billet(u) (u.Concert_ID = t.Concert_ID) ( v V ente(v) (v.Billet_ID = u.Billet_ID) ) ] } En SQL:

SELECT Concert_ID, Date FROM Concert t WHERE NOT EXISTS (SELECT * FROM Billet u WHERE u.Concert_ID=t.Concert_ID AND NOT EXISTS (SELECT * FROM Vente v WHERE u.Billet_ID = v.Billet_ID ) )

16

Dpendances fonctionnelles et normalisation


Exercice 5
Enonc de l'exercice
Soit un schma de bases de donnes contenant les relation suivantes :

Bureau(NumBureau, NumTelephone, Taille) avec FBureau = { N umBureau N umT elephone, T aille; N umT elephone N umBureau; } Occupant(NumBureau, PersonneID) avec FOccupant = { N umBureau P ersonneID } Materiel(NumBureau, NumPC) avec FM ateriel = { N umP C N umBureau }
1. Les contraintes ci-dessous sont-elles vries par ce schma de bases de donnes? Si la rponse est positive, expliquez pourquoi. Si la rponse est ngative, indiquez quelle(s) dpendance(s) fonctionnelle(s) il faut ajouter/supprimer ou modier pour que la contrainte soit vrie. (a) "Un bureau peut contenir plusieurs postes tlphoniques." (b) "Il y a une et une seule personne par bureau." (c) "Un bureau contient un seul ordinateur." 2. A partir des familles de dpendances fonctionnelles initiales donnes dans l'nonc, indiquez quelles sont les cls minimales possibles de chaque relation.

Correction de l'exercice 5
1. Vrication des contraintes exprimes par des dpendances fonctionnelles : (a) "Un bureau peut contenir plusieurs postes tlphoniques" Cette contrainte n'est pas vrie car FBureau contient la dpendance fonctionnelle N umBureau N umT elephone donc un bureau est associ un et un seul numro de tlphone. Pour que la contrainte soit vrie, il faudrait supprimer cette dpendances fonctionnelle. (b) "Il y a une et une seule personne par Bureau." Cette contrainte est vrie car FOccupant contient la dpendance fonctionnelle N umBureau P ersonneID, donc un numro de bureau est associe une et une seule personne. (c) "Un bureau contient un seul ordinateur." Cette contrainte n'est pas vrie car il y a juste l'information qu'un ordinateur est dans un seul bureau (N umP C N umBureau) mais pas l'inverse. Pour que la contrainte soit vrie, il faudrait ajouter la dpendance fonctionnelle N umBureau N umP C .

17

2. Dtermination des cls minimales des relations :

FBureau = { N umBureau N umT elephone, T aille; N umT elephone N umBureau; } La relation Bureau a donc deux cls minimales possibles : N umBureau et N umT elephone.
En eet, partir de l'attribut N umBureau il est possible de dduire les deux autres attributs de la relation (par la premire dpendance fonctionnelle). Par l'attribut N umT elephone, il est possible de dduire N umBureau (2me dpendance fonctionnelle) et donc l'attribut T aille (par la premire dpendance fonctionnelle). On a donc : [N umBureau]+ = {N umBureau, N umT elephone, T aille} car N umBureau N umT elephone, T aille. et [N umT elephone]+ = {N umT elephone, N umBureau, T aille}, car N umT elephone N umBureau et donc par transitivit avec N umBureau T aille, on obtient N umT elephone T aille.

FOccupant = { N umBureau P ersonneID } La relation Occupant a donc une seule cl minimale possible : N umBureau. FM ateriel = { N umP C N umBureau } La relation M ateriel a donc une seule cl minimale possible : N umP C .
Pour plus de dtails sur les dpendances fonctionnelles, vous pouvez vous reporter aux pages 422 430 de [2].

Exercice 6
Enonc de l'exercice
Soit R une relation dont le schma est le suivant : R(UtilisateurID, Nom, Prnom, AdresseEmail, Login, Passwd, ServeurMail). 1. Exprimer, l'aide de dpendances fonctionnelles, les contraintes suivantes que doivent vrier les instances de la relation R : (a) "On peut dduire le nom et le prnom d'un utilisateur partir de son identicateur." (b) "Un utilisateur (identi par son identicateur) possde un seul login et un seul password par serveur de mails." (c) "Une adresse email est associe un et un seul identicateur d'utilisateur." Attention : un utilisateur peut avoir plusieurs adresses de mails. (d) "Une adresse email est associe un et un seul serveur de mails."

2. Indiquer, partir de la famille de dpendances fonctionnelles, issue de la question 1, quelles sont les cls mimimales de R.

3. Indiquer, partir de la famille de dpendances fonctionnelles, issue de la question 1, en quelle forme normale est la relation R.

18

Correction de l'exercice 6
1. Expression de contraintes par des dpendances fonctionnelles : (a) "On peut dduire le nom et le prnom d'un utilisateur partir de son identicateur." Cette contrainte s'exprime par la dpendance fonctionnelle : UtilisateurID Nom, Prnom En eet, un identicateur d'utilisateur est associ un et un seul nom et un et un seul prnom. (b) "Un utilisateur (identi par son identicateur) possde un seul login et un seul password par serveur de mails." Cette contrainte s'exprime par la dpendance fonctionnelle : UtilisateurID, ServeurMail Login, Passwd En eet pour un couple (identicateur d'utilisateur, serveur de mail) est associ un et un seul login et un et un seul mot de passe. (c) "Une adresse email est associe un et un seul identicateur d'utilisateur." Attention : un utilisateur peut avoir plusieurs adresses de mails. Cette contrainte s'exprime par la dpendance fonctionnelle : AdresseEmail UtilisateurID En eet, une adresse mail est associe un et un seul identicateur d'utilisateur. (d) "Une adresse email est associe un et un seul serveur de mails." Cette contrainte s'exprime par la dpendance fonctionnelle : AdresseEmail ServeurMail En eet, une adresse mail est associe un et un seul serveur de mails. 2. Identication des cls minimales de la relation R La famille de dpendances fonctionnelles associes R est :

F = { UtilisateurID Nom, Prnom; AdresseEmail UtilisateurID;

UtilisateurID, ServeurMail Login, Passwd; AdresseEmail ServeurMail }

L'attribut AdresseEmail ne peut tre dduit d'aucun autre attribut, il doit donc appartenir tous les cls minimales possibles de la relation. A partir de l'attribut AdresseEmail on peut dduire l'identicateur de l'Utilisateur est donc, par transitivit, le nom et le prnom de l'utilisateur : AdresseEmail UtilisateurID Nom, Prnom. A partir de ce mme attribut, on peut en dduire aussi le nom du serveur de mail et donc avec l'identicateur d'utilisateur, le login et le mot de passe de l'utilisateur : AdresseEmail UtilisateurID, ServeurMail Login, Passwd D'o : [AdresseEmail]+ = { AdresseEmail, UtilisateurID, Nom, Prnom, ServeurMail, Login, Passwd } = R La relation R a donc une seule cl minimale possible : AdresseEmail. 3. Dduction de la forme normale du schma de la relation R Les deux dernires dpendances fonctionnelles sont de la forme cl primaire autre attribut, et vrient donc les proprits de la forme normale BCNF. En revanche, les deux premires dpendances fonctionnelles sont transitives puisqu'elles ne sont composes que d'attributs n'appartenant pas une cl. Par consquent, le schma de la relation R est en deuxime forme normale. 19

Pour plus de dtails sur les formes normales, vous pouvez vous rfrer aux pages 100 117 de l'ouvrage [1], au chapitre 15 de l'ouvrage [2] ou au chapitre 7 de l'ouvrage [3].

20

Bibliography
[1] H. Garcia-Molina, J.D. Ulmann et J. Widow, Database Systems - The Complete Book, Prentice Hall, 2002 [2] R. Ramakrishnan et J. Gehrke, Database Management Systems, Second Edition; McGrawHill, 2000, ISBN: 0-07-232206-3 [3] A. Silberschatz, H.F. Korth et S. Sudarshan, Database System Concepts, 4th Edition, McGraw-Hill, 2002, ISBN: 0-07-228363-7 [4] C. Soutou, De UML SQL - Conception de bases de donnes, Eyrolles, 2002, ISBN: 2-21211098-7

21

Vous aimerez peut-être aussi