3

かなり奇妙な問題/質問と呼ばれるものがあります。

他の多くの異なるテーブルの 1 つ (そして 1 つだけ) を参照するテーブルがあるとします。どうすれば最善の方法でそれを行うことができますか?? 大多数のデータベース (MS SQL、MySQL、PostgreSQL など) で機能するソリューションを探しています。私の見方では、いくつかの異なる解決策があります(他の解決策よりも優れていますか?):

  1. 可能な参照ごとに 1 つの列を用意します。これらの列のうち、特定の行の値を含むことができるのは 1 つのみで、その他はすべて null です。厳密な外部キーを許可しますが、「多数」(参照される可能性のあるテーブル) の数が大きくなると面倒になります
  2. 2 つの列の関係があります。つまり、1 つの列は参照されるテーブルを「説明」し、もう 1 つの列はインスタンス (そのテーブルの行) を参照します。「多くの」(参照されるテーブル)の数が増えると簡単に拡張できますが、単純な方法で単一のクエリ検索を実行することはできません(可能なすべてのテーブルを左結合するか、それぞれ1つのテーブルに結合する複数のクエリを結合します)
  3. ??

わかる?この場合のベスト プラクティス (もしあれば) は何ですか? どのテーブルが参照されているかを実際に知らなくても、参照されたエンティティからデータをクエリできるようにしたいのです。

どうしますか?

4

2 に答える 2

2

これらの方法はどちらもリレーショナル データベースに適しているため、その点について心配する必要はありません。どちらもかなり面倒なクエリになります。最初の方法の場合:

select . . .
from t left outer join
     ref1
     on t.ref1id = ref1.ref1id left outer join
     ref2
     on t.ref2id = ref2.ref2id . . .

2 番目の方法の場合:

select . . .
from t left outer join
     ref1
     on t.anyid = ref1.ref1id and anytype = 'ref1' left outer join
     ref2
     on t.anyid = ref2.ref2id and anytype = 'ref2' . . .

したがって、クエリの単純さの観点からは、一方と他方に大きな利点があるとは思いません。2 番目のバージョンには小さな欠点があります。クエリを作成するときに、結合の名前を覚えておく必要があります。これは時間の経過とともに失われる可能性があります。(もちろん、制約またはトリガーを使用して、固定された一連の値のみが列に含まれるようにすることができます。)

クエリ パフォーマンスの観点からは、最初のバージョンに大きな利点があります。列を外部キーとして識別できデータベースはその列に関する統計を保持できます。これは、たとえば、データベースが適切な結合アルゴリズムを選択するのに役立ちます。2 番目の方法では、この可能性はすぐには提供されません。

データ サイズの観点から、最初のバージョンでは、可能な値ごとに ID を格納する必要があります。2番目はよりコンパクトです。保守性の観点からすると、1 つ目は新しいオブジェクト タイプを追加するのが困難です。2番目は簡単です。

互いに類似したもののセットがある場合は、それらを 1 つのテーブルに格納することを検討できます。適切ではない属性は NULL にすることができます。物事のさまざまなフレーバーのビューを作成することもできます。1 つのテーブルはオプションの場合とそうでない場合があります。

つまり、この質問に正解はありません。データベース設計の多くの側面と同様に、データがどのように使用されるかによって異なります。他の情報がなければ、おそらく最初にデータを単一のテーブルに強制しようとします。それが妥当でない場合は、一方でテーブルの数を数えることができる場合は最初のオプションを使用し、それ以上のテーブルがある場合は 2 番目のオプションを使用します。

于 2013-04-22T21:43:19.777 に答える
1

1)

これは、静的テーブルの数が少ない場合に有効です。将来、多数の新しいテーブルを追加する必要があると予想される場合は、以下の3)を参照してください...

2)

お願い、それはやめて。データの整合性を維持するための最も重要なメカニズムの 1 つである、宣言型の FOREIGN KEY を失うことになります。

3)

継承を使用します。この投稿の詳細:

以下もご覧ください。

于 2013-04-22T21:47:33.970 に答える