Zoologie
[45 minutes]
Un zoologue souhaite réaliser une base de données pour l'étude des chaînes alimentaires.
Il souhaite étudier deux populations d'animaux : les carnivores et les herbivores, sachant que les carnivores ne mangent que des herbivores et que les herbivores, évidemment, ne mangent pas d'animaux. La base gère donc des espèces d'animaux, identifiées par leur nom (Lion, Biches, etc.). Les carnivores et les herbivores sont étudiés selon deux paramètres communs : taille moyenne et poids moyen.
Pour les herbivores, on étudie en plus le poids moyen de végétaux mangé par jour. Bien entendu le zoologue souhaite connaître également le poids moyen mangé par jour pour chaque espèce de carnivore et pour chaque espèce d'herbivore qu'il mange. Il souhaite enfin pouvoir obtenir très facilement le poids total mangé par un carnivore par jour (donc en sommant le poids de chaque herbivore mangé par jour). On fera apparaître cette opération sur le modèle.
Question
Réalisez le modèle conceptuel du problème posé.
Solution
Avec Animal classe abstraite.
Question
Réalisez le modèle logique relationnel-objet du problème (on utilisera les OID pour toutes les tables référencés).
Solution
Type Animal : <nom:string, poids:float, taille:float>
Type Carnivore hérite de Animal : <=poidsMangéParJourTotal(): float>
Type Herbivore hérite de Animal : <poidsMangéParJour: float>
tCarnivore de Carnivore (#nom)
tHerbivore de Herbivore (#nom)
Type Mange : <mangeur =>o tCarnivore, mangé =>o tHerbivore, poidsMangéParJour:float>
tMange de Mange ()
Remarque :
L'impossibilité de définir une clé à partir des OID fait que l'on ne peut pas empêcher les doublons mangeur/mangé dans Mange.
Question
Implémentez le modèle relationnel-objet en SQL3 sous Oracle (sans implémenter de méthode).
Solution
CREATE TYPE Animal AS OBJECT(
nom varchar2(50),
poids float,
taille float
) NOT FINAL ;
/
CREATE TYPE Carnivore UNDER animal(
MEMBER FUNCTION poidsMangeParJourTotal RETURN float
);
/
CREATE TYPE Herbivore UNDER animal(
poidsMangeParJour float
);
/
CREATE TYPE Mange AS OBJECT(
mangeur REF Carnivore,
mange REF Herbivore,
poidsMangeParJour float
);
/
CREATE TABLE tCarnivore OF Carnivore(
PRIMARY KEY(nom)
);
/
CREATE TABLE tHerbivore OF Herbivore(
PRIMARY KEY(nom)
);
/
CREATE TABLE tMange OF Mange(
SCOPE FOR(mangeur) IS tCarnivore,
SCOPE FOR(mange) IS tHerbivore
);
Question
Implémentez la méthode permettant de calculer le poids total d'herbivore mangé par un carnivore par jour.
Solution
CREATE TYPE BODY Carnivore
IS
MEMBER FUNCTION poidsMangeParJourTotal RETURN float
IS
vTotal float;
BEGIN
SELECT SUM(tm.poidsMangeParJour) INTO vTotal
FROM tMange tm
WHERE tm.mangeur.nom=self.nom;
RETURN vTotal;
END;
END;
Question
Écrivez une requête qui permet de retourner tous les carnivores, triés par leur poids, avec le poids total d'herbivore qu'ils mangent par jour.
Solution
SELECT tc.nom, tc.poidsMangeParJourTotal()
FROM tCarnivore tc
ORDER BY tc.poids;
Question
Proposez et implémentez une solution d'optimisation pour améliorer les performances de la requête précédente. Justifiez votre choix et expliquez, éventuellement à l'aide d'un petit schéma ou d'un exemple, pourquoi l'exécution sera améliorée.
Solution
CREATE INDEX TCARNIVORE_POIDS_IDX ON tCarnivore (poids);