余分なテーブルや不特定の外部キーはありますか?
-
09-06-2019 - |
質問
システムにはいくつかのタイプのオブジェクトがあり、それぞれがデータベース内に独自のテーブルを持っています。ユーザーはそれらのどれに対してもコメントできる必要があります。コメントテーブルはどのように設計しますか?いくつかの選択肢が考えられます。
- オブジェクト タイプ (ObjectAID、ObjectBID など) ごとに FK 列を含む 1 つのコメント テーブル
- 複数のコメント テーブル (オブジェクト タイプごとに 1 つ) (ObjectAComments、ObjectBComments など)
- タイプ (「ObjectA」) を示す別の列を持つ 1 つの汎用 FK (ParentObjectID)
どちらを選びますか?私が考えていないもっと良い方法はありますか?
解決
@パームジー
ほぼそうなのですが、私が最も頻繁に見たパターンのバリエーションは削除されます。 ObjectAID
他。 ParentID
PKとFKの両方になる Parents
. 。これにより、次のような結果が得られます。
Parents
ParentID
ObjectA
ParentID
(FKとPK)ColumnFromA NOT NULL
ObjectB
ParentID
(FKとPK)ColumnFromB NOT NULL
Comments
同じままだろう。次に、誤って問題が発生しないように ID の生成を制限するだけです。 ObjectA
列と ObjectB
両方が同じを指している行 Parents
行;これを行う最も簡単な方法は、使用しているものと同じシーケンス (または何でも) を使用することです。 Parents
のために ObjectA
そして ObjectB
.
次のようなスキーマも多数見られます。
Parents
ID
SubclassDiscriminator
ColumnFromA (nullable)
ColumnFromB (nullable)
そして Comments
は変わらないでしょう。しかし現在では、トリガーを作成するか、別のレイヤーで実行することなく、すべてのビジネス制約 (サブクラスのプロパティはすべて NULL 可能) を強制することはできません。
他のヒント
コメント可能な (適切な言葉がありませんが) テーブルが標準の継承モデリング パターンの 1 つに従うようにスキーマを設計することは可能でしょうか?その場合は、コメント テーブルの FK が共通の親テーブルを指すようにすることができます。
@ハンク・ゲイ
したがって、次のようなものです:
- オブジェクトA
- オブジェクトAID
- 親ID
- オブジェクトB
- オブジェクトBID
- 親ID
- コメント
- コメントID
- 親ID
- 両親
- 親ID
厳密に 1 つのテーブルを指さない汎用外部キーには注意してください。型の where 条件を分割し、複数の異なるテーブルを指す必要がある場合、クエリのパフォーマンスが大幅に低下します。型が数個しかなく、型の数が増えない場合は、異なるテーブルに個別の null 許容外部キーを用意しても問題ありませんが、より多くの型を使用する場合は、別のデータ モデルを考え出す方が良いでしょう (例: @palmsey の提案)。
私がやりたいことの 1 つは、汎用/共通テーブルをすべての個別テーブルにリンクする個別のテーブルを用意することです。
したがって、オブジェクト Foo と Bar、および Foo & Bar のコメントの場合、次のようになります。
- フー
- フー ID (PK)
- バー
- バーID (PK)
- コメント
- コメントID(PK)
- コメントテキスト
- Fooコメント
- フー ID (PK FK)
- コメントID (PK FK)
- バーコメント
- バーID (PK FK)
- コメントID (PK FK)
この構造は次のとおりです。
- 共通のコメントテーブルを作成できます
- テーブル継承のある DB は必要ありません
- Foo テーブルと Bar テーブルをコメント関連の情報で汚染しない
- コメントを添付できます 複数 オブジェクト (望ましい場合もあります)
- 必要に応じて、Foo/Bar と Comment のジャンクションに他のプロパティをアタッチできます。
- 標準との関係は引き続き維持されます (つまり:高速、シンプル、信頼性の高い) 外部キー