MATCH FULL、MATCH SIMPLE、MATCH PARTIALの違いは?


回答:


38

CREATE TABLEマニュアルページを確認してください

:3つのマッチタイプがありMATCH FULLMATCH PARTIALMATCH SIMPLE (デフォルト)。MATCH FULLすべての外部キー列がnullでない限り、複数列の外部キーの1つの列をnullにすることはできません。それらがすべてヌルの場合、行は参照されるテーブルで一致する必要はありません。MATCH SIMPLE任意の外部キー列をnullにすることができます。それらのいずれかがヌルである場合、行は参照されるテーブルで一致する必要はありません。MATCH PARTIALまだ実装されていません。(もちろん、NOT NULL参照列に制約を適用して、これらのケースが発生しないようにすることができます。)

また、外部キーに関する章では

通常、参照行のいずれかがNULLの場合、参照行は外部キー制約を満たす必要はありません。MATCH FULL 外部キー宣言に追加された場合、参照行はすべての参照列がnullの場合にのみ制約を満たすようにエスケープします(null値と非null値の混合はMATCH FULL 制約に失敗することが保証されます)。参照行が外部キー制約の充足を回避できないようにするには、参照列をとして宣言しますNOT NULL

そして、必ず現在のマニュアルまたはインストールに一致するバージョンを参照してください。古いバージョンへの古いGoogleリンクに陥らないでください。


7

FULLvs SIMPLEvsPARTIAL

選択した答えは正しいですが、これが初めての場合は、コードでそれを見たいと思うかもしれません。

-- one row with (1,1)
CREATE TABLE foo ( a int, b int,
  PRIMARY KEY (a,b)
);
INSERT INTO foo (a,b) VALUES (1,1);

--
-- two child tables to reference it
-- 
CREATE TABLE t_full ( a int, b int,
  FOREIGN KEY (a,b) REFERENCES foo MATCH FULL
);
CREATE TABLE t_simple ( a int, b int,
  FOREIGN KEY (a,b) REFERENCES foo MATCH SIMPLE
);

論理的に、とFULLSIMPLE、完全一致を挿入できます。

-- works
INSERT INTO t_full (a,b) VALUES (1,1);
INSERT INTO t_simple (a,b) VALUES (1,1);

問題は、列の1つがであるときに発生しますNULL

-- works
INSERT INTO t_simple (a,b) VALUES (1,NULL);

-- fails
INSERT INTO t_full (a,b) VALUES (1,NULL);

に挿入t_fullすると、次のエラーが生成されます。

ERROR:  insert or update on table "t_full" violates foreign key constraint "t_full_a_fkey"
DETAIL:  MATCH FULL does not allow mixing of null and nonnull key values.
INSERT 0 1

(42,NULL)わかりました、それではどうですか-これは私がいつも混乱しているMATCH SIMPLEと感じた部分です、

-- works
INSERT INTO t_simple (a,b) VALUES (42,NULL);

上記の動作は、実装されていない場合には機能しませんMATCH PARTIAL。これは、右端の列がNULL除外されている複合インデックスに必要なことを行う可能性があります。しかし、一部の人々は、それをPandoraの箱を悪いデザインに開放する方法として見ています。

簡単な定義とニーモニック

  • MATCH FULLすべてが完全に一致するか、すべての列が一致する必要がありますNULL
  • MATCH SIMPLE1つのことがNULL制約の場合、単に無視されます。
  • MATCH PARTIAL制約の目的のために賢明な何かをすることによって、NULLすべてNULL部分的に救われるわけではないという事実が一つの場合です。

SQL仕様ノート

後世のために、SQL仕様の定義を以下に示します。 <match type>

  • MATCH SIMPLE少なくとも1つの参照列がnullの場合、参照テーブルの行は制約チェックに合格します。すべての参照列がnullでない場合、すべての参照列に一致する参照先テーブルの行がある場合にのみ、行は制約チェックに合格します。
  • MATCH PARTIAL:すべての参照列がnullの場合、参照テーブルの行は制約チェックに合格します。少なくとも1つの参照列がNULLでない場合、すべての非NULL参照列と一致する参照先テーブルの行がある場合にのみ、行は制約チェックに合格します。
  • MATCH FULL:すべての参照列がnullの場合、参照テーブルの行は制約チェックに合格します。すべての参照列がnullでない場合、すべての参照列に一致する参照先テーブルの行がある場合にのみ、行は制約チェックに合格します。参照元の列がnullで、別の参照先の列がnullでない場合、参照元テーブルの行は制約チェックに違反します。

これはPostgreSQL固有のものではありませんが、これらの例はPostgreSQLで実証されています

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.