O que eu entendo:
Além das referências válidas à tabela referenciada, uma coluna com uma chave estrangeira também pode conter um valor NULL. O padrão SQL define vários modos de correspondência para chaves estrangeiras, como MATCH SIMPLE e MATCH FULL. Para chaves estrangeiras de várias colunas, MATCH SIMPLE permite um valor errado (= sem referência) em qualquer uma das colunas, desde que pelo menos uma coluna da chave estrangeira contenha um valor NULL.
As chaves estrangeiras de várias colunas são raras (porque as chaves primárias de várias colunas são), mas posso imaginar casos de uso válidos. Por exemplo, uma tradução de uma postagem de blog pode ter uma chave primária (post_id, language_id)
. Agora, algo que faça referência a tal tradução (por exemplo, qual tradução um usuário está editando no momento) teria uma chave estrangeira de várias colunas.
O que não entendo:
Por que eu usaria MATCH SIMPLE para minha chave estrangeira?
No exemplo acima, não faz sentido ter uma entrada "atualmente editando" que apenas faz referência a post_id
e não a language_id
.
Qual seria um exemplo em que faz sentido?
Minha preferência é evitar nulos em colunas de chave estrangeira. Torne todas as chaves estrangeiras não anuláveis. Na verdade, tenho chave estrangeira = não nulo como uma verificação padrão em alguns scripts de análise estática que uso para validar projetos de banco de dados.
O comportamento FULL / SIMPLE é obscuro o suficiente para que, em minha experiência, nem mesmo os especialistas o entendam (sou um especialista e tenho que pensar duas vezes!) Como o ypercube aponta, SIMPLE é efetivamente o padrão no Microsoft SQL Server mas suspeito que a maioria das pessoas que trabalha com esse produto nunca o considerou. Se um de seus objetivos no design do banco de dados é tornar os dados compreensíveis e úteis para o usuário médio, as chaves estrangeiras devem ser não anuláveis.
Não exatamente. Todas as restrições de chave estrangeira permitem que as linhas estejam "erradas" (sem referência) se a linha tiver
NULL
valores.MATCH FULL
por exemplo, permitirá uma(NULL, NULL)
linha em uma chave estrangeira de duas colunas. Isso também não faz muito sentido para mim. A única diferença é - como você mencionou - que permitiráMATCH SIMPLE
linhas enquanto não.(post_id_value, NULL)
(NULL, language_id_value)
MATCH FULL
Já vi algumas questões no site onde fazia (alguns) sentido ter
MATCH SIMPLE
e um valor ser nulo. Os casos geralmente tinham algum design desnormalizado. No seu exemplo ficaria como uma chave estrangeira extra da tabela de histórico, usando apenas uma das duas colunas:Isso permitiria que a tabela de histórico fizesse referência à tabela de tradução quando ambos os valores não fossem nulos e à tabela de postagem quando language_id fosse nulo. Eu mesmo nunca usaria, mas já vi.
Agora, deixando esses casos estranhos para trás, as duas opções (
MATCH FULL
eMATCH SIMPLE
) são idênticas se todas as colunas forem definidas comNOT NULL
. E como é comum ter colunas não anuláveis em chaves estrangeiras e essa configuração afeta apenas chaves estrangeiras de várias colunas, acho que é por isso que muitos designers geralmente não se preocupam com essa configuração e a deixam como padrão do DBMS (MATCH SIMPLE
no Postgres) .Então, para sua pergunta:
Posso contra-perguntar:
Observe também que a maioria dos DBMS não implementou todas as opções fornecidas pelo padrão SQL. O Postgres não tem
MATCH PARTIAL
e o SQL Server não tem nenhuma opção (todas as chaves estrangeiras se comportam comoMATCH SIMPLE
).Você está perguntando:
Aqui está um exemplo muito simples:
Neste exemplo, a tabela
info
mantém informações sobre, aluno, cursos e exames, e queremos que essas informações sejam consistentes. Semmatch simple
isso não é possível. Observe que, no entanto, a chave estrangeira é verificada:Finalmente, observe que no exemplo acima você deve especificar pelo menos um aluno ou um curso;