É aceitável ter uma referência circular entre duas tabelas no campo de chave estrangeira?
Caso contrário, como essas situações podem ser evitadas?
Se sim, como os dados podem ser inseridos?
Abaixo está um exemplo de onde (na minha opinião) uma referência circular seria aceitável:
CREATE TABLE Account
(
ID INT PRIMARY KEY IDENTITY,
Name VARCHAR(50)
)
CREATE TABLE Contact
(
ID INT PRIMARY KEY IDENTITY,
Name VARCHAR(50),
AccountID INT FOREIGN KEY REFERENCES Account(ID)
)
ALTER TABLE Account ADD PrimaryContactID INT FOREIGN KEY REFERENCES Contact(ID)
database-design
foreign-key
rdbms
KidCode
fonte
fonte
Respostas:
Como você está usando campos anuláveis para as chaves estrangeiras, é possível construir um sistema que funcione corretamente da maneira que você o imagina. Para inserir linhas na tabela Contas, você precisa ter uma linha presente na tabela Contatos, a menos que permita inserções nas Contas com um PrimaryContactID nulo. Para criar uma linha de contato sem já ter uma linha de Conta presente, você deve permitir que a coluna Código da Conta na tabela Contatos seja anulável. Isso permite que as contas não tenham contatos e permite que os contatos não tenham conta. Talvez isso seja desejável, talvez não.
Dito isto, minha preferência pessoal seria ter a seguinte configuração:
Isso fornece a capacidade de:
IX_AccountsContactsXRef_Primary
índice. Este índice contém um filtro, portanto, ele funcionará apenas em plataformas que os suportem. Como esse índice é especificado com aUNIQUE
opção, só pode haver um único contato principal para cada conta.Por exemplo, se você deseja exibir uma lista de todos os contatos, com uma coluna indicando o status "primário", mostrando os contatos principais no topo da lista de cada conta, você pode:
O índice filtrado impede a inserção de mais de um único contato principal por conta, ao mesmo tempo em que fornece um método rápido de retornar uma lista de contatos principais. Pode-se imaginar facilmente outra coluna,
IsActive
com um índice filtrado não exclusivo para manter um histórico de contatos por conta, mesmo depois que esse contato não estiver mais associado à conta:fonte
Não, não é aceitável ter referências circulares de chaves estrangeiras. Não apenas porque seria impossível inserir dados sem eliminar e recriar constantemente a restrição. mas porque é um modelo fundamentalmente defeituoso de todo e qualquer domínio em que posso pensar. No seu exemplo, não consigo pensar em nenhum domínio no qual o relacionamento entre Conta e Contato não seja NN, exigindo uma tabela de junção com referências FK de volta para Conta e Contato.
fonte
Você pode fazer com que seu objeto externo aponte para o contato principal e não para a conta. Seus dados ficariam assim:
fonte