Djangoモデリングの質問に触発されました:Djangoの複数の多対多リレーションを使用したデータベースモデリング。db-designは次のようなものです。
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
)は、DBMSでは使用できません。
別のアイデアは、ビューを使用(擬似コード)することです:
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)
) ;
3つの質問:
(おそらくマテリアライズド)
VIEW
を許可するDBMSはありPRIMARY KEY
ますか?許可DBMSがある
FOREIGN KEY
こと(とベースだけではなく)?REFERENCES
VIEW
TABLE
そうでなければ、利用可能なDBMS機能を使用して、この整合性の問題を解決できますか?
明確化:
おそらく100%満足できるソリューションはないので、Djangoの質問は私のものでもありません!-詳細な解決策ではなく、問題に対する攻撃の一般的な戦略に興味があります。したがって、「DBMS-Xでは、これはテーブルAのトリガーを使用して実行できます」などの回答は完全に受け入れられます。