2

4 つの異なるテーブルのいずれかを参照できる可能性がある uniqueidentifier を持つ列があります。私はこれが 2 つの方法で行われるのを見てきましたが、どちらも悪い習慣のようです。

まず、特定のテーブルへの外部キーとして明示的に宣言されていない単一の ObjectID 列を見てきました。次に、必要な一意の識別子を押し込むだけです。これは、必要な 4 つのテーブルの一部ではないテーブルから ID を挿入できる可能性があることを意味します。

次に、データは 4 つの異なるテーブルから取得できるため、4 つの異なる外部キーを作成する人も見てきました。その際、システムは、NULL 以外の値を持つ ONE AND ONLY ONE 列に依存します。

これを行うためのより良いアプローチは何ですか? たとえば、私のテーブルのレコードは、潜在的に病院 (ID)、診療所 (ID)、学校 (ID)、または大学 (ID) を参照する可能性がありますが、これらのテーブルのみです。

ありがとう!

4

3 に答える 3

8

タイプ/サブタイプのデータモデルを検討することをお勧めします。これは、オブジェクト指向プログラミングのクラス/サブクラスに非常によく似ていますが、実装がはるかに面倒であり、RDBMS(私が知っている)はそれらをネイティブにサポートしていません。一般的な考え方は次のとおりです。

  • タイプ(建物)を定義し、そのテーブルを作成して、主キーを指定します
  • 2つ以上のサブタイプ(ここでは、病院、診療所、学校、大学)を定義し、それぞれにテーブルを作成し、主キーを作成します。ただし、主キーは、Buildingテーブルを参照する外部キーでもあります。
  • これで、「ObjectType」列が1つあるテーブルを、外部キーを使用してBuildingテーブルに構築できます。あなたはそれがどんな種類の建物であるかを決定するためにいくつかのテーブルを結合しなければならないでしょう、しかしあなたはとにかくそれをしなければならないでしょう。それ、または冗長データを保存します。

このモデルの問題に気づきましたよね?Buildingが2つ以上のサブタイプテーブルにエントリを持たないようにするにはどうすればよいですか?あなたが尋ねてくれてうれしい:

  1. 建物のタイプを示す{H、C、S、U}の許可された値を持つchar(1)などの列をBuildingに追加します。
  2. BuildingID+BuildingTypeに一意の制約を作成します
  3. サブテーブルにBulidingType列があります。値(Hospitalsテーブルの場合はHなど)にのみ設定できるように、チェック制約を設定します。理論的には、これは計算列である可能性があります。実際には、次の手順のため、これは機能しません。
  4. 両方の列を使用してテーブルを関連付ける外部キーを作成します

出来上がり:タイプHで設定されたBUILDING行がある場合、そのビルディングを参照するようにSCHOOLテーブル(タイプS)のエントリを設定することはできません。

実装するのは難しいと言ったことを思い出してください。

実際、大きな問題は次のとおりです。これは行う価値がありますか?4つ(または時間の経過とともに)の建物タイプをタイプ/サブタイプとして実装することが理にかなっている場合(さらに正規化の利点:建物固有の属性がサブテーブルに格納されている、すべての建物に共通のアドレスおよびその他の属性用の1つの場所)、構築して維持するために余分な努力をする価値があるかもしれません。そうでない場合は、正方に戻ります。これは、現代の平均的なRDBMSでは実装が難しい論理モデルです。

于 2012-11-09T17:59:20.850 に答える
5

概念レベルから始めましょう。病院、診療所、学校、大学を主題エンティティのクラスと考える場合、それらすべてを一般化するスーパークラスはありますか?おそらくあります。私はあなたと同じようにあなたの主題を理解していないので、それが何であるかをあなたに話そうとはしません。しかし、私はそれらすべてを「機関」と呼ぶことができるかのように進め、4つのそれぞれを機関のサブクラスとして扱うつもりです。

他のレスポンダーが指摘しているように、クラス/サブクラスの拡張と継承は、ほとんどのリレーショナルデータベースシステムに組み込まれていません。しかし、適切な流行語を知っていれば、多くの支援があります。以下は、データベース用語で流行語を教えることを目的としています。登場する流行語の概要は次のとおりです。「ERGeneralization」、「ER Specialization」、「Single Table Inheritance」、「Class Table Inheritance」、「SharedPrimaryKey」。

概念レベルにとどまると、ERモデリングは概念レベルでデータを理解するための良い方法です。ERモデリングには、「ER Generalization」という概念と、先ほど「スーパークラス/サブクラス」として提示した思考プロセスに対応する「ERSpecialization」という概念があります。ERスペシャライゼーションでは、サブクラスの図を作成する方法については説明していますが、サブクラスの実装方法については説明していません。

次に、概念レベルから論理レベルに移動します。リレーション、または必要に応じてSQLテーブルの観点からデータを表現します。サブクラスを実装するためのテクニックがいくつかあります。1つは「単一テーブル継承」と呼ばれます。もう1つは、「クラステーブル継承」と呼ばれます。クラステーブル継承に関連して、「共有主キー」という名前の別の手法があります。

クラステーブル継承の場合は、最初に「Institutions」というテーブルを設計します。このテーブルには、Idフィールド、nameフィールド、および4種類の機関に関係するすべてのフィールドが含まれます。たとえば、郵送先住所フィールドなど。繰り返しになりますが、あなたは私よりもデータをよく理解しており、既存の4つのテーブルすべてにあるフィールドを見つけることができます。通常の方法でidフィールドに入力します。

次に、「病院」、「診療所」、「学校」、「大学」という4つのテーブルを設計します。これらには、idフィールドに加えて、その種類の機関にのみ関連するすべてのデータフィールドが含まれます。たとえば、病院には「病床数」があるかもしれません。繰り返しになりますが、あなたは私よりもあなたのデータをよく理解しており、Institutionsテーブルに含まれていなかった既存のテーブルのフィールドからこれらを理解することができます。

ここで「共有主キー」が登場します。「機関」に新しいエントリが作成されると、4つの特殊なサブクラステーブルの1つに新しい並列エントリを作成する必要があります。ただし、idフィールドに入力するために、ある種の自動番号機能は使用しません。代わりに、「Institutions」テーブルのidフィールドのコピーをサブクラステーブルのidフィールドに配置します。

これは少し作業ですが、メリットは努力する価値があります。共有主キーは、サブクラスエントリとスーパークラスエントリ間の関係の1対1の性質を強制します。これにより、スーパークラスデータとサブクラスデータの結合が簡単、簡単、高速になります。これにより、特定の機関がどのサブクラスに属しているかを示す特別なフィールドが不要になります。

そして、あなたの場合、それはあなたの元の質問に対する便利な答えを提供します。あなたが最初に尋ねていた外部キーは、今では常に機関テーブルへの外部キーです。また、shared-primary-keyの魔法により、外部キーは適切なサブクラステーブルのエントリも参照し、余分な作業は必要ありません。

便宜上、機関データを4つのサブクラステーブルのそれぞれと組み合わせる4つのビューを作成できます。

「ERスペシャライゼーション」、「クラステーブル継承」、「共有主キー」、そしておそらく「単一テーブル継承」をWebで、そしてここではSOで検索してください。ここSOには、これらの概念または手法のほとんどのタグがあります。

于 2012-11-09T20:33:56.553 に答える
0

テーブルにトリガーを設定し、そこで参照整合性を適用できます。この要件を実装するための、すぐに使用できる優れた機能はないと思います。

于 2012-11-09T17:37:08.203 に答える