O uso de várias chaves estrangeiras na mesma coluna no SQL Server
10
O SQL Server me permite criar várias chaves estrangeiras em uma coluna e, sempre que usando um nome diferente, posso criar outra referência de chave para o mesmo objeto. Basicamente, todas as chaves estão definindo o mesmo relacionamento. Quero saber para que serve ter várias chaves estrangeiras definidas na mesma coluna e fazer referência à mesma coluna em outra tabela. Qual é o benefício do SQL Server nos permitir fazer algo assim?
Não há benefício em ter restrições redundantes que diferem apenas pelo nome. Da mesma forma, não há benefício em ter índices redundantes que diferem apenas pelo nome. Ambos adicionam sobrecarga sem valor.
O mecanismo de banco de dados do SQL Server não impede que você faça isso. Uma boa nomeação de restrições As convenções de nomenclatura de restrições (por exemplo, FK_ReferencingTable_ReferencedTable) podem ajudar a proteger alguém contra esses erros.
O SQL Server permite que você faça muitas coisas tolas.
Você pode até criar uma chave estrangeira em uma coluna que faz referência a si mesma - apesar do fato de que isso nunca pode ser violado, pois todas as linhas atendem à restrição em si mesmas.
Um caso extremo em que a capacidade de criar duas chaves estrangeiras no mesmo relacionamento seria potencialmente útil é porque o índice usado para validar chaves estrangeiras é determinado no momento da criação. Se um índice melhor (ou seja, mais estreito) aparecer mais tarde, isso permitirá que uma nova restrição de chave estrangeira seja criada vinculada ao melhor índice e, em seguida, a restrição original será eliminada sem que haja nenhuma lacuna sem restrição ativa.
(Como no exemplo abaixo)
CREATETABLE T1(
T1_Id INT PRIMARYKEYCLUSTEREDNOTNULL,
Filler CHAR(4000)NULL,)INSERTINTO T1 VALUES(1,'');CREATETABLE T2(
T2_Id INT IDENTITY(1,1)PRIMARYKEYNOTNULL,
T1_Id INT NOTNULLCONSTRAINT FK REFERENCES T1 (T1_Id),
Filler CHAR(4000)NULL,)ALTERTABLE T1 ADDCONSTRAINT
UQ_T1 UNIQUENONCLUSTERED(T1_Id)/*Execution Plan uses clustered index*/INSERTINTO T2 VALUES(1,1)ALTERTABLE T2 WITHCHECKADDCONSTRAINT FK2 FOREIGNKEY(T1_Id)REFERENCES T1 (T1_Id)ALTERTABLE T2 DROPCONSTRAINT FK/*Now Execution Plan now uses non clustered index*/INSERTINTO T2 VALUES(1,1)DROPTABLE T2, T1;
Como um aparte para o período intermediário, enquanto ambas as restrições existem, quaisquer inserções acabam sendo validadas nos dois índices.
Uma transação poderia ser usada para garantir a mesma atualização de restrição contínua? Esse método de não transação é melhor devido a menos bloqueio, talvez?
binki 29/03
13
Não há utilidade em ter restrições de chave estrangeira idênticas., Que estão nas mesmas colunas e referenciam as mesmas tabelas e colunas.
-Não concordo. Pode haver uma chance de que a tabela principal precise de duas verificações separadas. Veja abaixo o exemplo remetente e destinatário são totalmente diferentes - stackoverflow.com/questions/40400483/…
trex
@exex você está falando de algo diferente. A pergunta aqui afirma: "Quero saber de que serve ter várias chaves estrangeiras definidas na mesma coluna e fazer referência à mesma coluna em outra tabela ".
ypercubeᵀᴹ
@ ypercubeᵀᴹ - Entendi. Obrigado por deixar claro
trex 14/02
6
Pelo mesmo motivo, você pode criar 50 índices na mesma coluna, adicionar um segundo arquivo de log, definir a memória máxima do servidor para 20 MB ... a maioria das pessoas não faz essas coisas, mas pode haver razões legítimas para fazê-las ocasionalmente, portanto não há benefício na criação de sobrecarga no mecanismo para adicionar verificações contra coisas que são meramente desaconselhadas.
Quando você começa a mudar de azul para verde, é necessário criar temporariamente cópias extras das coisas.
O que queremos fazer é criar temporariamente uma chave estrangeira extra CHECK WITH NOCHECKe ON UPDATE CASCADE ON DELETE SET NULL; o que isso faz é que é uma chave estrangeira ativa, mas as linhas existentes não são verificadas quando a chave é criada.
Mais tarde, depois de limpar todas as linhas que devem corresponder, criaríamos a nova chave estrangeira sem nenhuma opção de comando (o padrão é o CHECK WITH CHECKque você normalmente deseja) e soltar a chave estrangeira temporária.
Observe que, se você soltar e recriar a chave estrangeira, algumas linhas de lixo poderão passar despercebidas por você.
Não há utilidade em ter restrições de chave estrangeira idênticas., Que estão nas mesmas colunas e referenciam as mesmas tabelas e colunas.
É como ter o mesmo cheque 2 ou mais vezes.
fonte
Pelo mesmo motivo, você pode criar 50 índices na mesma coluna, adicionar um segundo arquivo de log, definir a memória máxima do servidor para 20 MB ... a maioria das pessoas não faz essas coisas, mas pode haver razões legítimas para fazê-las ocasionalmente, portanto não há benefício na criação de sobrecarga no mecanismo para adicionar verificações contra coisas que são meramente desaconselhadas.
fonte
Soa como uma coisa verde-azulada.
Quando você começa a mudar de azul para verde, é necessário criar temporariamente cópias extras das coisas.
O que queremos fazer é criar temporariamente uma chave estrangeira extra
CHECK WITH NOCHECK
eON UPDATE CASCADE ON DELETE SET NULL
; o que isso faz é que é uma chave estrangeira ativa, mas as linhas existentes não são verificadas quando a chave é criada.Mais tarde, depois de limpar todas as linhas que devem corresponder, criaríamos a nova chave estrangeira sem nenhuma opção de comando (o padrão é o
CHECK WITH CHECK
que você normalmente deseja) e soltar a chave estrangeira temporária.Observe que, se você soltar e recriar a chave estrangeira, algumas linhas de lixo poderão passar despercebidas por você.
fonte