MATCH SIMPLE
とMATCH FULL
に気づきましたが、何をしているのかわかりません。デフォルトはMATCH SIMPLE
です。しかし、FOREIGN KEY
制約関数に対する他のMATCH
句はどのように使用しますか?
マニュアルの CREATE TABLE
ページを確認してください :
マッチタイプには、
MATCH FULL
、MATCH PARTIAL
、MATCH SIMPLE
(デフォルト)の3つがあります。MATCH FULL
では、すべての外部キー列がnullでない限り、複数列の外部キーの1つの列をnullにすることはできません。それらがすべてnullの場合、その行は参照先のテーブルで一致する必要はありません。MATCH SIMPLE
では、任意の外部キー列をnullにすることができます。それらのいずれかがnullの場合、その行は参照されるテーブルで一致する必要はありません。MATCH PARTIAL
はまだ実装されていません。 (もちろん、NOT NULL
制約を参照列に適用して、これらのケースが発生しないようにすることができます。)
また、 外部キーの章 :
通常、その参照列のいずれかがnullの場合、参照行は外部キー制約を満たす必要はありません。
MATCH FULL
が外部キー宣言に追加された場合、すべての参照列がnullである場合にのみ、参照行は制約を満たし、エスケープされます(したがって、null値とnull以外の値の混合がMATCH FULL
制約)。参照する行が外部キー制約を満たさないようにしたくない場合は、参照する列をNOT NULL
として宣言します。
また、currentマニュアルまたはインストールに一致するバージョンを必ず参照してください。古いバージョンへの古いGoogleリンクに陥らないでください。
FULL
vs SIMPLE
vs PARTIAL
選択した答えは正しいですが、これが初めての場合は、コードで確認することをお勧めします。そのように考える方が簡単だと思います。
-- 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
);
論理的には、FULL
およびSIMPLE
を使用すると、完全一致を挿入できます。
-- 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);
上記の動作は[〜#〜] not [〜#〜]実装されていないMATCH PARTIAL
で機能します。これは、右端の列がNULL
edである複合インデックスに必要なことを行う可能性がありますアウト。しかし、一部の人々は、それをパンドラの箱を悪いデザインに広げる方法として見ています。
MATCH FULL
すべてが完全に一致する必要があります、またはすべての列がNULL
である必要がありますMATCH SIMPLE
1つのものがNULL
の場合、制約はsimply無視されます。MATCH PARTIAL
1つがNULL
である場合、すべてがNULL
であるとは限らないという事実は、部分的に制約の目的のために賢明な何かを行うことによって救われます。後世のために、これが<match type>
のSQL仕様の定義です。
MATCH SIMPLE
少なくとも1つの参照列がnullの場合、参照テーブルの行は制約チェックに合格します。すべての参照列がnullでない場合、行はすべての参照列に一致する被参照テーブルの行がある場合に限り、制約チェックに合格します。MATCH PARTIAL
:すべての参照列がnullの場合、参照テーブルの行は制約チェックに合格します。少なくとも1つの参照列がnullでない場合、その行は、null以外のすべての参照列と一致する参照先テーブルの行がある場合に限り、制約チェックに合格します。MATCH FULL
:すべての参照列がnullの場合、参照テーブルの行は制約チェックに合格します。すべての参照列がnullでない場合、行はすべての参照列に一致する被参照テーブルの行がある場合に限り、制約チェックに合格します。一部の参照列がnullで別の参照列がnullでない場合、参照テーブルの行は制約チェックに違反しています。
これはPostgreSQL固有ではありませんが、これらの例はPostgreSQLで示されています