web-dev-qa-db-ja.com

外部キーをnullにすることはできますか?

データベースプロジェクトには、プライマリキーと2つの排他的な外部キーVehicle_IDおよびPiece_IDを持つテーブルSaleがあります。たとえば、車両を販売する場合、外部キーとしてVehicle_IDが必要ですが、Piece_IDは必要ありません。 NULLをPiece_IDに入れることはできますか、外部キーがnullになる可能性がありますか?または、この仕事をする方法はありますか?

ありがとう。

11
notfound90

主キーの1つまたは複数の列はNOT NULLでなければなりません。レコードをNULLで一意に識別することはできません。したがって、外部キーの参照先のID列はNOT NULLとして定義する必要があります。

ただし、外部キーの関係をオプションにすることは正当な設計上の決定であり、それを表す方法は、キーの参照側をオプションにする、つまりNULLを許可することです。

データモデリング用語で説明したのは、(排他的な)弧です。「テーブル... 2つ以上の外部キーがあり、そのうちの1つだけがnull以外になる可能性があります。」論理モデリングでは、弧は完全に受け入れられますが、それらを別々のテーブルとして実装することに賛成する強い意見があります。シナリオでは、汎用のSaleテーブルと2つのサブタイプテーブルVehicleSaleおよびPieceSaleになります。

個別のテーブル実装の利点は次のとおりです。

  • 外部キーの制約を適用するのが簡単です。
  • (たとえば)車両販売に関連する追加の列を追加する方が簡単です。
  • 追加のサブタイプを使用してモデルを拡張するのが簡単です。
  • アプリケーション開発を簡素化できる、より明確なデータモデル。

ただし、利点はすべてが一方向というわけではありません。 SaleVehicleSaleまたはPieceSaleのいずれかに適用されることを確認することは非常に簡単ですが、両方にではなく、Saleというルールを適用します- 必須子のレコードがあると、実際にはかなり危険になります。

したがって、一般的なアドバイスは、排他的なアークが誤っているということであり、一般的には良いアドバイスです。しかし、一部の人が理解しているほど明確ではありません。

14
APC

回答:

はい、できます。FK自体をNULL可能にしますが、CHECKを追加して、FKの1つにNULL以外の値が含まれるようにします。

詳細:

FKはNULL可能で、1..0:N関係をモデル化できます。つまり、「子」行can(必須ではありません)に「親」行があります。

NOT NULL外部キーは1:N関係をモデル化します。つまり、すべての子mustには親があります。

FKがコンポジットの場合1、およびそのフィールドの少なくとも1つがNULL可能である場合、NULL値と非NULL値の混合は特別な方法で処理されます。

  • FKがMATCH FULLの場合、allの値はNULLであるか、すべての値がNULLでなく、一部の親行と一致する必要があります。
  • FKがMATCH PARTIALの場合、NULL以外の値のみが一部の親行と一致する必要があります(NULLは無視されます)。
  • FKがMATCH SIMPLEの場合、すべての値が非NULLであり、一部の親行と一致する必要があるか、少なくとも1つのNULL値が存在する(この場合、非NULLは一致する必要がない)。

ほとんどのDBMSはデフォルトでMATCH SIMPLE( MS Access の顕著な例外を除く)に設定されており、ほとんどはデフォルト以外は何もサポートしていません。


1 ここにはありません-完全を期すために言及しています。

6

「排他的な外部キー」が何を意味するかによって、車両と部品をいくつかのより大きなスーパークラスの2つのサブクラスと考え、販売可能アイテムと呼ぶかもしれません。

「クラステーブルの継承」と呼ばれるデザインパターンを使用すると、スーパークラス用と各サブクラステーブル用の3つのテーブルができます。さらに、「共有主キー」と呼ばれる設計を使用する場合、3つのテーブルすべてに同じ主キーを使用できます。

これにより、Saleテーブルに単一の外部キー、Saleable_Item_Idを持たせることができます。このキーは、Saleable_Itemテーブルを参照し、ケースに応じてVehicleまたはPieceテーブルを参照します。これは、既存のデザインよりもうまくいく場合があります。

詳しくは、「クラステーブルの継承」と「共有主キー」をgoogleにしてください。

1
Walter Mitty

外部キーがnullであっても、Oracleは文句を言うべきではありません。

エラーが発生しましたか?

0
Andrew Walters