オプション2は、リレーショナルデータベースには適していません。これは多形関係と呼ばれ(@Daniel Vassalloが言及しているように)、関係の基本的な定義を破ります。
たとえば、2つの異なる行に1234のResourceIdがあるとします。これらは同じリソースを表していますか?CommentTypeIdがこれらの2つの行で同じであるかどうかによって異なります。これは、リレーションの型の概念に違反します。詳細については、SQLおよびCJ日付による関係理論を参照してください。
壊れた設計であるというもう1つの手がかりは、ResourceIdの外部キー制約を宣言できないことです。これは、複数のテーブルのいずれかを指す可能性があるためです。トリガーなどを使用して参照整合性を適用しようとすると、新しいタイプのコメント可能なリソースを追加するたびにトリガーを書き直すことになります。
@mdmaが簡単に言及している(しかし無視している)解決策でこれを解決します:
CREATE TABLE Commentable (
ResourceId INT NOT NULL IDENTITY,
ResourceType INT NOT NULL,
PRIMARY KEY (ResourceId, ResourceType)
);
CREATE TABLE Documents (
ResourceId INT NOT NULL,
ResourceType INT NOT NULL CHECK (ResourceType = 1),
FOREIGN KEY (ResourceId, ResourceType) REFERENCES Commentable
);
CREATE TABLE Projects (
ResourceId INT NOT NULL,
ResourceType INT NOT NULL CHECK (ResourceType = 2),
FOREIGN KEY (ResourceId, ResourceType) REFERENCES Commentable
);
現在、各リソースタイプには独自のテーブルがありますが、シリアル主キーはCommentableによって一意に割り当てられます。特定の主キー値は、1つのリソースタイプでのみ使用できます。
CREATE TABLE Comments (
CommentId INT IDENTITY PRIMARY KEY,
ResourceId INT NOT NULL,
ResourceType INT NOT NULL,
FOREIGN KEY (ResourceId, ResourceType) REFERENCES Commentable
);
現在、コメントはコメント可能なリソースを参照しており、参照整合性が適用されています。特定のコメントは、1つのリソースタイプのみを参照できます。異常や競合するリソースIDの可能性はありません。
プレゼンテーション「SQLの実用的なオブジェクト指向モデル」と私の本「SQLアンチパターン」で、ポリモーフィックな関連付けについて詳しく説明します。