Bonsoir,
Envoyé par
Monstros Velu
je pense que cette modélisation ne respecte pas la règle 2 de Codd
Règle 2
Garantie d'accès :
Toutes les données doivent être accessibles sans ambiguïté. Cette règle est essentiellement un ajustement de la condition fondamentale pour des clefs primaires. Elle indique que chaque valeur scalaire individuelle dans la base de données doit être logiquement accessible en indiquant le nom de la table contenante, le nom de la colonne contenante et la valeur principale primaire de la rangée contenante.
Votre définition de la règle n’est pas formellement celle de Codd, laquelle est en fait la suivante (Is your DBMS really relational? ComputerWorld, October 14, 1985) :
Each and every datum (atomic value) in a relational database is guaranteed to be logically accessible by resorting to a combination of R-table name, primary key value, and column name.
CinePhil propose les tables ;
te_option_opt (opt_id, opt_nom...)
tj_opt_compatible_opt_oco (oco_id_option_1, oco_id_option_2)
Ces tables sont évidemment structurellement conformes au modèle relationnel de données de Codd.
Une variante de la belle ouvrage de CinePhil ; pour simplifier et pour mon confort visuel, je laisse tomber la table te_option_opt et renomme tj_opt_compatible_opt_oco en PAIRE. Passons à SQL :
CREATE TABLE PAIRE
(
optionCode_A VARCHAR(4) NOT NULL
, optionCode_B VARCHAR(4) NOT NULL
, CONSTRAINT Paire_PK PRIMARY KEY (optionCode_A, optionCode_B)
) ;
Comme la clé primaire {optionCode_A, optionCode_B} est un ensemble au sens de la théorie des ensembles, à laquelle Codd tient particulièrement, les valeurs <'a', 'b'> et <'b', 'a'> doublonnent, donc on empêchera cela au moyen d’une contrainte conforme à la norme SQL :
CREATE ASSERTION PAIRE_UNIQUE
CHECK
(NOT EXISTS
SELECT a.optionCode_A, a.optionCode_B
FROM PAIRE as a
JOIN PAIRE as b
ON a.optionCode_A = b.optionCode_B
AND a.optionCode_B = b.optionCode_A)
;
Si le SGBD ne connaît pas l’instruction CREATE ASSERTION, on passera par un trigger (cf. CinePhil).
Créons par exemple les paires
<'a', 'b'>
<'a', 'd'>
<'c', 'e'>
<'d', 'f'>
Code SQL :
insert into PAIRE values ('a', 'b') ;
insert into PAIRE values ('a', 'd') ;
insert into PAIRE values ('c', 'e') ;
insert into PAIRE values ('d', 'f') ;
Pour produire une table contenant l’ensemble des paires, <'a', 'b'>, <'b', 'a'>, etc. :
CREATE TABLE RESULTAT
(
optionCode_A VARCHAR(4) NOT NULL
, optionCode_B VARCHAR(4) NOT NULL
, CONSTRAINT RESULTAT_PK PRIMARY KEY (optionCode_A, optionCode_B)
) ;
go
WITH t1 as
(SELECT DISTINCT x.optionCode_A, y.optionCode_B
FROM PAIRE as x JOIN PAIRE as y ON x.optionCode_A < y.optionCode_B)
,
t2 as
(SELECT DISTINCT x.optionCode_A, x.optionCode_B
FROM t1 as x JOIN PAIRE as y
ON x.optionCode_A = y.optionCode_A
AND x.optionCode_B = y.optionCode_B)
,
t3 as
(SELECT DISTINCT x.optionCode_B, y.optionCode_A
FROM PAIRE as x JOIN PAIRE as y
ON x.optionCode_B > y.optionCode_A)
,
t4 as
(SELECT DISTINCT x.optionCode_B, x.optionCode_A
FROM t3 as x JOIN PAIRE as y
ON x.optionCode_A = y.optionCode_A
AND x.optionCode_B = y.optionCode_B)
INSERT INTO RESULTAT
SELECT * FROM t2 UNION SELECT * FROM t4
go
SELECT * FROM RESULTAT ;
=>
optionCode_A optionCode_B
a b
a d
b a
c e
d a
d f
e c
f d
Pas de difficulté particulière pour sélectionner par exemple la paire <'a', 'b'> et/ou sa soeur <'b', 'a'>.
Envoyé par
Monstros Velu
Je vois bien que "ça marche". Et je connais pas mal de cas de dénormalisation où "ça marche". Mais je cherche une solution normalisée.
Les tables PAIRE et RESULTAT sont en 6NF.
Envoyé par
CinePhil
Comme la clé primaire de cette table associative est composée de deux colonnes, la clé primaire est le couple des deux options compatibles.
Dans ces conditions la table est en 6NF.
■
Pour tout savoir sur la normalisation :
Partager