web-dev-qa-db-ja.com

1つの列への複数の外部キー

私は、2つの非常に異なるタイプの顧客が存在する顧客/注文システムのデータベースを定義しています。それらは非常に異なるため、単一の顧客テーブルを持つことは非常に醜いでしょう(1つのタイプには意味がないため、null列でいっぱいになります)。

ただし、注文は同じ形式です。 Orderテーブルに両方の顧客タイプへの外部キーを持つCustomerId列を含めることは可能ですか? SQL Serverでセットアップしましたが、問題はありません作成関係ですが、まだデータを挿入しようとはしていません。

また、ORMとしてnHibernateを使用することを計画していますが、このような関係を行うことで問題が発生する可能性はありますか?

24
Aaron Powell

いいえ、2つの異なるテーブルへの外部キーとして単一のフィールドを持つことはできません。キーを探す場所をどのように伝えますか?

少なくとも、ユーザーの種類を示すフィールド、または2つの個別の外部キーが必要です。

また、すべてのユーザーに共通の情報を1つのテーブルに入れ、ユーザータイプに固有の情報用に個別のテーブルを用意して、ユーザーIDを主キーとする単一のテーブルを作成することもできます。

25
Guffa

外部キーは単一の主キーしか参照できないため、参照できません。ただし、ブリッジテーブルを使用できます。

CustomerA <---- CustomerA_Orders ----> Order
CustomerB <---- CustomerB_Orders ----> Order

そのため、Orderはhaveの外部キーさえありません。しかし、これが望ましいかどうか...

4
Marc Gravell

これが行われたSQLServerデータベース(4つの無関係なテーブルとの4つの外部キー関係で使用される単一の列)を継承したので、はい、可能です。しかし、私の前任者がいなくなったので、なぜ彼がそれが良い考えだと思ったのかは尋ねられません。

彼は、あいまいさの問題を回避するためにGUID列( "uniqueidentifier"タイプ)を使用し、1つだけが一致することが保証されているため、外部キーの制約チェックをオフにしました。しかし、私は考えることができます。してはいけない理由はたくさんありますが、私が考えるべき理由はありません。

あなたの問題は、通常、共有顧客データを使用して親テーブルを作成し、次に顧客の各クラスに固有のデータを含む2つの子テーブルを作成することで解決される、従来の「特殊化」問題のように聞こえます。次に、外部キーは親の顧客テーブルに照らし合わせ、どのタイプの顧客の決定は、一致するエントリを持つ子テーブルに基づいて行われます。

2
Dave G.

複数のテーブルを参照する外部キーを作成できます。この機能は、テーブルの垂直分割を可能にし、参照整合性を維持するためのものです。しかし、あなたの場合、これは当てはまりません。

最善の策は、可能な列を持つCustomerTypeテーブル(CustomerTypeID、CustomerID、ここでCustomerIDはPK)を用意し、OrderIDテーブルをCustomerIDに参照することです。

ラージ

1
Raj

2つの異なるタイプの顧客は、タイプとサブタイプの古典的なケース、または必要に応じてクラスとサブクラスです。 ここ は別の質問からの回答です。

基本的に、クラステーブル継承手法はアーナンドの答えのようなものです。 shared-primary-key手法を使用すると、1つの列で2種類の外部キーによって発生する問題を回避できます。外部キーはcustomer-idになります。これにより、顧客テーブルの1つの行と、場合によっては適切な種類の顧客タイプテーブルの1つの行が識別されます。

0
Walter Mitty

前述のように、キーがたとえば12345の場合、どのテーブルで検索するかをどのようにして知ることができますか?おそらく、2つのテーブルのキー値が重複しないようにするために何かをすることはできますが、これはあまりに醜くて面倒なので、熟考することはできません。どの顧客タイプであるかを示す2番目のフィールドを持つことができます。ただし、2つのフィールドがある場合は、顧客タイプ1 ID用のフィールドと顧客タイプ2ID用のフィールドを用意してください。

アプリについて詳しく知らなくても、最初に考えたのは、両方に共通のデータを含む一般的な顧客テーブルを用意し、次に各顧客タイプに固有のデータを含む2つの追加テーブルを用意する必要があるということです。 2つに共通するデータがたくさんあるはずだと思います。少なくとも名前、住所、顧客番号などの基本的なものであり、テーブル間で列を繰り返すのは大変な時間です。その後、追加のテーブルはベーステーブルを参照することができます。その場合、基本テーブルには単一のキーが存在するため、外部キーの問題はどのテーブルを参照するかを知らなければならないという問題が解消されます。

0
Jay