web-dev-qa-db-ja.com

外部キーはNULLまたは重複する可能性がありますか。

2つのことを明確にしてください。

  1. 外部キーはNULLにできますか?
  2. 外部キーは複製できますか?

私の知る限りでは、NULLは外部キーに使用すべきではありませんが、私のアプリケーションでは、OracleとSQL Serverの両方にNULLを入力することができます。

257
jams

短い答え:はい、それはNULLでも重複していてもかまいません。

外部キーがnullである必要があるのか​​、一意である必要があるのか​​、または一意ではないのかを説明します。最初に覚えておいてください外部キーは単にそのフィールドの値が別のテーブル(親テーブル)の最初に存在しなければならないことを必要とします。それはすべてFKの定義によるものです。定義上NULLは値ではありません。 Nullは、その値が何であるかまだわからないことを意味します。

実生活の例を挙げましょう。販売提案を格納するデータベースがあるとします。さらに、各プロポーザルに1人の営業担当者と1人のクライアントしか割り当てられていないとします。したがって、提案テーブルには、クライアントIDと営業担当者IDの2つの外部キーがあります。ただし、レコードが作成された時点では、営業担当者は常に割り当てられているわけではないため(まだ誰も自由に作業できないため)、クライアントIDは入力されますが、営業担当者IDはnullになります。言い換えれば、通常、データが入力された時点でその値がわからない場合はNULL FKを持つことができる必要がありますが、入力する必要があるテーブル内の他の値はわかっています。 FKでnullを許可するには、通常、FKを持つフィールドにnullを許可するだけです。 null値は、FKであるという考えとは異なります。

それがユニークであるかどうかは、そのテーブルが親テーブルに対して1対1または1対多の関係にあるかどうかに関係します。 1対1の関係にある場合は、1つのテーブルにすべてのデータを含めることができますが、テーブルの幅が広すぎたり、データが別のトピックにある場合は可能です(従業員 - 保険の例@tbone例えば)、それからあなたはFKと別々のテーブルが欲しい。その場合は、このFKをPK(一意性を保証するもの)にもするか、またはそれに固有の制約を適用します。

ほとんどのFKは一対多のリレーションシップのためのものであり、それはあなたがFKからさらに制約を追加することなく得られるものです。たとえば、注文テーブルと注文詳細テーブルがあります。顧客が一度に10個の商品を注文すると、彼はFKと同じorderIDを含む1つの注文と10の注文詳細レコードを持っています。

435
HLGEM

1 - はい、少なくともSQL Server 2000以降です。

2 - はい、それがUNIQUE制約ではない、またはユニークインデックスにリンクされていない限り。

47
JNK

馬の口から:

一致するPRIMARYキーまたはUNIQUEキーがない場合でも、外部キーはすべてNULLのキー値を許可します。

外部キーに制約なし

外部キーに他の制約が定義されていない場合、子テーブル内の任意の数の行が同じ親キー値を参照できます。このモデルでは、外部キーにNULLを使用できます。 ...

外部キーに対するNOT NULL制約

外部キーにNULLが許可されていない場合、子テーブルの各行は外部キーにNULLが許可されていないため、親キーの値を明示的に参照する必要があります。

子テーブル内の任意の数の行が同じ親キー値を参照できるため、このモデルでは親キーと外部キーの間に1対多の関係が確立されます。ただし、子テーブルの各行は、親キー値への参照を持っている必要があります。外部キーに値(null)がないことは許可されていません。前のセクションの同じ例を使用して、このような関係を説明できます。ただし、この場合、従業員は特定の部門への参照を持つ必要があります。

外部キーに対する一意の制約

外部キーにUNIQUE制約が定義されている場合、子テーブル内の1行のみが特定の親キー値を参照できます。このモデルでは、外部キーにNULLを使用できます。

このモデルでは、親キーと外部キーとの間に1対1の関係が確立され、外部キーに未定義の値(null)が許容されます。たとえば、従業員テーブルに、会社の保険プランの従業員の会員番号を参照するMEMBERNOという名前の列があるとします。また、INSURANCEという名前のテーブルにはMEMBERNOという名前の主キーがあり、テーブルの他の列には従業員の保険契約に関する各情報が保持されています。 employeeテーブルのMEMBERNOは、外部キーと一意のキーの両方でなければなりません。

  • EMP_TAB表とINSURANCE表の間に参照整合性規則を強制する(FOREIGN KEY制約)

  • 各従業員が一意の会員番号を持っていることを保証する(UNIQUEキー制約)

外部キーに対するUNIQUEおよびNOT NULL制約

UNIQUE制約とNOT NULL制約の両方が外部キーに定義されている場合、子テーブルの1行のみが特定の親キー値を参照できます。また、NULL値は外部キーでは許可されない親キーの値.

これを見なさい:

Oracle 11gリンク

39
tbone

はい外部キーは上のプログラマーが言ったようにnullでもかまいません...外部キーをnullにする必要があるというシナリオをもう1つ追加します。ビデオコメントテーブルでは、2つの外部キーPicturesIdとVideosIdを主キーCommentIdと一緒に使用できます。そのため、ビデオにコメントする場合はVideosIdだけが必須で、pictureIdはnullになります。また、ピクチャにコメントする場合はPictureIdだけが必須になり、VideosIdはnullになります...

15

それはこのforeign keyがあなたの関係においてどのような役割を果たすかに依存します。

  1. もしこのforeign keyがあなたの関係のkey attributeでもあるなら、それはNULLになることはできません
  2. このforeign keyがあなたのリレーションの通常の属性であれば、NULLでも構いません。
5
shinxg

これは、Oracle構文を使用した例です。
まず、テーブルCOUNTRYを作成しましょう

CREATE TABLE TBL_COUNTRY ( COUNTRY_ID VARCHAR2 (50) NOT NULL ) ;
ALTER TABLE TBL_COUNTRY ADD CONSTRAINT COUNTRY_PK PRIMARY KEY ( COUNTRY_ID ) ;

テーブルPROVINCEを作成します。

CREATE TABLE TBL_PROVINCE(
PROVINCE_ID VARCHAR2 (50) NOT NULL ,
COUNTRY_ID  VARCHAR2 (50)
);
ALTER TABLE TBL_PROVINCE ADD CONSTRAINT PROVINCE_PK PRIMARY KEY ( PROVINCE_ID ) ;
ALTER TABLE TBL_PROVINCE ADD CONSTRAINT PROVINCE_COUNTRY_FK FOREIGN KEY ( COUNTRY_ID ) REFERENCES TBL_COUNTRY ( COUNTRY_ID ) ;

これはOracleでも完璧に動作します。 2番目のテーブルのCOUNTRY_ID外部キーには「NOT NULL」がありません。

PROVINCEテーブルに行を挿入するには、PROVINCE_IDを指定するだけで十分です。ただし、COUNTRY_IDも指定する場合は、COUNTRYテーブルにすでに存在している必要があります。

3
Mouhcine

デフォルトでは、外部キーに制約はありません。外部キーはnullで重複する可能性があります。

テーブルの作成中またはテーブルの変更中に、一意性の制約を追加した場合、またはnull以外の場合は、null /重複値を許可しません。

1
nitin lalwani

簡単に言うと、エンティティ間の「非識別」関係はERモデルの一部であり、ER図の設計時にMicrosoft Visioで使用できます。これは、「ゼロまたはゼロ以上」、または「ゼロまたは1」のエンティティ間でカーディナリティを強制するために必要です。 「1対多」の「1」ではなく、基数の「0」に注意してください。

さて、カーディナリティーが「ゼロ」(非識別)である可能性がある非識別関係の例は、1つのエンティティーA内のレコード/オブジェクトを言うときです。別のエンティティBの/ s。

そのため、あるエンティティAのレコードが他のエンティティBのレコードに対して自分自身を識別する可能性があるため、エンティティBにはエンティティBのレコードのID値を持つ列があるはずです。エンティティAのレコードがエンティティBのレコード(またはオブジェクト)を識別しない場合、この列は "Null"になります。

オブジェクト指向(現実世界)パラダイムでは、クラスBのオブジェクトがその存在に関してクラスAのオブジェクトに必ずしも依存しない(強く結合されていない)状況があります。クラスBのオブジェクトの概念とは対照的に、クラスAがクラスAのオブジェクトを「含む」(包含)できるようなA(クラスのオブジェクトはクラスAのオブジェクト) B)作成。

SQLクエリの観点からは、エンティティB用に予約されている外部キーに対して "null以外"であるエンティティB内のすべてのレコードをクエリできます。これにより、エンティティAの行に対応する特定の値を持つすべてのレコードが返されます。あるいは、NULL値を持つすべてのレコードが、エンティティBのエンティティAにレコードを持たないレコードになります。

0
Fakhar

外部キーの概念は、メインテーブルにすでに存在する値を参照するという概念に基づいています。それが他のテーブルで外部キーと呼ばれる理由です。この概念は参照整合性と呼ばれます。外部キーがnullフィールドとして宣言されていると、参照整合性の論理そのものに違反します。それは何を指しますか?メインテーブルにあるものだけを参照できます。したがって、外部キーフィールドをnullとして宣言するのは間違っていると思います。

0
SQLDev