Вдохновленный вопросом моделирования Django: Моделирование базы данных с множественными отношениями «многие ко многим» в Django . ДБ-дизайн это что-то вроде:
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)
) ;
и вопрос заключается в том, как определить BookAspectRating
таблицу и обеспечить ссылочную целостность, поэтому нельзя добавить оценку для (Book, Aspect)
недопустимой комбинации.
AFAIK, сложные CHECK
ограничения (или ASSERTIONS
), которые включают подзапросы и более одной таблицы, которые могли бы решить эту проблему, недоступны ни в одной СУБД.
Другая идея - использовать (псевдокод) представление:
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) ;
и таблица, которая имеет внешний ключ для вышеуказанного представления:
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)
) ;
Три вопроса:
Существуют ли СУБД, допускающие (возможно, материализованные)
VIEW
сPRIMARY KEY
?Существуют ли СУБД , которые позволяют ,
FOREIGN KEY
чтоREFERENCES
вVIEW
(а не только базыTABLE
)?Может ли эта проблема целостности быть решена иначе - с помощью доступных функций СУБД?
Разъяснение:
Поскольку, вероятно, нет 100% удовлетворительного решения - и вопрос Джанго даже не мой! - Меня больше интересует общая стратегия возможной атаки на проблему, а не детальное решение. Таким образом, ответ типа «в СУБД-Х это можно сделать с помощью триггеров в таблице А» вполне приемлем.