Bonjour OZ1977,
Je découvre bien tard votre message, mais il n’est pas situé au bon endroit : le forum schéma eut été préférable.
Votre diagramme est illisible en ce qui concerne les associations entre entités-types, il serait bon de le reprendre avec l’excellent Looping, gracieusement proposé par le professeur Patrick Bergougnoux.
Envoyé par
OZ1977
Un Client peut effectuer plusieurs Commandes et une Commande peut être associée à plusieurs Clients.
Je suppose que les clients en question seront réunis autour de la table référencée par une même commande.
Envoyé par
OZ1977
je pense pouvoir simplifier avec une relation ternaire Commandes_Utilisateurs_Commentaires.
Par ailleurs, les utilisateurs ne pouvant poster qu'un seul commentaire par commande et par utilisateur les commentaires sont associées à la tables associative par une relation 1 à 1.
En fait, cette cardinalité 1,1 n’empêche pas que l’on puisse associer un commentaire donné à un client cl1 et à une commande cd1 qui n’est pas associée à cl1.
Exemple plus conforme avec Looping :
A ma demande, Looping a transformé l’association CLI_COM en entité-type. L’identifiant de celle-ci est {clientId, CdeId}, en notant que la cardinalité 1,1(R) portée par la patte connectant l’entité-type CLI_COM et l’association CLI_COM_CLI est à interpréter ainsi : une occurrence de CLI_COM fait référence à un et un seul client et CLI_COM hérite de l’identifiant de CLIENT (principe de identification relative).
Le principe de l’identification relative vaut pour l’association de CLI_COM avec COMMANDE, et pour l’association de CLI_COM avec AVIS.
La patte connectant CLI_COM et AVIS_CLI_COM est 0,1 dans la mesure où un client ne pourrait fournir qu’un seul commentaire par commande. A noter qu’avec ce MCD, un client ne peut donner d’avis que sur les repas auxquels il a participé.
Code SQL produit par Looping :
CREATE TABLE CLIENT
(
clientId INT,
clientNom VARCHAR(32) NOT NULL,
CONSTRAINT CLIENT_PK PRIMARY KEY(clientId),
CONSTRAINT CLIENT_AK UNIQUE(clientNom)
);
CREATE TABLE TABLEE
(
tableId INT,
tableNumero CHAR(2) NOT NULL,
nbCouverts TINYINT NOT NULL,
CONSTRAINT TABLEE_PK PRIMARY KEY(tableId),
CONSTRAINT TABLEE_AK UNIQUE(tableNumero)
);
CREATE TABLE COMMANDE
(
cdeId INT,
cdeNumero CHAR(8) NOT NULL,
cdeDate DATE NOT NULL,
cdeReglee BIT NOT NULL,
tableId INT NOT NULL,
CONSTRAINT COMMANDE_PK PRIMARY KEY(cdeId),
CONSTRAINT COMMANDE_AK UNIQUE(cdeNumero),
CONSTRAINT COMMANDE_TABLEE_FK FOREIGN KEY(tableId)
REFERENCES TABLEE(tableId)
);
CREATE TABLE CLI_COM
(
clientId INT,
cdeId INT,
CONSTRAINT CLI_COM_PK PRIMARY KEY(clientId, cdeId),
CONSTRAINT CLI_COM_CLIENT_FK FOREIGN KEY(clientId)
REFERENCES CLIENT(clientId),
CONSTRAINT CLI_COM_COMMANDE_FK FOREIGN KEY(cdeId)
REFERENCES COMMANDE(cdeId)
);
CREATE TABLE AVIS
(
clientId INT,
cdeId INT,
commentaire VARCHAR(96) NOT NULL,
CONSTRAINT AVIS_PK PRIMARY KEY(clientId, cdeId),
CONSTRAINT AVIS_CLI_COM_FK FOREIGN KEY(clientId, cdeId)
REFERENCES CLI_COM(clientId, cdeId)
);
Quel est votre SGBD ?
S’il faut s’assurer que les commentaires des clients ne sont possibles qu’une une fois qu'ils ont payé, alors cela ne sera possible que par l’entremise d’un trigger (tous SGBD) ou d’une fonction (ça dépend du SGBD). Même chose si le nombre de clients pour une commande donnée ne doit pas être supérieur au nombre de couverts de la table associée à la commande, etc.
Un jeu d’essai :
INSERT INTO CLIENT (clientId, clientNom)
VALUES
(1, 'Fernand Naudin')
, (2, 'Maître Folace')
, (3, 'Raoul Volfoni')
, (4, 'Paul Volfoni')
, (5, 'Jean')
, (6, 'Antoine Delafoy')
, (7, 'Patricia')
, (8, 'Madame Mado')
;
SELECT * FROM CLIENT ;
=>
clientId clientNom
1 Fernand Naudin
2 Maître Folace
3 Raoul Volfoni
4 Paul Volfoni
5 Jean
6 Antoine Delafoy
7 Patricia
8 Madame Mado
INSERT INTO TABLEE (tableId, tableNumero, nbCouverts)
VALUES
(1, 'ta', 3)
, (2, 'tb', 3)
, (3, 'tc', 4)
;
SELECT * FROM TABLEE ;
=>
tableId tableNumero nbCouverts
1 ta 3
2 tb 3
3 tc 4
INSERT INTO COMMANDE (cdeId, cdeNumero, tableId, cdeDate, cdeReglee)
VALUES
(1, 'c0247', 2, '2020-12-05', 0)
, (2, 'c0364', 2, '2020-12-06', 0)
, (3, 'c1234', 3, '2020-12-12', 0)
;
SELECT * FROM COMMANDE ;
=>
cdeId cdeNumero tableId cdeDate cdeReglee
1 c0247 2 2020-12-05 0
2 c0364 2 2020-12-06 0
3 c1234 3 2020-12-12 0
INSERT INTO CLI_COM (clientId, cdeId)
VALUES
((SELECT clientId FROM CLIENT WHERE clientNom = 'Fernand Naudin')
, (SELECT cdeId FROM COMMANDE WHERE cdeNumero = 'c0247'))
,
((SELECT clientId FROM CLIENT WHERE clientNom = 'Maître Folace')
, (SELECT cdeId FROM COMMANDE WHERE cdeNumero = 'c0247'))
,
((SELECT clientId FROM CLIENT WHERE clientNom = 'Madame Mado')
, (SELECT cdeId FROM COMMANDE WHERE cdeNumero = 'c0247'))
;
INSERT INTO CLI_COM (clientId, cdeId)
VALUES
((SELECT clientId FROM CLIENT WHERE clientNom = 'Fernand Naudin')
, (SELECT cdeId FROM COMMANDE WHERE cdeNumero = 'c1234'))
,
((SELECT clientId FROM CLIENT WHERE clientNom = 'Maître Folace')
, (SELECT cdeId FROM COMMANDE WHERE cdeNumero = 'c1234'))
,
((SELECT clientId FROM CLIENT WHERE clientNom = 'Madame Mado')
, (SELECT cdeId FROM COMMANDE WHERE cdeNumero = 'c1234'))
,
((SELECT clientId FROM CLIENT WHERE clientNom = 'Raoul Volfoni')
, (SELECT cdeId FROM COMMANDE WHERE cdeNumero = 'c1234'))
;
INSERT INTO CLI_COM (clientId, cdeId)
VALUES
((SELECT clientId FROM CLIENT WHERE clientNom = 'Fernand Naudin')
, (SELECT cdeId FROM COMMANDE WHERE cdeNumero = 'c0364'))
,
((SELECT clientId FROM CLIENT WHERE clientNom = 'Maître Folace')
, (SELECT cdeId FROM COMMANDE WHERE cdeNumero = 'c0364'))
,
((SELECT clientId FROM CLIENT WHERE clientNom = 'Madame Mado')
, (SELECT cdeId FROM COMMANDE WHERE cdeNumero = 'c0364'))
;
SELECT clientNom, cdeNumero
FROM CLI_COM as x
JOIN CLIENT as y ON x.clientId = y.clientId
JOIN COMMANDE as z ON x.cdeId = z.cdeId
JOIN CLI_COM as t ON t.clientId = x.clientId
AND t.cdeId = z.cdeId
ORDER BY cdeNumero, clientNom
;
=>
clientNom cdeNumero
Fernand Naudin c0247
Madame Mado c0247
Maître Folace c0247
Fernand Naudin c0364
Madame Mado c0364
Maître Folace c0364
Fernand Naudin c1234
Madame Mado c1234
Maître Folace c1234
Raoul Volfoni c1234
INSERT INTO AVIS (clientId, cdeId, commentaire)
VALUES
(
(SELECT clientId FROM CLIENT WHERE clientNom = 'Fernand Naudin')
, (SELECT cdeId FROM COMMANDE WHERE cdeNumero = 'c0364')
, 'Miam, miam !'
)
;
SELECT clientNom, cdeNumero, commentaire
FROM AVIS as a
JOIN CLI_COM as x ON a.clientId = x.clientId
AND a.cdeId = x.cdeId
JOIN CLIENT as y ON x.clientId = y.clientId
JOIN COMMANDE as z ON x.cdeId = z.cdeId
JOIN CLI_COM as t ON t.clientId = x.clientId
AND t.cdeId = z.cdeId
ORDER BY cdeNumero, clientNom
;
=>
clientNom cdeNumero commentaire
Fernand Naudin c0364 Miam, miam !
Partager