1つのテーブルと他のいくつかのテーブルの間の最適な関係。それぞれは最初のテーブルのn個のデータセットに依存しますか? [複製]
-
11-07-2019 - |
質問
コンテンツタイプのさまざまなセットのコメントを保存するテーブルが1つあります。これらは他のテーブル(ニュース、記事、ユーザー)に保存されます。 これらのテーブルを接続する最良の方法は何でしょうか? 以前のプロジェクトでは、コンテンツの種類ごとに2番目のテーブルを使用しました。コメントテーブルのIDにマップされた特定のコンテンツのIDを保持していました。そのため、コメントごとにコメントエントリと「コネクタ」エントリがありました。 別の方法として、あらゆる種類のコンテンツに個別のコメントテーブルを使用する方法があります。 最後に、両方の方法に冗長性の欠陥が含まれています。
では、どちらを使用する必要がありますか、または1つのソリューションがありますか?
解決
テーブルを設計するいくつかの明白な方法があります:
1)マスターコメントテーブル、および各コメントをArticles、News、およびUsersテーブルに接続する中間テーブルを作成できます。
Comments -------- ID News NewsComments ---- ------------ ID NewsID CommentID Articles ArticleComments -------- --------------- ID ArticleID CommentID Users UserComments ----- ------------ ID UserID CommentID
この利点は、各機能のコメントを比較的簡単にクエリできることです。ただし、このスタイルには参照整合性の問題があります。単一のコメントを複数のコメント、ニュース記事、ユーザーに結び付けることができます。さらに、あまりスケーラブルではありません。RSSフィード、お気に入りのリンク、ユーザーステータスなどにコメントを追加すると、これらすべてのタイプの中間テーブルが作成されます。
2)別のアプローチは、わずかに非正規化されたバージョンです:
Comments -------- ID TableName PkID (Connects the primary key in other tables) News ---- ID Articles -------- ID Users ----- ID
これは機能し、新しい機能を追加するたびに簡単にスケーリングできますが、Comments.RefIDフィールドを複数のテーブルに同時にキー入力できないため、参照整合性が失われます。
3)最後のオプションでは、多くの冗長な「コメント」が必要です。各機能の表。
News NewsComments ---- ------------ ID NewsID Articles ArticleComments -------- --------------- ID ArticleID Users UserComments ----- ------------ ID UserID
このスタイルの利点は、参照整合性の保持であり、スキーマを見ている人なら誰でも容易に理解できることです。欠点は、同一のスキーマを持つ過剰な数のテーブルです。
他のヒント
各コンテンツテーブルに個別のコメントテーブルがあるため、外部キーの関係を利用して、元のコンテンツが変更/削除されたときに更新/削除を自動的に管理できます。したがって、ニュースと記事のテーブルがある場合、news_commentsとarticle_commentsのテーブルがあります。これらにはそれぞれ、content_idフィールドとuser_idフィールドがあります。 content_idフィールドはコンテンツテーブルを参照し、user_idフィールドはユーザーテーブルを参照します。適切なコンテンツとコメントテーブルとユーザーと各コメントテーブルの間に外部キー関係を設定し、更新/削除時に変更を反映させます。 idフィールドにインデックスを設定して、フィールド間でインデックス結合を行うこともできます。
単一のコメントテーブルがある場合、FKを他の1つのテーブルにのみ関連付けることができるため、DBに処理させるのではなく、コードでリレーションシップを手動で管理する必要があります。
あなたの質問は
に似ているようですさらに別の方法はこれかもしれません:
Comments
-------
ID
NewsID
ArticleID
UserID
各行について、非ゼロになるのは1つだけです。これにより、中間テーブルよりもクエリが簡単になります。
ただし、データの整合性の観点からは、ContentsテーブルごとにCommentsテーブルを1つ持つ方が賢明です。