Eu tenho uma tabela que contém dados e uma dessas linhas precisa existir em outra tabela. Então, eu quero uma chave estrangeira para manter a integridade referencial.
CREATE TABLE table1
(
ID INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
AnotherID INT NOT NULL,
SomeData VARCHAR(100) NOT NULL
)
CREATE TABLE table2
(
ID INT NOT NULL IDENTITY(1,1) PRIMARY KEY,
AnotherID INT NOT NULL,
MoreData VARCHAR(30) NOT NULL,
CONSTRAINT fk_table2_table1 FOREIGN KEY (AnotherID) REFERENCES table1 (AnotherID)
)
No entanto, como você pode ver, a chave estrangeira da tabela para a qual a coluna não é o PK. Existe uma maneira de criar essa chave estrangeira ou talvez uma maneira melhor de manter essa integridade referencial?
sql
sql-server
Craig
fonte
fonte
table1.ID
?Respostas:
Se você realmente deseja criar uma chave estrangeira para uma chave não primária, DEVE ser uma coluna que tenha uma restrição exclusiva.
Dos Livros Online :
Portanto, no seu caso, se você criar um modelo
AnotherID
exclusivo, será permitido. Se você não pode aplicar uma restrição única, está sem sorte, mas isso realmente faz sentido se você pensar sobre isso.Embora, como mencionado, se você possui uma chave primária perfeitamente boa como chave candidata, por que não usá-la?
fonte
Como outros já apontaram, idealmente, a chave estrangeira seria criada como referência a uma chave primária (geralmente uma coluna IDENTITY). No entanto, não vivemos em um mundo ideal e, às vezes, mesmo uma mudança "pequena" em um esquema pode ter efeitos significativos na lógica da aplicação.
Considere o caso de uma tabela Customer com uma coluna SSN (e uma chave primária burra) e uma tabela de declaração que também contém uma coluna SSN (preenchida pela lógica de negócios a partir dos dados do Cliente, mas não existe FK). O design é falho, mas está em uso há vários anos, e três aplicativos diferentes foram criados no esquema. Deveria ser óbvio que extrair o Claim.SSN e estabelecer um relacionamento PK-FK real seria o ideal, mas também seria uma revisão significativa . Por outro lado, colocar uma restrição ÚNICA no Customer.SSN e adicionar um FK no Claim.SSN pode fornecer integridade referencial, com pouco ou nenhum impacto nos aplicativos.
Não me interpretem mal, sou a favor da normalização, mas às vezes o pragmatismo vence o idealismo. Se um desenho medíocre puder ser ajudado com um curativo, a cirurgia poderá ser evitada.
fonte
Necromante.
Suponho que quando alguém chega aqui, ele precisa de uma chave estrangeira para coluna em uma tabela que contém chaves não exclusivas.
O problema é que, se você tiver esse problema, o esquema do banco de dados será desnormalizado.
Você está, por exemplo, mantendo salas em uma tabela, com uma chave primária de espaço em disco, um campo DateFrom e DateTo e outro campo, aqui RM_ApertureID para acompanhar a mesma sala e um campo de exclusão suave, como RM_Status, onde 99 significa 'excluído' e <> 99 significa 'ativo'.
Portanto, quando você cria a primeira sala, insira RM_UID e RM_ApertureID como o mesmo valor que RM_UID. Em seguida, quando você encerra a sala em uma data e a restabelece com um novo período, RM_UID é newid () e o RM_ApertureID da entrada anterior se torna o novo RM_ApertureID.
Portanto, se for esse o caso, RM_ApertureID é um campo não exclusivo e, portanto, você não pode definir uma chave estrangeira em outra tabela.
E não há como definir uma chave estrangeira para uma coluna / índice não exclusivo, por exemplo, em T_ZO_REM_AP_Raum_Reinigung (WHERE RM_UID é realmente RM_ApertureID).
Mas para proibir valores inválidos, é necessário definir uma chave estrangeira, caso contrário, o lixo de dados é o resultado mais cedo ou mais tarde ...
Agora, o que você pode fazer neste caso (exceto reescrever o aplicativo inteiro) é inserir uma restrição CHECK, com uma função escalar que verifica a presença da chave:
fonte
As chaves primárias sempre precisam ser exclusivas, as chaves estrangeiras precisam permitir valores não exclusivos se a tabela for um relacionamento um para muitos. É perfeitamente bom usar uma chave estrangeira como chave primária se a tabela estiver conectada por um relacionamento um para um, não um para um para muitos.
Uma restrição FOREIGN KEY não precisa ser vinculada apenas a uma restrição PRIMARY KEY em outra tabela; também pode ser definido para referenciar as colunas de uma restrição UNIQUE em outra tabela.
fonte