67

アプリに次のcomments表があります。

comments
--------
id           INT
foreign_id   INT
model        TEXT
comment_text TEXT
...

このテーブルのアイデアは、アプリのさまざまな部分のコメントを保存することです-ブログ投稿のコメントを保存できます。

1|34|blogpost|lorem ipsum...

ユーザー画像:

2|12|picture|lorem ipsum...

等々。

今、そのようなデータに FOREIGN KEY 制約を強制する方法はありますか?

つまり、コメント テーブルに次のようなものがあります。

FOREIGN KEY (`foreign_id`) REFERENCES blogposts (`id`)
-- but only when model='blogpost'
4

2 に答える 2

120

Polymorphic Associationsと呼ばれる設計を行おうとしています。つまり、外部キーは、複数の関連テーブルのいずれかの行を参照できます。

ただし、外部キー制約は正確に 1 つのテーブルを参照する必要があります。テーブルの別の列の値に応じて異なるテーブルを参照する外部キーを宣言することはできませんComments。これは、リレーショナル データベース設計のいくつかのルールに違反します。

より良い解決策は、コメントによって参照される一種の「スーパーテーブル」を作成することです。

CREATE TABLE Commentable (
  id SERIAL PRIMARY KEY
);

CREATE TABLE Comments (
  comment_id SERIAL PRIMARY KEY,
  foreign_id INT NOT NULL,
  ...
  FOREIGN KEY (foreign_id) REFERENCES Commentable(id)
);

各コンテンツ タイプは、このスーパーテーブルのサブタイプと見なされます。これは、インターフェイスのオブジェクト指向の概念に似ています。

CREATE TABLE BlogPosts (
  blogpost_id INT PRIMARY KEY, -- notice this is not auto-generated
  ...
  FOREIGN KEY (blogpost_id) REFERENCES Commentable(id)
);

CREATE TABLE UserPictures (
  userpicture_id INT PRIMARY KEY, -- notice this is not auto-generated
  ...
  FOREIGN KEY (userpicture_id) REFERENCES Commentable(id)
);

BlogPostsまたはに行を挿入する前にUserPictures、 に新しい行を挿入してCommentable、新しい疑似キー ID を生成する必要があります。次に、コンテンツをそれぞれのサブタイプ テーブルに挿入するときに、その生成された ID を使用できます。

それがすべて完了したら、参照整合性制約に依存できます。

于 2010-01-04T23:23:40.500 に答える