Des voitures et des hommes

[30 minutes]

Soit le diagramme de classe UML suivant :

Des voitures...

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

1
Type ListePrénom: collection de <string>
2
Type Personne : <
3
  nom:string,
4
  prénom:ListePrénom,
5
  dateNaissance:date,
6
  =age():entier
7
>
8
Type Conducteur : <
9
  fkPersonne:string,
10
  typePermis:char={A,B,E},
11
  datePermis:date
12
>
13
tPersonne de Personne (#nom)
14
tConducteur de Conducteur (#fkPersonne=>Personne(nom))
15
16
Type RefConducteur : <fkConducteur =>o tConducteur>
17
Type ListeRefConducteur : collection de <RefConducteur>
18
Type Voiture : <
19
  type:string,
20
  marque:string,
21
  nbPortes:integer,
22
  puissance:integer,
23
  kilométrage:integer,
24
  fkPropriétaire =>o tPersonne,
25
  fkConducteurs:ListeRefConducteur
26
>
27
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

1
CREATE OR REPLACE TYPE ListePrenom AS TABLE OF varchar(20);
2
/
3
CREATE OR REPLACE TYPE Personne AS OBJECT (
4
  nom varchar(20),
5
  prenom ListePrenom,
6
  dateNaissance date,
7
  MEMBER FUNCTION age RETURN number
8
);
9
/
10
CREATE OR REPLACE TYPE BODY Personne
11
IS 
12
  MEMBER FUNCTION age RETURN number
13
  IS
14
  BEGIN 
15
    RETURN trunc(months_between(SYSDATE, dateNaissance)/12);
16
  END; 
17
END;
18
/
19
CREATE OR REPLACE TYPE Conducteur AS OBJECT(
20
  fkPersonne varchar(20),
21
  typePermis char(1),
22
  datePermis date
23
);
24
/
25
CREATE OR REPLACE TYPE RefConducteur AS OBJECT (fkConducteur REF Conducteur);
26
/
27
CREATE OR REPLACE TYPE ListeRefConducteur AS TABLE OF RefConducteur;
28
/
29
CREATE OR REPLACE TYPE Voiture AS OBJECT (
30
  type varchar(20),
31
  marque varchar(20),
32
  nbPortes number,
33
  puissance number,
34
  kilometrage number, 
35
  fkProprietaire REF Personne,
36
  fkConducteurs ListeRefConducteur
37
);
38
/
39
CREATE TABLE tPersonne OF Personne (
40
  PRIMARY KEY (nom)
41
)
42
NESTED TABLE prenom STORE AS nttPersonnePrenom;
43
/
44
CREATE TABLE tConducteur OF Conducteur (
45
  PRIMARY KEY (fkPersonne),
46
  FOREIGN KEY (fkPersonne) REFERENCES tPersonne (nom),
47
  CHECK (typePermis IN ('A','B','E'))
48
);
49
/
50
CREATE TABLE tVoiture OF Voiture (
51
  PRIMARY KEY (type, marque),
52
  SCOPE FOR (fkProprietaire) IS tPersonne
53
)
54
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.