3

Book と Person があるとします。人は多くの本を書くことができ、本は多くの人が書くことができます。人は多くの本を読み、本は多くの人に読まれてきました。

Person               Book
------               -----
personId             bookId

2 つの関係テーブルを使用できます。

has_read             has_authored
--------             ------------
personId, bookId     personId, bookId

または 1 つ:

person_book_relation
--------------------
personId, bookId, relationType ("read", "authored")

もう 1 つの例は、Actor と Event の間のある種のサブスクライバー/パブリッシャーの関係です。

どちらを選択するかのガイドラインはありますか?

より多くの種類の関係がある場合はどうなるでしょうか。それはあなたの解決策を変えますか?

チームには、役割を持つ多くの人がいます。人は多くのチームに所属できます。(ただの作り話です)

Team_Person_relation
--------------------
TeamId, PersonId, Role ('Defender', 'Attacker', 'Goalkeeper', 'Midfielder'... etc)

別々のテーブルを使用する場合、これは少なくとも 4 つのテーブルになります。しかし、「読む・書く」という関係よりも、チームの役割がお互いにつながっているような気がしますか?

4

2 に答える 2

3

リレーションシップのタイプが実際にテーブルの列に影響を与える状況に遭遇しない限り、2 番目のタイプのテーブルを使用します。

たとえば、本の例では、著者が出版社に送った日付を持っている可能性があります。これは、すべての情報を 1 つのテーブルに保持するという考えを無効にします。その情報は読者には適用されないからです。

同様に、「セーブされたゴール」は、ゴールキーパーにのみ適用されます。

正直なところ、「抽出しようとしている情報によって異なります」というやや陳腐な応答があると思いますが、一般的に、「これはテーブル x とテーブル y の関係を説明するテーブルである」ことをより明確に示すことができます。データベースの保守が容易になります。

于 2012-08-30T22:20:41.903 に答える
1

どちらのソリューションも正しいため、データベース作成者としてのあなた次第です。考慮すべきことは、ほとんどの場合、データが将来どのように使用されるか (または、少なくとも現在どのように使用されると予測されているか) です。いくつかの例:

  1. 1 つのテーブルにあまりにも多くの多対多のリレーションを強制する場合、そのうちの 1 つを操作するときに「そこに他のリレーションがある」ことを常に覚えておく必要があります。たとえば、本を執筆していないすべての人を表示したい場合は、「読み取り」関係をフィルタリングする方法で左結合クエリを作成する必要があります。クエリがより複雑になり、より多くのテーブルとより多くの外部結合が含まれるようになると、不要な結果が得られやすくなります。

  2. チームの役割の例は、役割のリストが将来変更される可能性があることを示唆しています。したがって、この役割を関係の列に保持する方が良い解決策です。また、ここでの関係とは「チームの一員であること」を指し、このメンバーの役割はこのメンバーのみの財産です。

  3. 多対多の関係に追加情報を保存したい場合 (作成日や読者が本をどれだけ気に入ったかなど)、別のテーブルが提案されます。それ以外の場合は、考えられるすべての関係を処理するために多くの疎列が使用されます。 .

  4. 最後になりましたが、パフォーマンスです。テーブルに「関連のない」データが多すぎると、インデックスを効果的に設計して使用することが難しい場合があります。

于 2012-08-30T22:27:20.103 に答える