Bonsoir Del,
A propos des chemins différents, menant de A à Z.
Reprenons le 1er MCD présenté dans le message #32 :
On observe l’existence d’une boucle, d’un cycle, dont les associations entre entités-types METIER, POSTE, EQUIPE, QUALIFICATION sont la cause. Ainsi, à partir de l’entité-type EQUIPE, via POSTE, on peut « naviguer » vers METIER selon un 1er chemin, et via QUALIFICATION, naviguer vers METIER selon un 2e chemin, mais rien n’impose que, selon le chemin utilisé, les métiers sélectionnés soient strictement les mêmes, alors que du point de vue de l’application, il doit en être ainsi : si l’on n’y prenait garde, il pourrait y avoir des incohérences dans la base de données...
Exemple légal au vu du modèle, mais illégal vu de l’application :
L’équipe e1 fait référence au poste p1, lequel fait référence au métier m1 ;
L’équipe e1 fait référence à la qualification q1 laquelle fait référence au métier m2.
En théorie, dans le cadre de la théorie relationnelle (alias modèle relationnel de données) on devrait mettre en oeuvre une contrainte ad-hoc, vérifiant que m1 = m2.
Ici, il suffit d’aménager le MLD produit par DB-MAIN.
Le MLD à l’état brut :
Dans l’état du MLD, les incohérences évoquées sont rendues possibles du fait de l’existence dans la table EQUIPE de l’attribut EQU_metierId en plus de l’attribut metierId, alors qu’il fait double emploi. Pour empêcher ces incohérences, on doit en théorie mettre en oeuvre une contrainte forçant ces deux attributs à prendre les mêmes valeurs : le plus simple est évidemment de les fondre en un seul, l’égalité est alors effective, question de bon sens.
Techniquement parlant, on va se débarrasser de l’attribut EQU_metierId, mais en le remplaçant d’abord par metierId dans la clé étrangère (ref) {EQU_prestationId, EQU_metierId}, puis en le supprimant dans les clés candidates (id et id’).
Mettons les mains dans le cambouis. En cliquant sur la clé étrangère en cause, on provoque l’ouverture la boîte de propriétés associée :
En cliquant sur la propriété « components », on provoque l’ouverture de la fenêtre « Multiple choice dialog », dans laquelle on effectuera un « Remove » de l’attribut EQU_metierId, puis, pour le remplacer, un « Add Next » de l’attribut metierId :
Au résultat :
Ceci fait, on peut supprimer l’attribut EQU_metierId dans les clés candidates id et id’. Là encore, on passe par la boîte de propriétés, où l’on clique sur la propriété « components ». Exemple avec la clé id :
Dans la fenêtre « Multiple choice dialog », on effectue un « Remove » décisif de l’attribut EQU_metierId :
Au résultat :
De la même façon, on débarrasse la clé id’ de l’attribut EQU_metierId. Au résultat :
Les clés candidates et étrangères ayant été débarrassées de l’attribut EQU_metierId, on peut supprimer ce dernier qui est devenu sans emploi. Au résultat :
Désormais, quel que soit le chemin emprunté, c'est-à-dire via POSTE ou QUALIFICATION, chaque équipe ne peut faire référence qu’à un seul métier.
En complément, histoire de se débarrasser d’un préfixe « EQU » qui n’apporte rien, on renomme EQU_prestationId en prestationId. DB-MAIN renomme de lui-même l’attribut dans les clés :
Script SQL produit par DB-MAIN (table EQUIPE, attribut periode : j’ai ajouté le type daterange manuellement) :
create table METIER (
metierId int not null,
metierNom varchar(32) not null,
constraint ID_METIER primary key (metierId));
create table PERSONNE (
personneId int not null,
personneNom varchar(32) not null,
constraint ID_PERSONNE primary key (personneId));
create table QUALIFICATION (
metierId int not null,
personneId int not null,
constraint ID_QUALIFICATION primary key (metierId, personneId));
create table PRESTATION (
prestationId int not null,
prestationNom varchar(32) not null,
constraint ID_PRESTATION_ID primary key (prestationId));
create table POSTE (
prestationId int not null,
metierId int not null,
quantite int not null,
constraint ID_POSTE primary key (prestationId, metierId));
create table EQUIPE (
prestationId int not null,
metierId int not null,
equipeid int not null,
personneId int not null,
periode daterange not null,
constraint ID_EQUIPE primary key (prestationId, metierId, personneId, equipeid),
constraint SID_EQUIPE unique (prestationId, metierId, personneId, periode));
alter table EQUIPE add constraint FKEQU_QUA
foreign key (metierId, personneId)
references QUALIFICATION (metierId, personneId);
alter table EQUIPE add constraint FKEQU_POS
foreign key (prestationId, metierId)
references POSTE (prestationId, metierId);
alter table POSTE add constraint FKPOS_MET
foreign key (metierId)
references METIER (metierId);
alter table POSTE add constraint FKPOS_PRE
foreign key (prestationId)
references PRESTATION (prestationId);
alter table QUALIFICATION add constraint FKQUA_MET
foreign key (metierId)
references METIER (metierId);
alter table QUALIFICATION add constraint FKQUA_PER
foreign key (personneId)
references PERSONNE (personneId);
A suivre : prise en compte des entités-types FILM, PRE_FILM et de l'association EPF.
Partager