Lấy cảm hứng từ một câu hỏi mô hình hóa Django: Mô hình hóa cơ sở dữ liệu với nhiều mối quan hệ nhiều-nhiều trong Django . Thiết kế db là một cái gì đó như:
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)
) ;
và vấn đề là làm thế nào để xác định BookAspectRating
bảng và để thực thi tính toàn vẹn tham chiếu, do đó người ta không thể thêm xếp hạng cho một (Book, Aspect)
kết hợp không hợp lệ.
AFAIK, các CHECK
ràng buộc phức tạp (hoặc ASSERTIONS
) liên quan đến các truy vấn con và nhiều hơn một bảng, có thể giải quyết điều này, không có sẵn trong bất kỳ DBMS nào.
Một ý tưởng khác là sử dụng (mã giả) một khung nhìn:
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) ;
và một bảng có Khóa ngoài cho Chế độ xem ở trên:
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)
) ;
Ba câu hỏi:
Có DBMS cho phép một (có thể được vật chất hóa)
VIEW
với mộtPRIMARY KEY
?Có DBMS cho phép một
FOREIGN KEY
màREFERENCES
mộtVIEW
(và không chỉ là một cơ sởTABLE
)?Vấn đề toàn vẹn này có thể được giải quyết bằng cách khác - với các tính năng DBMS có sẵn?
Làm rõ:
Vì có lẽ không có giải pháp thỏa mãn 100% - và câu hỏi Django thậm chí không phải là của tôi! - Tôi quan tâm nhiều hơn đến một chiến lược chung về khả năng tấn công vào vấn đề, chứ không phải là một giải pháp chi tiết. Vì vậy, một câu trả lời như "trong DBMS-X điều này có thể được thực hiện với các kích hoạt trên bảng A" là hoàn toàn chấp nhận được.