Bonsoir,
Je viens seulement de découvrir l’article rédigé par Benoit Simard en 2016. Manifestement l’opérateur JOIN de la théorie relationnelle de Codd - et repris par la suite dans SQL - n’y est pas en odeur de sainteté...
Quoi qu’il en soit, on a une présentation d’un système orienté graphe, Neo4j, gérant des noeuds et leurs relations. Au paragraphe I-C-3-a, on apprend qu’une relation connecte un noeud de départ à un noeud d’arrivée : une relation est donc exclusivement binaire. Ainsi une relation ternaire (et plus) ne peut pas être prise en compte en tant que telle. Pour ma part, en 40 ans de conception, de modélisation, d’audit de bases de données, j’ai eu à faire à des wagons de ce type de relations de degré > 2).
A titre d’exemple, je reprends ici la structure de base de données utilisée par l’inventeur du modèle relationnel de données, E. F. Codd (cf. son article A Data Base Sublanguage Founded on the Relational Calculus. IBM Research Report RJ893 (July 26th 1971)). Cet article largement cinquantenaire n’a pas vieilli.
j’ai repris cette structure en utilisant Looping (enfant du professeur Patrick Bergougnoux, Paprick chez developpez.com), sous la forme d’un MCD (modèle conceptuel des données) :
Pour l’utilisateur, le but de la manoeuvre est de savoir à quelle date, pour quels projets et en quelle quantité des pièces lui ont été livrées par ses fournisseurs.
Dans le MCD, Les entités-types (classes d’entités) sont les suivantes :
Supplier (fournisseur)
Part (produit)
Project (projet)
ShipDate (date de livraison)
Ces entités-types sont mises en relation au moyen de l’association Supply, porteuse de la quantité de pièces livrées (attribut Quantity).
Est en gras le nom de chaque attribut faisant l’objet d’un identifiant d’entité-type :
SupplierId, PartId, ProjectId (pour ces identifiants principaux, « primaires », le nom est souligné),
SupplierName, ProjectName sont des identifiants alternatifs.
Les cardinalités portées par les pattes d’association sont ici de deux types :
« 0,n » pour préciser qu’une entité-type participe facultativement à une ou plusieurs fois à une association (par exemple, un fournisseur peut participer à plusieurs livraisons),
« 1,n » pour préciser qu’une entité-type doit participer au moins une fois à l’association (un projet a fait l’objet d’au moins une livraison).
Looping nous fournit le code SQL suivant, inféré du MCD :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| CREATE TABLE Supplier
(
SupplierId CHAR(4),
SupplierName VARCHAR(50) NOT NULL,
Location VARCHAR(50) NOT NULL,
CONSTRAINT Supplier_PK PRIMARY KEY(SupplierId),
CONSTRAINT Supplier_AK UNIQUE(SupplierName)
);
CREATE TABLE Part
(
PartId CHAR(4),
PartName VARCHAR(50) NOT NULL,
Color VARCHAR(16) NOT NULL,
Weight SMALLINT NOT NULL,
QuantityOnHand SMALLINT NOT NULL,
CONSTRAINT Part_PK PRIMARY KEY(PartId),
);
CREATE TABLE Project
(
ProjectId CHAR(4),
ProjectName VARCHAR(50) NOT NULL,
ManagerName VARCHAR(50) NOT NULL,
CONSTRAINT Project_PK PRIMARY KEY(ProjectId),
CONSTRAINT Project_AK UNIQUE(ProjectName)
);
CREATE TABLE Supply
(
SupplierId CHAR(4),
PartId CHAR(4),
ProjectId CHAR(4),
ShipDate DATE,
Quantity SMALLINT NOT NULL,
CONSTRAINT Supply_PK PRIMARY KEY(SupplierId, PartId, ProjectId, ShipDate),
CONSTRAINT Supply_Supplier_FK FOREIGN KEY(SupplierId) REFERENCES Supplier(SupplierId),
CONSTRAINT Supply_Part_FK FOREIGN KEY(PartId) REFERENCES Part(PartId),
CONSTRAINT Supply_Project_FK FOREIGN KEY(ProjectId) REFERENCES Project(ProjectId)
) ; |
Code auquel il faut ajouter une contrainte garantissant la participation d’un projet à au moins une livraison :
1 2
| CREATE ASSERTION Project_Supply_Chk CHECK
(select count(y.ProjectId) from Supply y join Inserted i on y.ProjectId = i.ProjectId) > 0) |
Le SGBD que j’utilise ici (à savoir SQL Server) ne connaissant pas l’instruction CREATE ASSERTION, je pallie au moyen d’un trigger :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| CREATE TRIGGER Project_Supply_Chk on Project after insert, update as
begin
declare @errTexte as varchar (255) -- message d'erreur
declare @ProjectName as varchar(24) projet illégal
if (select count(y.ProjectId) from Supply y join Inserted i on y.ProjectId = i.ProjectId) = 0
begin
set @ProjectName = (select top (1) ProjectName from Inserted)
set @errTexte =
char(13)
+ 'Un projet doit être associé à au moins un fournisseur (Supplier) et une pièce (Part).'
+ char(13)
+ 'Le projet '''
+ @ProjectName
+ ''' ne répond pas à cette obligation.'
+ char(13)
; throw 314116, @errTexte, 16
end ;
end |
A noter que la clé primaire de la table Supply est une conséquence de la dépendance fonctionnelle suivante :
DF1 : {SupplierId, PartId, ProjectId, ShipDate} → {Quantity}
Questions que je pose dans le contexte de Neo4j :
(Q1) Comment garantir cette dépendance fonctionnelle ?
(Q2) Comment garantir la contrainte Project_Supply_Chk ?
Suite à l’examen effectué par le service des achats, une modification doit être apportée dans le contenu de la base de données : ce n’est pas le projet j001 (ProjectId = 'j001') mais le projet j998 (ProjectId = 'j998') qui, en date du 18 janvier 1971, a fait l’objet de la livraison des pièces p001 (PartId = 'p001') par le fournisseur s001 (SupplierId = 's001').
(Q3) Avec Neo4j, comment effectuer cette mise à jour de la base de données ?
Je vous remercie d’avance pour vos réponses.
Partager