Inspiré d'une question de modélisation Django: Modélisation de base de données avec plusieurs relations plusieurs-à-plusieurs dans Django . Le db-design est quelque chose comme:
CREATE TABLE Book
( BookID INT NOT NULL
, BookTitle VARCHAR(200) NOT NULL
, PRIMARY KEY (BookID)
) ;
CREATE TABLE Tag
( TagID INT NOT NULL
, TagName VARCHAR(50) NOT NULL
, PRIMARY KEY (TagID)
) ;
CREATE TABLE BookTag
( BookID INT NOT NULL
, TagID INT NOT NULL
, PRIMARY KEY (BookID, TagID)
, FOREIGN KEY (BookID) REFERENCES Book (BookID)
, FOREIGN KEY (TagID) REFERENCES Tag (TagID)
) ;
CREATE TABLE Aspect
( AspectID INT NOT NULL
, AspectName VARCHAR(50) NOT NULL
, PRIMARY KEY (AspectID)
) ;
CREATE TABLE TagAspect
( TagID INT NOT NULL
, AspectID INT NOT NULL
, PRIMARY KEY (TagID, AspectID)
, FOREIGN KEY (TagID) REFERENCES Tag (TagID)
, FOREIGN KEY (AspectID) REFERENCES Aspect (AspectID)
) ;
et le problème est de savoir comment définir la BookAspectRating
table et appliquer l'intégrité référentielle, de sorte que l'on ne peut pas ajouter de note pour une (Book, Aspect)
combinaison non valide.
AFAIK, les CHECK
contraintes complexes (ou ASSERTIONS
) qui impliquent des sous-requêtes et plus d'une table, qui pourraient éventuellement résoudre ce problème, ne sont disponibles dans aucun SGBD.
Une autre idée est d'utiliser (pseudocode) une vue:
CREATE VIEW BookAspect_view
AS
SELECT DISTINCT
bt.BookId
, ta.AspectId
FROM
BookTag AS bt
JOIN
Tag AS t ON t.TagID = bt.TagID
JOIN
TagAspect AS ta ON ta.TagID = bt.TagID
WITH PRIMARY KEY (BookId, AspectId) ;
et une table qui a une clé étrangère vers la vue ci-dessus:
CREATE TABLE BookAspectRating
( BookID INT NOT NULL
, AspectID INT NOT NULL
, PersonID INT NOT NULL
, Rating INT NOT NULL
, PRIMARY KEY (BookID, AspectID, PersonID)
, FOREIGN KEY (PersonID) REFERENCES Person (PersonID)
, FOREIGN KEY (BookID, AspectID)
REFERENCES BookAspect_view (BookID, AspectID)
) ;
Trois questions:
Existe-t-il des SGBD qui permettent un (éventuellement matérialisé)
VIEW
avec unPRIMARY KEY
?Y at - il un SGBD qui permettent un
FOREIGN KEY
queREFERENCES
unVIEW
(et non seulement une baseTABLE
)?Ce problème d'intégrité pourrait-il être résolu autrement - avec les fonctionnalités de SGBD disponibles?
Clarification:
Puisqu'il n'y a probablement pas de solution 100% satisfaisante - et la question Django n'est même pas la mienne! - Je suis plus intéressé par une stratégie générale d'attaque possible du problème, pas par une solution détaillée. Ainsi, une réponse comme «dans SGBD-X, cela peut être fait avec des déclencheurs sur la table A» est parfaitement acceptable.