Por que uma tabela usaria sua chave primária como uma chave estrangeira para si mesma

21

Examinando um banco de dados, deparei-me com uma tabela que usava sua chave primária como uma chave estrangeira para si mesma.

Vi que uma tabela pode ter uma chave estrangeira para criar uma estrutura hierárquica, mas usaria outra coluna para fazer referência à chave primária.

Como a chave primária é única, nessa situação a linha não seria capaz de apontar de volta para si mesma? Isso parece ser um elo tautológico, pois se eu já tenho a linha, então já a tenho.

Existe alguma razão para isso ser feito?

Tabela unida a si mesma

Estou certo de que a restrição está escrita dessa maneira (não apenas olhando para o diagrama) porque a mesma tabela e coluna são usadas para as duas metades da definição.

Aaroninus
fonte
6
Provavelmente, através do uso do designer pela mão cack, está a minha teoria #
Martin Smith

Respostas:

28

Como você disse. Uma FOREIGN KEYrestrição que faz referência à mesma tabela geralmente é para uma estrutura hierárquica e usaria outra coluna para fazer referência à chave primária. Um bom exemplo é uma tabela de funcionários:

EmployeeId    Int     Primary Key
EmployeeName  String
ManagerId     Int     Foreign key going back to the EmployeeId

Portanto, neste caso, há uma chave estrangeira da tabela de volta para si mesma. Todos os gerentes também são funcionários; portanto, esse ManagerIdé realmente o EmployeeIddo gerente.

Agora, por outro lado, se você quer dizer que alguém usou a EmployeeIdchave estrangeira na tabela Employee , provavelmente foi um erro . Fiz um teste e é possível, mas não teria nenhum uso real.

CREATE TABLE Employee (EmployeeId Int PRIMARY KEY,
                        EmployeeName varchar(50),
                        ManagerId Int);


ALTER TABLE Employee ADD CONSTRAINT fk_employee 
    FOREIGN KEY (EmployeeId) REFERENCES Employee(EmployeeId);
Kenneth Fisher
fonte
1
A colocação de uma restrição no ManagerId relacionada ao EmployeeId nesse caso pode ser benéfica se o gerente for "separado". Não permitiria a exclusão da linha se configurada dessa maneira. Não estou dizendo que eu faria dessa maneira, mas poderia ter algum benefício se o seu aplicativo dependesse de funcionários com gerentes.
Zgr024
6

Acabei de encontrar uma chave estrangeira no meu próprio banco de dados e deve ter sido eu mesma criando-a. Eu acho que isso aconteceu por acidente. Se eu clicar em "Nova chave estrangeira" no menu de contexto de uma tabela com chave primária (no Management Studio, SQL 2014 Express), isso já criará automaticamente uma chave estrangeira referente a si mesma. Ver abaixo:

insira a descrição da imagem aqui

Se eu não perceber que devo alterá-lo em vez de adicionar um novo, ele permanecerá lá. Ou, se eu simplesmente clicar no botão [Fechar], o que significa que seria como um [Cancelar], a chave estrangeira ainda será criada após salvar a definição da tabela.

Então, para mim, uma chave estrangeira não faz sentido e pode ser removida.

Stefan Müller
fonte
É possível que você queira criar um FK e, no processo, perceba que a outra tabela ainda não definiu seu PK, portanto, cancele, vá para a outra tabela e, por algum motivo, esqueça de continuar com o processo FK. Lá você tem seu FK recursivo.
Andrew
4

Talvez o designer quisesse desativar o uso de TRUNCATE TABLE?

TRUNCATE TABLEnão pode ser usado em uma tabela com restrição de chave estrangeira para outra tabela, embora possa ser usado se houver chaves estrangeiras autorreferenciais . Na documentação para TRUNCATE TABLE (Transact-SQL) :

Extrato de BOL

Uma DELETEinstrução sem uma WHEREcláusula tem um efeito semelhante a TRUNCATE TABLE(removendo todas as linhas da tabela), mas a DELETEinstrução aciona os gatilhos de exclusão, o que pode ser um motivo para permitirDELETE mas não TRUNCATE TABLE.

Eu faria isso usando permissões ( DELETErequer permissão para excluir, TRUNCATE TABLErequer permissão para alterar a tabela), mas talvez haja algum motivo pelo qual o designer não possa fazer isso?

Nota: Embora o que o designer tenha feito realmente não desabilite o uso TRUNCATE TABLE, ainda estou especulando que essa era a intenção deles.

Andarilho de Pedra Verde
fonte