Des voitures et des hommes
[30 minutes]
Soit le diagramme de classe UML suivant :
Question
A partir de ce modèle conceptuel établissez un modèle logique en relationnel-objet, sachant que le cœur du problème concerne la gestion des voitures.
Indice
On utilisera des OID pour disposer de clés artificielles.
Solution
Type ListePrénom: collection de <string>
Type Personne : <
nom:string,
prénom:ListePrénom,
dateNaissance:date,
=age():entier
>
Type Conducteur : <
fkPersonne:string,
typePermis:char={A,B,E},
datePermis:date
>
tPersonne de Personne (#nom)
tConducteur de Conducteur (#fkPersonne=>Personne(nom))
Type RefConducteur : <fkConducteur =>o tConducteur>
Type ListeRefConducteur : collection de <RefConducteur>
Type Voiture : <
type:string,
marque:string,
nbPortes:integer,
puissance:integer,
kilométrage:integer,
fkPropriétaire =>o tPersonne,
fkConducteurs:ListeRefConducteur
>
tVoiture de Voiture (#type, #marque)
L'héritage n'est pas complet (cf. les associations), ni exclusif (il existe des personnes qui ne sont pas des conducteurs), donc la transformation la plus adaptée est l'héritage par référence. On utilise la référence classique (clé étrangère) entre tConducteur et tPersonne), plutôt que la référence à un OID, pour pouvoir déclarer le nom fkPersonne comme clé dans tConducteur.
On notera que l'on a choisi d'imbriquer la relation N:M dans la classe Voiture, ce qui est justifié par le fait que la gestion des voitures est au centre du modèle.
Question
Proposer une implémentation sous Oracle de votre modèle logique.
Solution
CREATE OR REPLACE TYPE ListePrenom AS TABLE OF varchar(20);
/
CREATE OR REPLACE TYPE Personne AS OBJECT (
nom varchar(20),
prenom ListePrenom,
dateNaissance date,
MEMBER FUNCTION age RETURN number
);
/
CREATE OR REPLACE TYPE BODY Personne
IS
MEMBER FUNCTION age RETURN number
IS
BEGIN
RETURN trunc(months_between(SYSDATE, dateNaissance)/12);
END;
END;
/
CREATE OR REPLACE TYPE Conducteur AS OBJECT(
fkPersonne varchar(20),
typePermis char(1),
datePermis date
);
/
CREATE OR REPLACE TYPE RefConducteur AS OBJECT (fkConducteur REF Conducteur);
/
CREATE OR REPLACE TYPE ListeRefConducteur AS TABLE OF RefConducteur;
/
CREATE OR REPLACE TYPE Voiture AS OBJECT (
type varchar(20),
marque varchar(20),
nbPortes number,
puissance number,
kilometrage number,
fkProprietaire REF Personne,
fkConducteurs ListeRefConducteur
);
/
CREATE TABLE tPersonne OF Personne (
PRIMARY KEY (nom)
)
NESTED TABLE prenom STORE AS nttPersonnePrenom;
/
CREATE TABLE tConducteur OF Conducteur (
PRIMARY KEY (fkPersonne),
FOREIGN KEY (fkPersonne) REFERENCES tPersonne (nom),
CHECK (typePermis IN ('A','B','E'))
);
/
CREATE TABLE tVoiture OF Voiture (
PRIMARY KEY (type, marque),
SCOPE FOR (fkProprietaire) IS tPersonne
)
NESTED TABLE fkConducteurs STORE AS nttVoiturefkConducteurs;
On notera que le choix d'implémentation de fkConducteurs en collection de références à des OID nous empêche dans l'implémentation sous Oracle de définir le SCOPE FOR et donc de contraindre l'intégrité référentielle à la table tConducteur. Dans le cas présent ce n'est pas préjudiciable dans la mesure où seule la table tConducteur contient des objets Conducteur.