Digamos que você tenha uma tabela Pedidos com uma chave estrangeira para um ID do cliente. Agora, suponha que você queira adicionar um pedido sem um ID de cliente, (se isso deveria ser possível é outra questão), você teria que tornar a chave estrangeira NULL ... Isso é uma prática ruim ou você prefere trabalhar com uma tabela de links entre Pedidos e clientes? Embora o relacionamento seja de 1 para n, uma tabela de links tornaria n para n. Por outro lado, com uma tabela de links, não tenho mais esses NULLS ...
Na verdade, não haverá muitos NULLs no banco de dados, porque um registro com uma chave estrangeira para NULL é apenas temporariamente até que um cliente para o pedido seja adicionado.
(No meu caso não é um Pedido e um Cliente).
EDIT: Que tal um cliente não atribuído para vincular?
fonte
Respostas:
Ter a tabela de links provavelmente é a melhor opção. Pelo menos não viola a normalização BCNF (forma normal de Boyce-Codd). no entanto, eu preferiria ser pragmático. Se você tiver poucos desses valores nulos e eles forem apenas temporários, acho que você deve pular a tabela de links, pois isso só adiciona complexidade ao esquema.
Em uma nota lateral; usar uma tabela de link não necessariamente torna n para n, se você na tabela de link usar a chave estrangeira que está apontando para sua tabela de pedidos como a chave primária nessa tabela de link, o relacionamento ainda é 1..n. Só pode haver uma entrada nessa tabela de links por pedido.
fonte
Não Não há nada de errado com FKs anuláveis. Isso é comum quando a entidade para a qual o FK aponta está em um relacionamento (zero ou um) a (1 ou muitos) com a tabela referenciada por chave primária.
Um exemplo poderia ser se você tivesse um endereço físico e um atributo (coluna) de endereço para correspondência em uma tabela, com FKs para uma tabela de endereços. Você pode tornar o endereço físico anulável para manipulação quando a entidade tem apenas uma caixa postal (endereço de correspondência) e o endereço de correspondência anulável para manipulação quando o endereço de correspondência é o mesmo que o endereço físico (ou não).
fonte
Somente se você souber melhor do que Chris Date "o que a primeira forma normal realmente significa". Se x e y são anuláveis e, de fato, em alguma linha x e y são ambos
null
, entãoWHERE x=y
não resultatrue
. Isso prova, sem qualquer dúvida razoável, que nulo não é um valor (porque qualquer valor real é sempre igual a si mesmo). E como o RM prescreve que "deve haver um valor em cada célula de uma tabela", qualquer coisa que possivelmente contenha nulos não é uma coisa relacional e, portanto, a questão de 1NF nem mesmo surge.Veja acima a razão sólida subjacente a esse argumento.
Somente se você for imune às dores de cabeça que geralmente causam no resto do mundo. Uma dessas dores de cabeça (e é apenas uma pequena, comparativamente a outros
null
fenômenos) é o fato de queWHERE x=y
em SQL realmente significaWHERE x is not null and y is not null and x=y
, mas a maioria dos programadores simplesmente não está ciente desse fato e apenas o lê. Às vezes sem nenhum dano, outras vezes não.Na verdade, colunas anuláveis violam uma das regras de design de banco de dados mais fundamentais: não combine elementos de informação distintos em uma coluna. Os nulos fazem exatamente isso porque combinam o valor booleano "este campo está / não está realmente presente" com o valor real.
fonte
Não consigo ver nada de errado nisso, é apenas um relacionamento n-1 opcional que será representado com um nulo na chave estrangeira. Do contrário, se você colocar sua tabela de links, terá que cuidar para que não se torne um relacionamento nn, causando ainda mais problemas.
fonte
Relacionamentos opcionais são definitivamente possíveis no modelo relacional.
Você pode usar nulos para expressar a ausência de um relacionamento. Eles são convenientes, mas causarão as mesmas dores de cabeça que os nulos causam em outros lugares. Um lugar onde eles não causam problemas são as junções. As linhas que possuem um valor nulo na chave estrangeira não correspondem a nenhuma linha na tabela referenciada. Então, eles saem de uma junção interna. Se você fizer junções externas, lidará com nulos de qualquer maneira.
Se você realmente deseja evitar nulos (6ª forma normal), você pode decompor a tabela. Uma das duas tabelas decompostas possui duas colunas de chave estrangeira. Uma é a chave estrangeira opcional que você possui e a outra é uma chave estrangeira que faz referência à chave primária da tabela original. Agora você tem que usar restrições para evitar que o relacionamento se torne muitos para muitos, se você quiser evitar isso.
fonte
Usar NULL seria uma boa maneira de limpar pedidos incompletos:
O texto acima mostraria pedidos com mais de 15 minutos sem um ID de cliente relacionado.
fonte
Se você estiver apenas adicionando o pedido temporariamente sem ID de cliente até que um cliente seja definido, não seria mais simples adicionar o cliente e o pedido em uma única transação, removendo assim a necessidade da entrada de chave estrangeira NULL e evitando quaisquer restrições ou gatilhos você configurou ser violado?
Normalmente, essa situação surge em aplicativos web onde o pedido é detalhado antes que o cliente defina quem ele é. E nessas situações o pedido é mantido no estado de servidor ou em um cookie até que todo o estado necessário para um pedido completo seja fornecido, momento em que o pedido é mantido no banco de dados.
Chaves estrangeiras NULL são aceitáveis para coisas como endereços, conforme mencionado acima. Mas um campo de cliente NULL não faz sentido para um pedido e deve ser restrito.
fonte
Você sempre pode adicionar uma linha artificial à sua tabela Customer, algo como Id = -1 e CustomerName = 'Unknown' e, em casos em que você normalmente definiria seu CustomerId em Order NULL, defina-o como -1.
Isso permite que você não tenha FKs anuláveis, mas ainda represente a falta de dados de forma apropriada (e o salvará de usuários downstream que não sabem como lidar com NULLs).
fonte
FKs anuláveis para relações muitos para um opcionais são totalmente aceitáveis.
fonte
Ouvi dizer que as colunas anuláveis em geral quebram o primeiro grau de normalização. Mas na prática é muito prático.
fonte
Sim, há algo errado. Não é uma chave estrangeira se for anulável. Seu banco de dados projetado por código. Talvez você faça um link zero para os não atribuídos. ou "Não atribuído" se estiver usando uma coluna de caractere. Mantenha a integridade de seus dados 100%.
fonte