Bonsoir,
Envoyé par
matheous
Le MCD reste en quelque sorte pour moi de la théorie... J'ai du mal a comprendre sans quelque chose de concret.
Un MCD est un modèle, il n’est donc pas de la théorie. Depuis plus de trente ans que j’utilise des MCD, je m’en suis beaucoup servi chez mes clients, comme support de communication auprès de la maîtrise d’oeuvre, voire de la maîtrise d’ouvrage, gens comprenant vite la méthode de construction.
Le MCD a un côté bande dessinée indéniable, mais il n’en demeure pas moins que le MLD puis le code SQL (les create table) en sont la conséquence et donc il vaut mieux ne pas se fourvoyer à ce stade. De même le MCD est lui-même la conséquence des règles de gestion qui doivent évidemment être formulées de façon exhaustive et rigoureuse.
Vous avez du mal à comprendre sans quelque chose de concret : d’accord, on va mettre les mains dans le cambouis avec des exemples.
Partons du code SQL suivant :
CREATE TABLE CHAUFFEUR
(
chauffeurId INTEGER NOT NULL
, chauffeurMatricule VARCHAR(12) NOT NULL
, chauffeurNom VARCHAR(48) NOT NULL
, chauffeurTel VARCHAR(20) NOT NULL DEFAULT ' '
, CONSTRAINT CHAUFFEUR_PK PRIMARY KEY (chauffeurId)
, CONSTRAINT CHAUFFEUR_AK UNIQUE (chauffeurMatricule)
);
CREATE TABLE VOITURE
(
voitureId INTEGER NOT NULL
, voitureImmat VARCHAR(12) NOT NULL
, voitureMarque VARCHAR(24) NOT NULL
, voitureModele VARCHAR(48) NOT NULL DEFAULT ' '
, CONSTRAINT VOITURE_PK PRIMARY KEY (voitureId)
, CONSTRAINT VOITURE_AK UNIQUE (voitureImmat)
);
CREATE TABLE COURSE
(
voitureId INTEGER NOT NULL
, chauffeurId INTEGER NOT NULL
, dateHeureDebut DATETIME NOT NULL
, dateHeureFin DATETIME NOT NULL DEFAULT '9999-12-31 23:59:59'
, CONSTRAINT COURSE_AK1 UNIQUE (voitureId, dateHeureDebut)
, CONSTRAINT COURSE_AK2 UNIQUE (chauffeurId, dateHeureDebut)
, CONSTRAINT COURSE_AK3 UNIQUE (voitureId, dateHeureFin)
, CONSTRAINT COURSE_AK4 UNIQUE (chauffeurId, dateHeureFin)
, CONSTRAINT COURSE_VOITURE_FK FOREIGN KEY (voitureId)
REFERENCES VOITURE (voitureId)
, CONSTRAINT COURSE_CHAUFFEUR_FK FOREIGN KEY (chauffeurId)
REFERENCES CHAUFFEUR (chauffeurId)
, CONSTRAINT COURSE_DATE_CHK CHECK (dateHeureDebut < dateHeureFin)
);
Un trigger pour les inserts dans la table COURSE :
DROP TRIGGER IF EXISTS COURSE_INSERT ;
delimiter GO
CREATE TRIGGER COURSE_INSERT BEFORE INSERT ON COURSE
FOR EACH ROW
BEGIN
set @pNew = NEW.chauffeurId ;
set @vNew = NEW.voitureId ;
set @debutNew = NEW.dateHeureDebut ;
set @finNew = NEW.dateHeureFin ;
set @engueulade1 = ' : à T, une voiture n’est conduite que par un seul chauffeur.' ;
set @engueulade2 = ' : à T, un chauffeur ne conduit qu’une seule voiture.' ;
/* -- ------------------------------------------------------
-- Au cours d’un l’intervalle de temps donné,
-- une voiture n’est conduite que par un seul chauffeur
*/ -- ------------------------------------------------------
set @N = (SELECT COUNT(*)
FROM COURSE
WHERE voitureId = @vNew AND dateHeureDebut <> @debutNew
IF @N > 0 THEN
SET @erreur = CONCAT('voitureId = ', @vNew, ' ; chauffeurId = ', @pNew, ' ; début = ', @debutNew, @engueulade1) ;
SIGNAL SQLSTATE '45001' SET MESSAGE_TEXT = @erreur ;
END IF ;
/* -- ------------------------------------------------------
-- Au cours d’un l’intervalle de temps donné,
-- un chauffeur ne conduit qu’une seule voiture
*/ -- ------------------------------------------------------
set @N = (SELECT COUNT(*)
FROM COURSE
WHERE chauffeurId = @pNew AND dateHeureDebut <> @debutNew
IF @N > 0 THEN
SET @erreur = CONCAT('voitureId = ', @vNew, ' ; chauffeurId = ', @pNew, ' ; début = ', @debutNew, @engueulade2) ;
SIGNAL SQLSTATE '45001' SET MESSAGE_TEXT = @erreur ;
END IF ;
END
GO
delimiter ;
Si les requêtes SQL ne sont pas valides, escartefigue ne manquera pas de les corriger, car il ne laisse rien passer…
Un début de jeu d’essai, dans lequel le recouvrement de dates est omniprésent :
INSERT INTO CHAUFFEUR (chauffeurId, chauffeurMatricule, chauffeurNom)
VALUES
(1, 'Fernand', 'Fernand Naudin'), (2, 'Raoul', 'Raoul Volfoni'), (3, 'Paul', 'Paul Volfoni')
;
SELECT * FROM CHAUFFEUR ;
INSERT INTO VOITURE (voitureId, voitureImmat, voitureMarque)
VALUES
(1, '1 ZAA 75', 'Peugeot'), (2, '2 ZBB 75', 'Peugeot')
;
SELECT * FROM VOITURE ;
INSERT INTO COURSE (voitureId, chauffeurId, dateHeureDebut, dateHeureFin)
VALUES
(1, 1, '2019-02-01 12:00:00', '2019-07-02 12:30:00')
, (1, 2, '2019-02-01 12:02:00', '2019-02-01 12:25:00')
, (2, 1, '2019-02-01 12:05', '2019-07-02 12:35')
, (2, 2, '2019-02-01 12:08', '2019-02-01 12:15')
, (2, 3, '2019-02-01 12:09', '2019-02-01 12:23')
;
SELECT * FROM COURSE ;
Envoyé par
matheous
Donc l'entité-type Cars_Data doit être associée avec la table Fares ?
Je reprends ce que vous aviez écrit auparavant :
Envoyé par
matheous
le chauffeur aura des données à renseigner à chaque début de course (d'où l'entité Cars_data).
Dans la mesure où le chauffeur fournira impérativement ces données concernant la voiture impliquée dans la course, Cars_data devient inutile, c’est la table COURSE qui devra héberger ces données.
Quand les choses seront stabilisées, on pourra remonter sur le pont et revenir sur le concept de CIF.
Partager