web-dev-qa-db-ja.com

SQL Serverのテーブルに複数のnull可能なFKを置くことは悪い習慣と見なされますか

SQL Serverのデータベース構造には、注文に関するさまざまな情報を必要とする3つのタイプの製品があります。そこで、1つのCustomersテーブルと3つの異なる注文テーブルOrdersForProductAsOrdersForProductBsOrdersForProductCsを作成しました。すべての注文テーブルには、Customersテーブルで1対多の関係があります。

Paymentsという別のテーブルもあり、その中に支払いの詳細を保持します。しかし、私はそれをどのように構造化するかについてここで疑問を持っています。

私には複数の製品タイプがあり、顧客が同時に複数の製品を注文する可能性があるため、これらの3つの注文テーブルをPaymentsテーブルに関連付ける必要があります。

もう1つの問題は、顧客が注文できるのは1種類の製品のみであることです。したがって、PaymentsテーブルのFK列はnullableである必要があります。

私の質問は、これらのnullable FK列が長期的に見て頭痛の種になるかどうかです。一般的に言えば、テーブルにnull可能なFK列を含めることは悪い習慣と見なされますか?

13
tugberk

なぜOrdersForProductXテーブルがあるのか​​、疑問に思います
あなたが質問したFK問題は、設計できる可能性があります...

これらのテーブルの構造が同じ場合は、ProductTypeテーブルにOrderProduct列が必要です。次に、Paymentは1つのFKでそれにリンクします

テーブルの構造が異なる場合、いくつかの共通の属性があると思います。したがって、共通のOrderProductテーブルを作成してから、製品タイプごとに特定の子テーブルを作成できます(以下を参照)。繰り返しますが、Paymentは、1つのFKでcommoneテーブルにリンクするだけです。

これは「スーパーキー/サブタイプパターン」です

  • UQ1は、サブタイプテーブルで外部キーを使用する「スーパーキー」です。
  • 各サブタイプテーブルには、(OrderID, ProductType)に対する複合PKおよびFKがあります。
  • 各サブタイプテーブルには、そのテーブルのタイプを制限するCHECK制約があります。

注文商品

  • OrderID、PK、UQ1
  • ProductType、UQ1
  • CommonThing1
  • ...

OrderProductA

  • OrderID、PK、FK
  • ProductType、PK、FK、CHECK ProductType = A
  • ProductAThing1
  • ...

OrderProductB

  • OrderID、PK、FK
  • ProductType、PK、FK、CHECK ProductType = B
  • ProductBThing1
  • ...
13
gbn

Null可能な「外部キー」は避けてください。それらには複数の欠点があります。

外部キーにnullが含まれている場合、参照する行の制約は常に適用されるわけではありません。ただし、そのデフォルトの動作は、異なるDBMS間で一貫していません。一部のDBMSは、null可能外部キーの動作を変更するための構成オプションをサポートしており、一部はサポートしていません。したがって、SQL開発者とユーザーは、データの整合性の観点から、null可能外部キー制約が実際に何を意味するのかが不明確になる可能性があります。 DBMS製品間、または同じ製品を使用する異なるサーバー間でのデータベースの移植では、一貫性のない結果が生じる可能性があります。

データベース設計ツール、統合ツール、およびその他のソフトウェアは、常にそれらを正しくサポートしているわけではなく、それらが生成する結果は間違っている可能性があります。

外部キーは、結合やその他のクエリロジックで頻繁に使用され、制約が有効ではない場合や、特定のDBMSによって適用されているロジックを知らない場合に制約が有効であると考えるユーザーの問題を悪化させます。

外部キーがnull可能である場合、クエリの書き換えを可能にする一部のクエリ最適化機能やその他の最適化は使用できない場合があります。

論理的には、null許容の「外部キー」制約はあまり論理的に意味がありません。 SQL標準によれば、参照されるテーブルが空であっても、このような制約に違反することはありません。これは、nullを使用する理由として最も一般的に主張されている正当化の1つ、つまり「不明な」ケースを表すものと矛盾しています。 Xの有効な値がない場合、「不明な」Xは確かに有効な値にはなりません。SQLはそれを許可します。

Null可能な外部キーは完全に不要です。外部キーを新しいテーブルに分解するか、スーパータイプ/サブタイプパターンを使用して、nullが不要になるようにすることができます。したがって、単純さと正確さのために、nullを入れるよりも省略することをお勧めします。

5
nvogel

Null可能なFK列を使用することは悪い習慣だと考えたことはありません。これらは、別のテーブルを参照するが、入力されない可能性のある列(つまり、オプションのデータ)に最適です。

(なぜ問題になると思いますか?)

2
StilesCrisis