Bonsoir,
Dans son message précédent, JPhi33 a proposé la mise en oeuvre d’une contrainte d’inclusion. Je fournis ici des éléments de comparaison de cette solution par rapport à celle qui a été fournie par javass, bien épaulé par CinePhil, et certaines conclusions pouvant influer sur le choix du MLD.
Retour sur le MLD proposé par javass et CinePhil.
Pour faciliter le travail de comparaison, je présente le MLD correspondant à la base de données décrite dans mon message précédent (voir les instructions CREATE TABLE) :
Ce MLD correspond à la dérivation du dernier MCD proposé par javass, en y renommant la table Associer en Posseder et en établissant un lien entre les tables Posseder et Renseigner. La formule d’une classe est déterminée sans ambiguïté, grâce à la dépendance fonctionnelle cId → fId définie pour la table Renseigner et garantie par le trigger Renseigner_Trigger (qui pallie donc le viol de la 2NF). J’appellerai ce MLD : MLD orienté javass-CinePhil.
A noter que si le trigger Renseigner_Trigger (cf. mon message précédent) est utilisé pour contrôler les opérations d’INSERT, il doit être accompagné d'un 2e trigger pour contrôler les opérations d’UPDATE. En effet, rien ne nous empêche pour une classe donnée de modifier la formule et le paramètre qui lui sont associés. Accessoirement, au prix d’une certaine complication, des deux triggers on pourrait n’en faire qu’un, mais ça n’est pas notre objet.
Observons encore que si l’on se situe dans le contexte relationnel pur (par exemple en Tutorial D), la contrainte peut être ainsi traduite, de façon ramassée (à comparer avec les lourds et parfois bien compliqués triggers SQL) :
CONSTRAINT Renseigner_DF FORALL x, y ∈ Renseigner (x.cId = y.cId ⇒ x.fId = y.fId) ;
Ou encore, par référence à la norme SQL :
1 2 3 4 5 6 7
|
CREATE ASSERTION Renseigner_DF CHECK
(NOT EXISTS (
SELECT x.fId
FROM Renseigner AS x, Renseigner AS y
WHERE x.cId = y.cId
AND x.fId <> y.fId)) ; |
Présentation du MLD résultant de la contrainte d’inclusion proposée par JPhi33.
Ce MLD (appelons-le MLD orienté JPhi33) correspond à la dérivation du MCD proposé par javass dans son premier message (avec remplacement des cardinalités 0,1 en cardinalités 0,N en ce qui concerne les pattes branchées sur l’association-type Renseigner), enrichi de la représentation de la contrainte d’inclusion :
Cette contrainte d’inclusion pourrait s’exprimer ainsi au niveau du MLD :
En relation avec une paire {Classe, Formule} de la table Associer, chaque paire {Classe, Param} de la table Renseigner donne lieu à un triplet {Classe, Param, Formule} dont la projection {Param, Formule} doit faire référence à une paire {Param, Formule} de la table Posseder.
Ou, pour reprendre les noms des attributs utilisés pour le MLD :
En relation avec une paire {cId, fId} de la table Associer, chaque paire {cId, pId} de la table Renseigner donne lieu à un triplet {cId, pId, fId} dont la projection {pId, fId} doit faire référence à une paire {pId, fId} de la table Posseder.
Si l’on se situe dans le contexte relationnel pur (par exemple en Tutorial D), la contrainte pourrait être ainsi traduite :
CONSTRAINT Contrainte_Inclusion (Renseigner JOIN Associer) {pId, fId} ⊆ Posseder {pId, fId} ;
Si l’on se situe dans le contexte de la norme SQL, on peut coder par exemple :
1 2 3 4 5 6 7 8 9 10 11 12
|
CREATE ASSERTION Contrainte_Inclusion
CHECK (NOT EXISTS (
SELECT *
FROM Associer x JOIN Renseigner y
ON x.cId = y.cId
WHERE NOT EXISTS (
SELECT *
FROM Posseder z
WHERE y.pId = z.pId
AND x.fId = z.fId)
)) ; |
Ainsi, quand on est dans le contexte de la théorie relationnelle ou quand le SGBD propose l’instruction CREATE ASSERTION prévue par la norme SQL, la mise en œuvre des contraintes est simple, qu’il s’agisse du MLD orienté javass-CinePhil ou du MLD orienté JPhi33, avec un avantage malgré tout pour ce dernier, car le bonhomme NULL y est interdit de séjour. Pour que le MLD orienté javass-CinePhil fasse aussi bien, il faudrait prévoir une valeur par défaut, pour l’attribut cId de la table Renseigner, par exemple « cId = 0 » équivalent à « Classe sans formule ».
Les choses sont moins simples quand on utilise un SGBDR utilisant SQL et ne proposant pas l’instruction CREATE ASSERTION. En effet, on est obligé d’en passer par des triggers pour surveiller les mises à jour : une paire de triggers (INSERT, UPDATE) pour la table Associer, un triplet de triggers (INSERT, UPDATE, DELETE) pour la table Renseigner et une paire de triggers (UPDATE, DELETE) pour la table Posseder.
A la place, on pourrait envisager de créer une vue avec l’option "WITH CHECK OPTION" pour représenter la contrainte d’intégrité, mais il faudra lui attacher des triggers pour ventiler les mises à jour dans les tables de base.
On peut dire cette fois-ci que le MLD orienté javass-CinePhil devient économiquement plus intéressant.
Une autre solution consisterait à mettre en œuvre une table (appelons-la Inclusion) matérialisant la contrainte d’inclusion. Cette table a pour clé primaire la paire {cId, pId} :
Observations relatives à cette solution alternative.
1) A son tour, la table Inclusion viole la 2NF : comme dans le cas de la solution MLD orienté javass-CinePhil, il faudra prévoir une paire de triggers permettant de garantir la dépendance fonctionnelle cId → fId.
2) Qui plus est, la paire {cId, fId} de la table Inclusion redonde avec son homologue de la table Associer, et il faudra en conséquence prévoir une autre paire de triggers pour la table Inclusion, afin de garantir que la formule f de la classe c (table Inclusion) est bien celle que l’on a initialement dans la table Associer pour la classe c.
3) Si on analyse les conséquences des opérations de mise à jour impliquant les différentes tables et affectant la validité du contenu de la table Inclusion, on constate qu’il y a — pour le moins — un certain nombre de points sur lesquels il faut être vigilant. Il y aura encore quelques précautions à prendre et des triggers à développer. Chacun peut sexercer à découvrir les inconvénients de la mise en œuvre d’une table Inclusion, autres que ceux qui viennent d’être mentionnés, à savoir les inconvénients provoqués par les mises à jour portant sur les autres tables.
La solution alternative consistant à matérialiser la contrainte d'inclusion est à éviter.
=>
En conclusion, si on utilise un SGBD basé sur Tutorial D, ou si l’on utilise un SGBD utilisant SQL et fournissant l’instruction CREATE ASSERTION, on peut mettre en œuvre le MLD orienté javass-CinePhil ou le MLD orienté JPhi33. Si l’on utilise un SGBD SQL et si on se sert de triggers, on pourra préférer la solution javass-CinePhil.
Partager