Database
 sql >> Base de Dados >  >> RDS >> Database

SQL FOREIGN KEY CONSTRAINT:O guia definitivo e fácil para iniciantes


Novato? Então uma chave estrangeira SQL pode ser estrangeira para você.

Você pode ter ouvido opiniões diferentes sobre chaves estrangeiras SQL. Se não tiver, em breve terá. Ou sua experiência afetará sua visão. A principal coisa a saber é que as chaves estrangeiras são obrigatórias em bancos de dados relacionais.

No entanto, alguns desenvolvedores podem remover ou ignorar chaves estrangeiras ao enfrentar algumas complicações. Então o que fazer? Usar a chave estrangeira ou não usá-la? Haverá momentos em que você não precisará usá-los?

Este guia é para você ver como isso é importante. Você também conhecerá algumas armadilhas no código e aprenderá como corrigi-las. Além disso, é claro, usaremos exemplos práticos. Não há nada que você não possa lidar.

O que é uma chave estrangeira SQL?


Primeiras coisas primeiro. O que é chave estrangeira no SQL? Em poucas palavras, é uma chave que liga 2 tabelas. Digamos que você tenha uma tabela pai e uma tabela filho. Há alguma semelhança tornando-os pais e filhos – a chave que relaciona essas duas tabelas.

No entanto, em bancos de dados SQL, uma chave estrangeira não se relaciona apenas a tabelas. Isso reforça o relacionamento. É por isso que é chamado de restrição de chave estrangeira.

Ocorrerá um erro se você tentar adicionar um registro filho com um valor de chave estrangeira que não existe nas chaves primárias da tabela pai. Mais tarde, veremos exemplos de código ilustrando isso.

Quais tabelas devem ter restrições de chave estrangeira SQL?


As tabelas filhas podem ter chaves estrangeiras. Uma chave estrangeira pode estar referenciando outra tabela. Além disso, pode haver várias chaves estrangeiras em uma tabela “filho”. No SQL Server, a chave estrangeira pode referenciar uma chave primária ou uma chave exclusiva em outra tabela.

E quanto à auto-referência?


Isso sai da definição geral de uma chave estrangeira. Uma auto-referência significa que você pode atribuir uma chave estrangeira que referências uma coluna diferente na mesma tabela . SQL Server, MySQL e Oracle suportam isso.

A auto-referência é aplicável quando você deseja criar hierarquias como a relação gerente-equipe. É permitido, ainda, que a maioria das implementações de chaves estrangeiras estejam entre 2 tabelas.

Mais tarde, teremos exemplos.

4 Benefícios do uso de chaves estrangeiras SQL


Vamos explorar a chave primária e a chave estrangeira em SQL em detalhes. O que torna as chaves estrangeiras obrigatórias para um banco de dados SQL? Vamos examinar 4 pontos (aqui, a sintaxe de restrição não importa).

1. Evite dados “ausentes”


Dados “ausentes” são valores de chave estrangeira de tabelas filhas sem valores de chave primária associados da tabela pai. Eles também são chamados de linhas órfãs. Quando isso acontece, podemos dizer que o banco de dados tem pouca ou nenhuma integridade referencial.

Com as restrições de chave estrangeira aplicadas, os dados “ausentes” não acontecerão. O mecanismo de banco de dados não permitirá a exclusão de um valor de chave primária referenciado por outra tabela. Da mesma forma, a inserção de uma chave estrangeira na tabela filho que não existe nas chaves primárias da tabela pai acionará um erro.

Qual é a pior coisa que pode acontecer se você não usar as restrições de chave estrangeira? Aqui estão alguns:
  • Os clientes não receberão os produtos pelos quais pagaram.
  • O tratamento não é administrado aos pacientes.
  • As listas de verificação ausentes ignoram as precauções de segurança.

Você pode lidar com essas coisas fora do banco de dados, mas precisa codificá-las. Mais sobre isso seguirá.

Digamos que um desenvolvedor em sua organização tenha lidado com a mesma restrição fora do banco de dados. Ele será responsável e corrigirá o problema na produção se o código falhar? Eu não acho. E se você for o administrador do banco de dados? Então, você terá que limpar a bagunça deles. Não é tão encorajador se você me perguntar.

2. Evite relatórios inconsistentes


Relaciona-se com o primeiro ponto. Se alguns dados estiverem “faltando”, totais inconsistentes aparecem em relatórios diferentes. Os detalhes não correspondem aos resumos. As linhas órfãs somam os totais dos resumos. Enquanto isso, o relatório detalhado não capturou linhas órfãs devido a uma junção interna nas tabelas pai.

Se for seu trabalho manter seu banco de dados em boas condições, você também limpará essa bagunça.

3. Nenhum código necessário para evitar linhas órfãs


As restrições de chave estrangeira agem como agentes autolimpantes. Em vez de você limpar a bagunça, o banco de dados faz isso não permitindo linhas órfãs. As restrições de chave estrangeira também atuam como polícia. Eles prendem a lógica defeituosa que causa linhas órfãs, tratando-as como um crime cometido fora do banco de dados.

Você quer um banco de dados brilhante livre de linhas órfãs? Claro que você faz. Se você quiser analisar os dados algum dia, ficará feliz por ter usado chaves estrangeiras. Este banco de dados será uma boa fonte para copiar os dados necessários para sua área de teste.

4. Entenda rapidamente os relacionamentos de tabela em um diagrama


O SQL Server Management Studio tem uma ferramenta de diagramação interna para seu banco de dados. As chaves primárias e estrangeiras tornam o diagrama de banco de dados informativo à primeira vista. No entanto, dependerá de quantas tabelas com relacionamentos você incluiu no diagrama.

Os diagramas ajudam os novos membros da equipe a entender a estrutura de dados. Para colegas de equipe sênior, pode ser útil também como documentação.

Quando a chave estrangeira do SQL pode ser um “problema” (mais a correção)


Para migrar dados antigos para um novo banco de dados, você inserirá registros em massa. Se o banco de dados de origem tiver baixa integridade referencial, será difícil inserir registros da origem. A razão é que os erros de chave estrangeira aparecem aqui e ali.

Existe uma correção? Você tem 2 opções.
  1. Certifique-se de preencher primeiro as tabelas de referência ou as tabelas pai. Depois disso, preencha as tabelas filhas. Uma complicação está sendo muito lenta. Em outros casos, ocorrem mais erros de restrição de chave estrangeira. Se o último caso ocorrer, você precisará reavaliar a sequência de inserções e garantir que as chaves primárias sejam inseridas primeiro. Se houver um problema de "execução lenta", considere a próxima opção.
  2. Desative as chaves estrangeiras temporariamente e ative-as após a conclusão da migração (e limpeza). Você pode fazer isso no SQL Server Management Studio ou usar T-SQL ALTER TABLE. No entanto, é mais fácil falar do que fazer. Neste ponto, você precisa de mais paciência, além de sua inteligência e força de vontade. Mais tarde, encontraremos a sintaxe para desativar e reativar chaves estrangeiras.

Outra coisa a considerar é usar um banco de dados como uma área de teste para OLAP ou análise de dados. Suponha que o banco de dados transacional de origem esteja limpo de linhas órfãs. Ou você pode evitar essas linhas por meio do código. Então você pode optar por não usar chaves estrangeiras. Chaves estrangeiras retardarão inserções e atualizações em massa, especialmente em conjuntos de dados gigantescos.

3 maneiras fáceis de adicionar, editar e excluir restrições de chave estrangeira SQL


O que é necessário para adicionar, editar ou excluir chaves estrangeiras? É fácil com essas 3 dicas.

As duas primeiras etapas usam uma interface gráfica do usuário. Ferramentas como SQL Server Management Studio ou dbForge Studio for SQL Server são ótimas candidatas. O terceiro usará o código T-SQL. A escolha de um código GUI ou T-SQL depende da situação.

1. Usando o Table Designer para adicionar, editar e excluir restrição de chave estrangeira do SQL


É possível no SQL adicionar restrições de chave estrangeira ao criar ou alterar uma estrutura de tabela usando o Designer de tabela em SSMS. A Figura 1 abaixo mostra como acessá-lo a partir do menu principal quando a estrutura da tabela está aberta.

Outra opção é clicar com o botão direito do mouse em qualquer lugar do designer de tabela e selecionar Relacionamentos no menu de contexto:

Depois de selecionar Relacionamentos , os Relacionamentos de Chave Estrangeira janela irá aparecer:

Nas Relações de chave estrangeira janela, você pode optar por adicionar uma nova chave estrangeira ou editar/excluir uma existente.

Se você optar por adicionar ou editar, clique para expandir as Tabelas e Colunas Especificações. Em seguida, clique nas reticências botão para definir ou editar as tabelas de chave primária e estrangeira.

A partir daí, você pode indicar as colunas de chave primária e estrangeira.

Após definir as chaves primária e estrangeira, clique em OK . Em seguida, navegue de volta ao designer de tabela e salve as alterações.

2. Usando o diagrama de banco de dados para adicionar, editar e excluir restrição de chave estrangeira do SQL


Você pode usar o Diagrama de Banco de Dados para criar restrições de chave estrangeira SQL. A Figura 5 mostra como criar um relacionamento entre duas tabelas clicando na tabela de chave estrangeira e arrastando-a para a tabela de chave primária.

Ao soltar o mouse, as Tabelas e Colunas irá aparecer como a da Figura 4. Então você pode indicar as colunas de chave primária e estrangeira. Em seguida, clique em OK.

Para editar um relacionamento existente, clique com o botão direito do mouse em um relacionamento no diagrama. Em seguida, selecione Propriedades :

Em seguida, nas Propriedades janela, expanda Tabelas e Colunas e clique nas reticências botão:

Depois de clicar nas reticências botão, o botão Tabelas e Colunas janela aparecerá. Você pode alterar as colunas de chave primária e estrangeira (consulte a Figura 4 acima novamente).

Enquanto isso, excluir um relacionamento requer clicar com o botão direito do mouse em um existente relação. Selecione Excluir relacionamentos do banco de dados e clique em Sim quando solicitado.

3. Usando T-SQL para adicionar, editar e excluir restrição de chave estrangeira SQL


A terceira maneira de adicionar uma chave estrangeira é por meio do código T-SQL. Você pode usar SQL CREATE TABLE e adicionar a restrição de chave estrangeira. Ou você também pode usar ALTER TABLE para adicionar essa restrição após criar a tabela.

Aqui está a sintaxe para usar CREATE TABLE:
-- Single-column foreign key
CREATE TABLE Table2
(ID INT IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED,
 col1 INT NULL REFERENCES Table1(col1)
)
GO

Depois de definir o nome e o tipo da coluna, você pode adicionar REFERENCES a uma tabela e coluna. A sintaxe acima mostra a Tabela1 tabela na col1 coluna. Observe que os nomes das colunas em ambas as tabelas devem ser os mesmos para serem válidos para chaves estrangeiras.

A sintaxe acima é para chaves estrangeiras de coluna única. Se você precisar de várias colunas como chaves estrangeiras, use a cláusula FOREIGN KEY conforme abaixo:
-- Multiple-column foreign key
CREATE TABLE Table2
(ID INT IDENTITY(1,1) NOT NULL PRIMARY KEY CLUSTERED,
 col1 INT NOT NULL,
 col2 INT NOT NULL,
 col3 VARCHAR(10) NULL
 CONSTRAINT FK_Table1_Table2 FOREIGN KEY(col1, col2)
	REFERENCES Table1(col1,col2)
)
GO

Depois de criar a tabela, você pode adicionar chaves estrangeiras usando ALTER TABLE. Aqui está a sintaxe:
ALTER TABLE Table2 WITH CHECK ADD CONSTRAINT FK_Table1_Table2_2 FOREIGN KEY(col3)
	REFERENCES Table3(col1)
GO

Para excluir uma restrição de chave estrangeira, você pode usar ALTER TABLE com DROP CONSTRAINT:
ALTER TABLE Table2 
DROP CONSTRAINT FK_Table1_Table2_2
GO

Agora, podemos resumir 3 maneiras de adicionar, editar e excluir chaves estrangeiras:

Exemplos de restrição de chave estrangeira SQL (MySQL)

Tabela filha com 1 referência a uma tabela pai

-- Single Reference
CREATE TABLE [dbo].[Countries](
	[CountryID] [int] IDENTITY(1,1) NOT NULL,
	[Country] [nvarchar](50) NOT NULL,
	[ContinentID] [int] NULL,
	[Modified] [datetime] NOT NULL,
 CONSTRAINT [PK_Country] PRIMARY KEY CLUSTERED 
(
	[CountryID] ASC
))
GO

ALTER TABLE [dbo].[Countries]  WITH CHECK ADD CONSTRAINT [FK_Countries_Continent] FOREIGN KEY([ContinentID])
REFERENCES [dbo].[Continent] ([ContinentID])

GO

ALTER TABLE [dbo].[Countries] CHECK CONSTRAINT [FK_Countries_Continent]
GO

Para visualizar essa relação, dê uma olhada na Figura 9 abaixo:

O ContinentID é a chave que relaciona as duas tabelas.

Tabela filha com várias referências


O Carro Esportivo table tem várias referências a três tabelas diferentes:
-- Multiple References
CREATE TABLE [dbo].[SportsCars](
	[SportsCarID] [int] IDENTITY(1,1) NOT NULL,
	[ManufacturerID] [int] NULL,
	[StyleID] [int] NULL,
	[CountryID] [int] NULL,
	[Model] [nvarchar](50) NOT NULL,
	[Years] [varchar](50) NOT NULL,
	[Notes] [varchar](255) NOT NULL,
	[Modified] [datetime] NOT NULL,
 CONSTRAINT [PK_SportsCars] PRIMARY KEY CLUSTERED 
(
	[SportsCarID] ASC
))
GO

ALTER TABLE [dbo].[SportsCars] WITH CHECK ADD CONSTRAINT [FK_SportsCars_Country] FOREIGN KEY([CountryID])
REFERENCES [dbo].[Countries] ([CountryID])
GO

ALTER TABLE [dbo].[SportsCars] CHECK CONSTRAINT [FK_SportsCars_Country]
GO

ALTER TABLE [dbo].[SportsCars] WITH CHECK ADD CONSTRAINT [FK_SportsCars_Manufacturer] FOREIGN KEY([ManufacturerID])
REFERENCES [dbo].[Manufacturers] ([ManufacturerID])
GO

ALTER TABLE [dbo].[SportsCars] CHECK CONSTRAINT [FK_SportsCars_Manufacturer]
GO

ALTER TABLE [dbo].[SportsCars] WITH CHECK ADD CONSTRAINT [FK_SportsCars_Styles] FOREIGN KEY([StyleID])
REFERENCES [dbo].[Styles] ([StyleID])
GO

ALTER TABLE [dbo].[SportsCars] CHECK CONSTRAINT [FK_SportsCars_Styles]
GO

Aqui está como ele aparece em um diagrama de banco de dados:

Auto-referência


As hierarquias de posição mostram a auto-referência na tabela a seguir:
CREATE TABLE [dbo].[Ranks](
	[RankId] [int] IDENTITY(1,1) NOT NULL,
	[Rank] [varchar](50) NOT NULL,
	[RankLevel] [smallint] NOT NULL,
	[RankParentId] [int] NULL,
 CONSTRAINT [PK_Ranks] PRIMARY KEY CLUSTERED 
(
	[RankId] ASC
)) ON [PRIMARY]
GO

ALTER TABLE [dbo].[Ranks] WITH CHECK ADD CONSTRAINT [FK_Ranks_Ranks] FOREIGN KEY([RankParentId])
REFERENCES [dbo].[Ranks] ([RankId])
GO

ALTER TABLE [dbo].[Ranks] CHECK CONSTRAINT [FK_Ranks_Ranks]
GO

O diagrama desta auto-referência é simples. A linha aponta para a mesma tabela em auto-referência.

Com ATUALIZAÇÃO e APAGAR


Com ON UPDATE CASCADE, atualizar um valor de coluna de chave primária também atualizará os valores de chave estrangeira nas tabelas relacionadas. Enquanto isso, quando você usa ON DELETE CASCADE, excluir uma chave primária também excluirá chaves estrangeiras. O padrão para ON UPDATE e ON DELETE é SEM AÇÃO.

Aqui está um exemplo de UPDATE e DELETE CASCADE:
ALTER TABLE [dbo].[Countries] WITH CHECK ADD CONSTRAINT [FK_Countries_Continent] FOREIGN KEY([ContinentID])
REFERENCES [dbo].[Continent] ([ContinentID]) 
ON UPDATE CASCADE 
ON DELETE CASCADE
GO

Desativando uma restrição de chave estrangeira SQL


O seguinte irá desabilitar uma restrição de chave estrangeira existente. Observe que a relação ainda existe.
ALTER TABLE [dbo].[SportsCars] NOCHECK CONSTRAINT [FK_SportsCars_Country]
GO

Este não é o padrão e não é recomendado. Mas para acelerar inserções e atualizações em massa, você pode desativar temporariamente a chave estrangeira como a mostrada acima. Depois de terminar, você deve trocá-lo novamente usando CHECK CONSTRAINT.
ALTER TABLE [dbo].[SportsCars] CHECK CONSTRAINT [FK_SportsCars_Country]
GO

Sugestões e correções


Esta seção mostrará o que acontece quando você INSERT, UPDATE ou DELETE registros com chaves estrangeiras. Isso também pressupõe que as chaves estrangeiras não estão desabilitadas com RESTRIÇÃO NOCHECK. Isso irá ajudá-lo quando você encontrar esses problemas comuns.

Em INSERIR

-- This will cause an error because countryID = 47 does not exist in the Countries table
INSERT INTO SportsCars 
(ManufacturerID, StyleID, CountryID, Model, Years, Notes) 
VALUES (108, 10, 47, 'F2', '2021', 'Limited Edition')
GO

Aqui está a mensagem de erro:
Msg 547, Level 16, State 0, Line 56
The INSERT statement conflicted with the FOREIGN KEY constraint "FK_SportsCars_Country". The conflict occurred in database "Vehicles", table "dbo.Countries", column 'CountryID'.
The statement has been terminated.

A correção :Adicionar CountryID =47 nos Países mesa primeiro. Em seguida, execute novamente a instrução INSERT acima. A sequência começa com a inserção de registros na tabela pai e, em seguida, na tabela filho.

Em ATUALIZAÇÃO

-- Update CountryID to 47 will trigger an error.
UPDATE SportsCars
SET CountryID = 47
WHERE ManufacturerID = 108
GO

Aqui está o erro UPDATE:
Msg 547, Level 16, State 0, Line 60
The UPDATE statement conflicted with the FOREIGN KEY constraint "FK_SportsCars_Country". The conflict occurred in database "Vehicles", table "dbo.Countries", column 'CountryID'.
The statement has been terminated.

A correção :Adicionar CountryID =47 nos Países tabela. Em seguida, execute novamente a instrução UPDATE.

Ao EXCLUIR

-- This will trigger an error because ManufacturerID = 108 is referenced in the SportsCars table
DELETE FROM Manufacturers
WHERE ManufacturerID = 108

Este código irá acionar o erro como abaixo:
Msg 547, Level 16, State 0, Line 64
The DELETE statement conflicted with the REFERENCE constraint "FK_SportsCars_Manufacturer". The conflict occurred in database "Vehicles", table "dbo.SportsCars", column 'ManufacturerID'.
The statement has been terminated.

A correção :Excluir os registros correspondentes do SportsCars tabela com ID do fabricante =108. Em seguida, execute novamente a instrução DELETE acima. Outra maneira é habilitar ON DELETE CASCADE se aplicável. A sequência começa com a exclusão de registros das tabelas filhas e, em seguida, da tabela pai.

Recomendações


Então, as chaves estrangeiras ainda são estranhas para você?

Vamos recapitular o que aprendemos até agora.
  • As chaves estrangeiras vinculam duas tabelas (ou uma tabela ao usar a auto-referência). Você precisa deles para garantir a integridade referencial.
  • Você pode usar uma ferramenta GUI ou T-SQL para adicionar, editar ou excluir as restrições de chave estrangeira.
  • Para ferramentas GUI, você pode usar o SQL Server Management Studio ou dbForge Studio para SQL Server. Ambos oferecem diagramas de banco de dados e designers de tabela para criar tabelas com chaves primárias e estrangeiras.
  • CREATE TABLE e ALTER TABLE são adequados para adicionar e excluir as restrições de chave estrangeira.
  • Você pode desabilitar temporariamente chaves estrangeiras com NOCHECK CONSTRAINT em ALTER TABLE. Isso acelerará as inserções e atualizações em massa. Mas certifique-se de habilitá-lo novamente com CHECK CONSTRAINT.
  • Para evitar pegadinhas com chaves estrangeiras, certifique-se de seguir a sequência correta. Para INSERT e UPDATE, insira primeiro na tabela pai e depois nas tabelas filhas. Para DELETE, exclua os registros filho primeiro e, em seguida, exclua os registros pai.

Você gostaria de adicionar algo para ajudar os novatos a dominar as chaves estrangeiras? Os Comentários seção está aberta para suas idéias brilhantes. Se você gostou deste post, compartilhe-o em suas redes sociais favoritas.