Я заметил MATCH SIMPLE
и MATCH FULL
, но я не понимаю, что они делают. Я вижу, по умолчанию это MATCH SIMPLE
; но как другие MATCH
предложения к FOREIGN KEY
функции ограничения?
источник
Я заметил MATCH SIMPLE
и MATCH FULL
, но я не понимаю, что они делают. Я вижу, по умолчанию это MATCH SIMPLE
; но как другие MATCH
предложения к FOREIGN KEY
функции ограничения?
Проверьте CREATE TABLE
страницу руководства :
Есть три типа соответствия:
MATCH FULL
,MATCH PARTIAL
иMATCH SIMPLE
(это значение по умолчанию).MATCH FULL
не допустит, чтобы один столбец внешнего ключа из нескольких столбцов был нулевым, если все столбцы внешнего ключа не равны нулю; если все они являются нулевыми, строка не обязательно должна иметь совпадение в ссылочной таблице.MATCH SIMPLE
позволяет любому из столбцов внешнего ключа быть нулевым; если какой-либо из них имеет значение null, строка не обязательно должна иметь совпадение в ссылочной таблице.MATCH PARTIAL
еще не реализовано. (Конечно,NOT NULL
ограничения могут быть применены к ссылочному столбцу (столбцам), чтобы предотвратить возникновение этих случаев.)
Также в главе об иностранных ключах :
Обычно ссылочная строка не должна удовлетворять ограничению внешнего ключа, если какой-либо из ее столбцов ссылается на NULL. Если
MATCH FULL
он добавлен в объявление внешнего ключа, ссылочная строка выходит за пределы, удовлетворяющие ограничению, только в том случае, если все ее ссылочные столбцы имеют нулевое значение (поэтому сочетание нулевых и ненулевых значений гарантированно не выполнитMATCH FULL
ограничение). Если вы не хотите, чтобы ссылки на строки могли избежать ограничения внешнего ключа, объявите столбец (и) ссылки какNOT NULL
.
И обязательно ознакомьтесь с текущим руководством или версией, соответствующей вашей установке. Не поддавайтесь на устаревшие ссылки Google на устаревшие версии.
FULL
против SIMPLE
против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);
Проблема возникает, когда один из столбцов есть 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
вычеркнут крайний правый столбец . Тем не менее, некоторые люди рассматривают это как способ открыть ящик Пандоры для плохого дизайна.
MATCH FULL
все должно полностью совпадать, или все столбцы должны бытьNULL
MATCH SIMPLE
если одна вещь является NULL
ограничением просто игнорируется.MATCH PARTIAL
если одна вещь NULL
в том , что не все NULL
это частично спасенных делать что - то осмысленное с целью ограничения.Для потомков, вот определения из спецификации SQL на <match type>
MATCH SIMPLE
если хотя бы один ссылающийся столбец имеет значение null, то строка таблицы ссылок проходит проверку ограничения. Если все ссылочные столбцы не равны NULL, тогда строка проходит проверку ограничения, если и только если есть строка таблицы, на которую ссылаются, которая соответствует всем ссылочным столбцам.MATCH PARTIAL
: если все ссылающиеся столбцы являются нулевыми, то строка таблицы ссылок проходит проверку ограничения. Если хотя бы один ссылающийся столбец не является нулевым, тогда строка проходит проверку ограничения, если и только если существует строка таблицы, на которую ссылаются, которая соответствует всем ненулевым ссылочным столбцам.MATCH FULL
: если все ссылающиеся столбцы являются нулевыми, то строка таблицы ссылок проходит проверку ограничения. Если все ссылочные столбцы не равны NULL, тогда строка проходит проверку ограничения, если и только если есть строка таблицы, на которую ссылаются, которая соответствует всем ссылочным столбцам. Если какой-либо столбец ссылки имеет значение NULL, а другой столбец ссылается не NULL, то строка таблицы ссылок нарушает проверку ограничения.
Хотя это не является специфичным для PostgreSQL, эти примеры демонстрируются на PostgreSQL.