Bonjour à tous,
Envoyé par
escartefigue
À préciser
En attendant que Bettybroute donne son avis, je reviens sur ce point en particulier :
Envoyé par
fsmrel
Si le MCD que je propose est conforme aux règles de gestion, pour combler cette lacune SQL, on passera à une solution alternative permettant quand même la prise en compte automatique de cette contrainte.
Et supposons donc que le MCD en question soit conforme aux règles de gestion. La solution alternative est la suivante, qui permet de prendre en compte la contrainte d’inclusion directement au stade CREATE TABLE, donc de ne pas avoir à injecter de code la garantissant (triggers procédures, etc.) :
Il ne s’agit pas (quoique...) d’un MCD à présenter à l’utilisateur (maîtrise d’oeuvre), mais en tout cas d’un MCD orienté génération du code SQL. Il s’agit d’établir une association entre une classe d’entités (par exemple PRIX) et l’association TAILLE_COULEUR du MCD précédent. Comme Merise refuse d’associer une association à quoi que ce soit, on commence par transformer TAILLE_COULEUR en classe d’entités, ce que Looping sait faire de lui -même (merci Paprick !). Au passage, renommons TAILLE_COULEUR par exemple en PRIX. Mais maintenant, c’est l’association PRODUIT_TAILLE du MCD précédent qu’on veut associer à PRIX : une fois de plus Merise ne le permet pas, mais même pas grave, on demande à Looping de transformer PRODUIT_TAILLE en classe d’entités et on associe celle-ci à PRIX (association PRODUIT_PRIX). Suite à cela, l’association PRODUIT_COULEUR du MCD précédent devient sans emploi car redondante (donc source d’erreur), on la vire. En effet, la couleur est connue par l’association PRODUIT_PRIX comme le montre le code SQL généré par Looping :
CREATE TABLE GAMME
(
gammeId INT,
gammeNom VARCHAR(50) NOT NULL,
CONSTRAINT GAMME_PK PRIMARY KEY(gammeId)
);
CREATE TABLE PRODUIT
(
produitId INT,
produitNom VARCHAR(50) NOT NULL,
gammeId INT NOT NULL,
CONSTRAINT PRODUIT_PK PRIMARY KEY(produitId),
CONSTRAINT PRODUIT_GAMME_FK FOREIGN KEY(gammeId) REFERENCES GAMME(gammeId)
);
CREATE TABLE COULEUR
(
couleurId INT,
couleurNom VARCHAR(50) NOT NULL UNIQUE,
CONSTRAINT COULEUR_PK PRIMARY KEY(couleurId)
);
CREATE TABLE TAILLE
(
tailleId INT,
taille DECIMAL(4,2) NOT NULL UNIQUE,
CONSTRAINT TAILLE_PK PRIMARY KEY(tailleId)
);
CREATE TABLE PRODUIT_TAILLE
(
tailleId INT,
produitId INT,
poids DECIMAL(4,2) NOT NULL,
CONSTRAINT PRODUIT_TAILLE_PK PRIMARY KEY(tailleId, produitId),
CONSTRAINT PRODUIT_TAILLE_TAILLE_FK FOREIGN KEY(tailleId) REFERENCES TAILLE(tailleId),
CONSTRAINT PRODUIT_TAILLE_PRODUIT_FK FOREIGN KEY(produitId) REFERENCES PRODUIT(produitId)
);
CREATE TABLE PRIX
(
tailleId INT,
couleurId INT,
prix INT NOT NULL,
reference VARCHAR(48) NOT NULL,
CONSTRAINT PRIX_PK PRIMARY KEY(tailleId, couleurId),
CONSTRAINT PRIX_TAILLE_FK FOREIGN KEY(tailleId) REFERENCES TAILLE(tailleId),
CONSTRAINT PRIX_COULEUR_FK FOREIGN KEY(couleurId) REFERENCES COULEUR(couleurId)
);
CREATE TABLE PRODUIT_PRIX
(
tailleId INT,
couleurId INT,
tailleId_1 INT,
produitId INT,
CONSTRAINT PRODUIT_PRIX_PK PRIMARY KEY(tailleId, couleurId, tailleId_1, produitId),
CONSTRAINT PRODUIT_PRIX_PRIX_FK FOREIGN KEY(tailleId, couleurId) REFERENCES PRIX(tailleId, couleurId),
CONSTRAINT PRODUIT_PRIX_PRODUIT_TAILLE_1_FK FOREIGN KEY(tailleId_1, produitId) REFERENCES PRODUIT_TAILLE(tailleId, produitId)
);
Mais on constate que la structure de la table PRODUIT_PRIX comporte une redondance des colonnes tailleId et tailleId_1, et au lieu d’établir une contrainte pour garantir que les valeurs prises par ces colonnes soit strictement les mêmes (trigger en perspective...), le plus simple est d’en virer une, d’où les ALTER TABLE, permettant de procéder au réglage du tir (noter la structure correcte cette fois-ci de la clé primaire) :
ALTER TABLE PRODUIT_PRIX
DROP CONSTRAINT PRODUIT_PRIX_PRODUIT_TAILLE_1_FK
, CONSTRAINT PRODUIT_PRIX_PK
, COLUMN tailleId_1 ;
ALTER TABLE PRODUIT_PRIX
ADD CONSTRAINT PRODUIT_PRIX_PK
PRIMARY KEY(tailleId, couleurId, produitId)
, CONSTRAINT PRODUIT_PRIX_PRODUIT_TAILLE_FK
FOREIGN KEY(tailleId, produitId)
REFERENCES PRODUIT_TAILLE(tailleId, produitId) ;
En passant, cette façon de procéder vaut dans le cas général, c’est-à-dire quand des classes d’entités sont impliquées dans une boucle (TAILLE, PRODUIT_TAILLE, PRIX dans le cas présent), c’est-à-dire virer une des deux colonnes redondantes.
Partager