Como projetar esse banco de dados para evitar dependência cíclica?


12

Existem duas tabelas:

  1. Do utilizador
  2. Endereço

O usuário contém uma referência ao endereço.

Endereço contém as colunas CreatedBy e ModifiedBy, que são referência ao usuário.

Como faço para projetar esse banco de dados para evitar uma dependência cíclica?


4
Você tem certeza de que ModifiedBy não é uma referência ao usuário do banco de dados que fez a alteração, e não ao usuário de aplicativos (que residiria na tabela Usuário)? De qualquer maneira, isso realmente não importa. Não vejo por que há um problema real?
— Philᵀᴹ

Qual deles será criado primeiro. Como CreatedBy e Modifiedby são dados obrigatórios. E a tabela do usuário não deve ter o endereço como nulo. Problema com ovo de galinha. Como eu resolver isso criando um novo UserAddress tabela que contém a referência para ID do usuário e AddressID
— Shashi

2
Você sempre pode usar restrições adiadas se o seu DBMS as suportar.
— Colin 'Hart

Nota: O modelo relacional suporta duas inserções ou atualizações como uma operação atômica, é uma pena que isso não seja suportado no SQL (como restrições adiadas - mesmo que eu as tenha sugerido - são bastante horríveis).
— Colin 'Hart

Respostas:


7

Em vez de procurar dicas e truques (restrições adiadas incluídas), eu sugeriria que você simplesmente desenhasse esse "bloqueio de referência" - então tente algo como isto:


Fatos

  • Usuário(UserID) existe.
  • O endereço(AddressID) foi criado pelo usuário(UserID) .
  • O endereço(AddressID) foi criado em Data(DateCreated) .
  • O endereço(AddressID) foi modificado pela última vez pelo usuário(UserID) na data(ModifiedOn) .
  • O usuário(UserID) reside em Endereço(AddressID) desde a Data(ValidFrom) .

Restrições

  • Each O endereço foi criado pelo exactly one usuário . It is possible that more than one O endereço foi criado pelo the same usuário .

  • Each O endereço foi criado em exactly one Data . It is possible that more than one O endereço foi criado em the same Data .

  • For each and Data do endereço , o that endereço foi modificado pelo at most one usuário na that data .

  • For each and Data do Usuário , o that Usuário reside em at most one Endereço desde a that Data .


Lógico

insira a descrição da imagem aqui


No que diz respeito ao endereço obrigatório, verifique se, na camada do aplicativo, envolva as instruções de carregamento em uma transação - para que você obtenha tudo ou nada.


5

Você não tem opção a não ser criar a dependência cíclica em 2 operações, como abaixo, porque uma tabela não existe quando você cria a primeira.

CREATE TABLE A (A_ID INT PRIMARY KEY, B_FK INT);
CREATE TABLE B (B_ID INT PRIMARY KEY, A_FK INT REFERENCES A(A_ID));

ALTER TABLE A ADD B_FK INT;

Se você deseja evitar dependência cíclica. Em seguida, é necessário remover uma restrição de REFERENCES ou adicionar uma referência DELETE e UPDATE CASCADE de uma maneira. Você também pode implementar um TRIGGER se sua lógica for um pouco complexa.


1
A remoção das restrições remove a dependência cíclica da definição, mas não do design. Você pode adicionar uma tabela de eventos para registrar o UserID e o AddressID que criaram ou modificaram o endereço pela última vez, mas isso apenas move a dependência um passo adiante. Indo de outra maneira, se a tabela Usuário tivesse colunas CreatedBy e ModifiedBy, a dependência cíclica existiria em uma tabela. Isso é semelhante a uma tabela de funcionários com uma coluna de supervisor em que o supervisor também é um funcionário. Como Phil indicou - Não há problema.
— Leigh Riffel

@LeighRiffel, eu concordo. Mas a tabela Eventos que você propõe remove realmente todas as dependências cíclicas.
— ypercubeᵀᴹ

@ypercube De fato, sim; não sei como consegui atravessar esse fio. Para ficar claro, você provavelmente não deve criar uma tabela de Eventos, embora remova a dependência cíclica.
— Leigh Riffel

De qualquer forma, acho que essa resposta não resolve o problema. A questão (eu acho) é sobre como evitar o caminho cíclico, e não como criar os FKs com o caminho cíclico em primeiro lugar.
— ypercubeᵀᴹ
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.