Gauloiseries
[30 minutes]
Un vieux druide perdant la mémoire souhaite réaliser une base de données pour se souvenir de la composition de ses potions. Un de ses apprentis ayant suivi un cours sur les bases de données lors de son initiation druidique, il réalise le schéma conceptuel suivant :
Vous pouvez tester vos requêtes directement sur votre base de données en l'initialisant avec le fichier de données.
/**
DROP TABLE Composition ;
DROP TABLE Ingredient ;
DROP TABLE Potion ;
**/
CREATE TABLE Potion (
Nom VARCHAR PRIMARY KEY,
Effet VARCHAR,
Duree INTEGER
);
CREATE TABLE Ingredient (
Nom VARCHAR PRIMARY KEY,
Localisation VARCHAR
);
CREATE TABLE Composition (
NomP VARCHAR REFERENCES Potion(Nom),
NomI VARCHAR REFERENCES Ingredient(Nom),
PRIMARY KEY (NomP, NomI)
);
INSERT INTO Potion (Nom, Effet, Duree) VALUES ('Potion Magique','Force', 60);
INSERT INTO Ingredient (Nom, Localisation) VALUES ('Eau', 'Partout');
INSERT INTO Ingredient (Nom, Localisation) VALUES ('Gui', 'Forêt');
INSERT INTO Ingredient (Nom, Localisation) VALUES ('Pomme', 'Pommier');
INSERT INTO Composition (NomP, NomI) VALUES ('Potion Magique', 'Eau');
INSERT INTO Composition (NomP, NomI) VALUES ('Potion Magique', 'Gui');
INSERT INTO Composition (NomP, NomI) VALUES ('Potion Magique', 'Pomme');
INSERT INTO Ingredient (Nom, Localisation) VALUES ('Bière', 'Pic');
INSERT INTO Potion (Nom, Effet, Duree) VALUES ('Potion Inutile','Rien', 0);
INSERT INTO Composition (NomP, NomI) VALUES ('Potion Inutile', 'Eau');
INSERT INTO Potion (Nom, Effet, Duree) VALUES ('Eau Aromatisée','Goût', 10);
INSERT INTO Composition (NomP, NomI) VALUES ('Eau Aromatisée', 'Eau');
INSERT INTO Composition (NomP, NomI) VALUES ('Eau Aromatisée', 'Gui');
Question
Réaliser le modèle logique correspondant en relationnel, en faisant apparaître les clés primaires et étrangères (sans clé artificielle).
Solution
Potion (#Nom:string, Effet:string, Durée:integer)
Ingrédient (#Nom:string, Localisation:string)
Composition (#NomP=>Potion(Nom), #NomI=>Ingrédient(Nom))
Question
Écrivez une requête SQL permettant de trouver la recette de la potion magique.
Solution
SELECT NomI
FROM Composition
WHERE NomP = 'Potion Magique';
Question
Qu'a-t-on gagné à ne pas avoir utilisé de clé artificielle dans notre modèle relationnel ?
Solution
On économise des jointures, dans les questions qui ne portent que sur le nom des ingrédients ou des potions, sans impliquer les autres attributs.
Question
Écrivez une requête SQL permettant de trouver les ingrédients utilisés par aucune potion.
Solution
Avec jointure externe
SELECT I.Nom
FROM Ingredient I LEFT JOIN Composition C ON I.Nom=C.NomI
WHERE C.NomI IS NULL ;
Question
Écrivez une vue SQL permettant de préparer l'implémentation de la méthode NbIngrédients. Cette vue devra renvoyer le nombre d'ingrédients pour chaque potion.
Solution
CREATE VIEW vNbIngredients (Potion, NbIngredients) AS
SELECT NomP, Count(*)
FROM Composition
GROUP BY NomP;
Question
Critiquez le schéma conceptuel de l'apprenti : Est-ce qu'un même ingrédient peut apparaître deux fois dans la même potion ? Peut-on gérer la quantité d'ingrédients pour chaque potion ? Proposer une solution et redessiner le schéma conceptuel en Entité-Association, en y intégrant votre amélioration.
Solution
Non, un même ingrédient ne peut pas apparaître deux fois dans une potion, car la clé de l'association Composition étant la concaténation des clés de Potion et de Ingrédient, elle ne peut exister en double, par définition. Une solution élégante serait d'ajouter une propriété Quantité sur l'association Composition, ainsi on pourrait fixer le nombre (en gramme ou en pourcentage par exemple) de chaque ingrédient pour chaque potion.