Eu notei um MATCH SIMPLE
e MATCH FULL
, mas não entendo o que eles fazem. Eu vejo o padrão é MATCH SIMPLE
; mas, como as outras MATCH
cláusulas da FOREIGN KEY
restrição funcionam?
Eu notei um MATCH SIMPLE
e MATCH FULL
, mas não entendo o que eles fazem. Eu vejo o padrão é MATCH SIMPLE
; mas, como as outras MATCH
cláusulas da FOREIGN KEY
restrição funcionam?
Respostas:
Verifique a CREATE TABLE
página do manual :
Existem três tipos de correspondência:
MATCH FULL
,MATCH PARTIAL
eMATCH SIMPLE
(que é o padrão).MATCH FULL
não permitirá que uma coluna de uma chave estrangeira de várias colunas seja nula, a menos que todas as colunas de chave estrangeira sejam nulas; se forem todos nulos, não é necessário que a linha tenha uma correspondência na tabela referenciada.MATCH SIMPLE
permite que qualquer uma das colunas de chave estrangeira seja nula; se algum deles for nulo, não é necessário que a linha tenha uma correspondência na tabela referenciada.MATCH PARTIAL
ainda não está implementado. (Obviamente,NOT NULL
restrições podem ser aplicadas às colunas de referência para impedir que esses casos ocorram.)
Além disso, no capítulo sobre Chaves estrangeiras :
Normalmente, uma linha de referência não precisa satisfazer a restrição de chave estrangeira se alguma de suas colunas de referência for nula. Se
MATCH FULL
for adicionado à declaração de chave estrangeira, uma linha de referência escapará satisfazendo a restrição apenas se todas as suas colunas de referência forem nulas (portanto, é garantido que uma combinação de valores nulos e não nulos falhará em umaMATCH FULL
restrição). Se você não deseja que as linhas de referência evitem satisfazer a restrição de chave estrangeira, declare as colunas de referência comoNOT NULL
.
E não deixe de consultar o manual atual ou a versão correspondente à sua instalação. Não caia em links desatualizados do Google para versões desatualizadas.
FULL
vs SIMPLE
vsPARTIAL
Embora a resposta escolhida esteja correta, se isso é novidade para você, você pode querer vê-la com código - acho que é mais fácil pensar dessa maneira.
-- 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
);
Logicamente, com FULL
e SIMPLE
, podemos inserir uma correspondência completa.
-- works
INSERT INTO t_full (a,b) VALUES (1,1);
INSERT INTO t_simple (a,b) VALUES (1,1);
O problema surge quando uma das colunas é NULL
.
-- works
INSERT INTO t_simple (a,b) VALUES (1,NULL);
-- fails
INSERT INTO t_full (a,b) VALUES (1,NULL);
A inserção em t_full
gera o seguinte erro,
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
Ok, so what about (42,NULL)
-- this is the part that I always found confusing about MATCH SIMPLE
,
-- works
INSERT INTO t_simple (a,b) VALUES (42,NULL);
O comportamento acima NÃO funcionaria com os não implementados MATCH PARTIAL
, o que provavelmente faz o que você deseja para um índice composto no qual a coluna mais à direita é NULL
editada. No entanto, algumas pessoas vêem isso como um método de abrir a caixa de uma Pandora para um design ruim.
MATCH FULL
tudo deve corresponder totalmente ou todas as colunas devem serNULL
MATCH SIMPLE
se uma coisa é NULL
a restrição é simplesmente ignorada.MATCH PARTIAL
Se uma coisa é NULL
o fato de que nem tudo está NULL
é parcialmente recuperado fazendo algo sensato com a finalidade da restrição.Para a posteridade, aqui estão as definições do SQL Spec no diretório <match type>
MATCH SIMPLE
se pelo menos uma coluna de referência for nula, a linha da tabela de referência passará na verificação de restrição. Se todas as colunas de referência não forem nulas, a linha passará na verificação de restrição se e somente se houver uma linha da tabela referenciada que corresponda a todas as colunas de referência.MATCH PARTIAL
: se todas as colunas de referência forem nulas, a linha da tabela de referência passará na verificação de restrição. Se pelo menos uma coluna de referência não for nula, a linha passará na verificação de restrição se e somente se houver uma linha da tabela referenciada que corresponda a todas as colunas de referência não nulas.MATCH FULL
: se todas as colunas de referência forem nulas, a linha da tabela de referência passará na verificação de restrição. Se todas as colunas de referência não forem nulas, a linha passará na verificação de restrição se e somente se houver uma linha da tabela referenciada que corresponda a todas as colunas de referência. Se alguma coluna de referência for nula e outra não for nula, a linha da tabela de referência violará a verificação de restrição.
Embora isso não seja específico do PostgreSQL, esses exemplos são demonstrados com o PostgreSQL