1

私の質問は、0から多くの関係に関連しています。たとえば、customerテーブルとOrderテーブルがあり、顧客が1つまたは複数の注文を持ち、注文が0または1つの顧客を持つことができる場合。ゼロになる可能性がある理由は、注文が、顧客の詳細が保持されていないレガシー注文システムからインポートされたためです。

私は2つのオプションがあると信じています:

  1. 顧客がいない注文の場合は、CustomerID(Ordersテーブルの外部ケット)をnullに設定します。
  2. CustomerIDとOrderIDを含む顧客と注文の間にジャンクションテーブルを作成します。しかし、ジャンクションテーブルは特に多対多の関係のためのものだと思いました

どちらが最良の選択肢ですか?

編集:

私は次の投稿を発見し、Molfの回答に同意します。これは、元の質問のオプション2です。必要なnull許容外部キーの例はありますか?

4

2 に答える 2

3

最初に順序キーを一意に制限したり、関係が多対多になることを予測したりしない限り、ジャンクション テーブルは作成しません。

通常の単一 FK を使用した単純な 2 テーブル オプションでの問題は、注文行で NULL 顧客 FK を許可するかどうかです。これを許可しないことは確かに可能であり (今後の参照整合性の理由から明らかです)、不明な顧客のすべての従来の注文に使用される「不明な顧客」の顧客が存在する可能性があります。これは非常に良い方法で、NULL (誤解される可能性があります) を明示的なもの (「UNKNOWN CUSTOMER」への参照。実際の顧客が作成または識別されると、いつでも修正できます) に置き換えられます。

レガシーデータが今後のデータの比較的小さな部分になり、典型的なケースでデータにできるだけ多くのRIを確保したいので、それを強く検討します(今後のすべてのケースでは、注文作成時に顧客) を保持しながら、従来のケース (時間の経過とともにデータ ユニバースでの重要性が低下する) に対応します。

于 2012-05-10T19:37:18.527 に答える
1

ここには冗長性があり、概念的に混乱していますが、これには要件があるかもしれません。これを最初から行った場合は、Orders に Customer.CustomerID の NULLable FK を持たせることができます。これにより、顧客が 1 人の場合 (多数の注文と顧客への 1/0 注文) を満たすことができます。これは技術的には多対多の関係であるため、ジャンクション テーブルを使用してそれを行うこともできます。

最良の代替手段は、データのクエリ方法によって異なります。たとえば、Orders テーブルに対して分析タイプのクエリを実行すると、より便利になる場合があります。

顧客なしで注文を見つける

SELECT SUM(CASE WHEN customer iS NULL THEN 1 ELSE 0 END) FROM Orders

SELECT SUM(CASE WHEN j.oid iS NULL THEN 1 ELSE 0 END) FROM 
Orders o  LEFT OUTER JOIN Junction j 
WHERE o.o_id = j.o_id

もう一方がよりクリーンで効率的なクエリを作成する例を考え出すことができます。

于 2012-05-10T18:53:29.343 に答える