Database
 sql >> Database >  >> RDS >> Database

VINCOLO DI CHIAVE STRANIERA SQL:la guida definitiva e facile per i principianti

Novizio? Quindi una chiave esterna SQL potrebbe essere estranea a te.

Potresti aver sentito opinioni diverse sulle chiavi esterne SQL. Se non lo hai fatto, presto lo farai. Oppure la tua esperienza influenzerà la tua vista. La cosa principale da sapere è che le chiavi esterne sono un must nei database relazionali.

Tuttavia, alcuni sviluppatori potrebbero rimuovere o ignorare le chiavi esterne quando devono affrontare alcune complicazioni. Quindi che si fa? Usare la chiave esterna o non usarla? Ci saranno momenti in cui non avrai bisogno di usarli?

Questa guida è per farti vedere quanto sia importante questa cosa. Conoscerai anche alcuni problemi nel codice e imparerai come risolverli. Inoltre, ovviamente, utilizzeremo esempi pratici. Non c'è niente che non puoi gestire.

Cos'è una chiave esterna SQL?

Cominciando dall'inizio. Che cos'è la chiave esterna in SQL? In poche parole, è una chiave che collega 2 tabelle. Supponiamo che tu abbia una tabella padre e una tabella figlio. C'è una certa comunanza che li rende un genitore e un figlio, la chiave che mette in relazione queste 2 tabelle.

Tuttavia, nei database SQL, una chiave esterna non riguarda solo le tabelle. Rafforza la relazione. Ecco perché è chiamato vincolo di chiave esterna.

Si verificherà un errore se si tenta di aggiungere un record figlio con un valore di chiave esterna che non esiste nelle chiavi primarie della tabella padre. Successivamente, vedremo esempi di codice che illustrano questo.

Quali tabelle dovrebbero avere vincoli di chiave esterna SQL?

Le tabelle figlio possono avere chiavi esterne. Una chiave esterna potrebbe fare riferimento a un'altra tabella. Inoltre, possono esserci diverse chiavi esterne in una tabella "figlio". In SQL Server, la chiave esterna può fare riferimento a una chiave primaria oa una chiave univoca in un'altra tabella.

Che ne dici di auto-riferimento?

Questo esce dalla definizione generale di chiave esterna. Un autoriferimento significa che puoi assegnare una chiave esterna a cui fa riferimento una colonna diversa nella stessa tabella . SQL Server, MySQL e Oracle lo supportano.

L'autoriferimento è applicabile quando si desidera creare gerarchie come la relazione manager-personale. È consentito, tuttavia, la maggior parte delle implementazioni di chiavi esterne si trovano tra 2 tabelle.

Più avanti avremo degli esempi.

4 Vantaggi dell'utilizzo di chiavi esterne SQL

Esploriamo in dettaglio la chiave primaria e la chiave esterna in SQL. Cosa rende le chiavi esterne un must per un database SQL? Esaminiamo 4 punti (qui la sintassi del vincolo non ha importanza).

1. Evita i dati "mancanti"

I dati "mancanti" sono valori di chiave esterna da tabelle figlio senza valori di chiave primaria associati dalla tabella padre. Vengono anche dette righe orfane. Quando succede, possiamo dire che il database ha poca o nessuna integrità referenziale.

Con i vincoli di chiave esterna applicati, i dati "mancanti" non si verificheranno affatto. Il motore di database non consentirà l'eliminazione di un valore di chiave primaria a cui fa riferimento un'altra tabella. Allo stesso modo, l'inserimento di una chiave esterna nella tabella figlio che non esiste nelle chiavi primarie della tabella padre attiverà un errore.

Qual è la cosa peggiore che può succedere se non usi i vincoli della chiave esterna? Eccone alcuni:

  • I clienti non riceveranno i prodotti per cui hanno pagato.
  • Il trattamento non viene somministrato ai pazienti.
  • Le liste di controllo mancanti saltano le precauzioni di sicurezza.

Puoi gestire questa roba al di fuori del database, ma devi codificarla. Seguiranno ulteriori informazioni.

Supponiamo che uno sviluppatore della tua organizzazione abbia gestito lo stesso vincolo al di fuori del database. Sarà responsabile e risolverà il problema in produzione se il codice non riesce? Non credo. E se fossi l'amministratore del database? Quindi, dovrai pulire il loro pasticcio. Non così incoraggiante se me lo chiedi.

2. Evita rapporti incoerenti

Riguarda il primo punto. Se alcuni dati sono "mancanti", i totali incoerenti vengono visualizzati in rapporti diversi. I dettagli non corrispondono ai riepiloghi. Le righe orfane si sommano ai totali dei riepiloghi. Nel frattempo, il rapporto dettagliato non ha catturato le righe orfane a causa di un inner join alle tabelle principali.

Se il tuo lavoro è mantenere il tuo database in buone condizioni, pulirai anche questo pasticcio.

3. Nessun codice necessario per evitare righe orfane

I vincoli di chiave esterna agiscono come agenti autopulenti. Invece di pulire il pasticcio, il database lo fa non consentendo righe orfane. I vincoli della chiave esterna fungono anche da polizia. Arrestano la logica errata che causa le righe orfane, trattandolo come un crimine commesso al di fuori del database.

Vuoi un database lucido e privo di righe orfane? Certo, lo fai. Se vuoi analizzare i dati un giorno, saresti felice di aver usato chiavi esterne. Questo database sarà una buona fonte per copiare i dati necessari nella tua area di sosta.

4. Comprendi rapidamente le relazioni tra tabelle in un diagramma

SQL Server Management Studio dispone di uno strumento di creazione di diagrammi integrato per il database. Le chiavi primarie ed esterne rendono il diagramma del database informativo a colpo d'occhio. Tuttavia, dipenderà da quante tabelle con relazioni hai incluso nel diagramma.

I diagrammi aiutano i nuovi membri del team a comprendere la struttura dei dati. Per i compagni di squadra senior, può essere utile anche come documentazione.

Quando la chiave esterna SQL può essere un "problema" (più la correzione)

Per migrare i vecchi dati in un nuovo database, inserirai i record in blocco. Se il database di origine ha una bassa integrità referenziale, sarà difficile inserire i record dall'origine. Il motivo è che gli errori di chiave esterna vengono visualizzati qua e là.

C'è una soluzione? Hai 2 opzioni.

  1. Assicurati di popolare prima le tabelle di riferimento o le tabelle padre. Successivamente, popolare le tabelle figlio. Una complicazione sta funzionando molto lentamente. In altri casi, si verificano più errori di vincolo di chiave esterna. Se si verifica quest'ultimo caso, è necessario rivalutare la sequenza di inserimenti e assicurarsi che le chiavi primarie vengano inserite per prime. Se si verifica un problema di "esecuzione lenta", considera l'opzione successiva.
  2. Disabilita temporaneamente le chiavi esterne e abilitale dopo che la migrazione è stata completata (e pulita). Puoi farlo in SQL Server Management Studio o utilizzare T-SQL ALTER TABLE. Tuttavia, è più facile a dirsi che a farsi. A questo punto, oltre al tuo ingegno e alla tua forza di volontà, hai bisogno di più pazienza. Più avanti troveremo la sintassi per disabilitare e riattivare le chiavi esterne.

Un'altra cosa da considerare è l'utilizzo di un database come area di staging per l'OLAP o l'analisi dei dati. Si supponga che il database transazionale di origine sia pulito dalle righe orfane. Oppure puoi riuscire a evitare queste righe tramite il codice. Quindi puoi scegliere di non utilizzare chiavi esterne. Le chiavi esterne rallenteranno gli inserimenti e gli aggiornamenti in blocco, specialmente su set di dati enormi.

3 semplici modi per aggiungere, modificare ed eliminare i vincoli di chiave esterna SQL

Cosa serve per aggiungere, modificare o eliminare chiavi esterne? È facile con questi 3 suggerimenti.

I primi due passaggi utilizzano un'interfaccia utente grafica. Strumenti come SQL Server Management Studio o dbForge Studio per SQL Server sono ottimi candidati. Il terzo utilizzerà il codice T-SQL. La scelta di un codice GUI o T-SQL dipende dalla situazione.

1. Utilizzo di Progettazione tabelle per aggiungere, modificare ed eliminare il vincolo di chiave esterna SQL

È possibile in SQL aggiungere vincoli di chiave esterna quando si crea o si modifica la struttura di una tabella utilizzando Table Designer in SSMS. La figura 1 di seguito mostra come accedervi dal menu principale quando la struttura della tabella è aperta.

Un'altra opzione consiste nel fare clic con il pulsante destro del mouse in un punto qualsiasi del designer della tabella e selezionare Relazioni dal menu contestuale:

Dopo aver selezionato Relazioni , le relazioni chiave estere si aprirà una finestra:

Nelle relazioni chiave estere finestra, puoi scegliere di aggiungere una nuova chiave esterna o modificarne/eliminarne una esistente.

Se scegli di aggiungere o modificare, fai clic per espandere le Tabelle e colonne Specifiche. Quindi fai clic sui puntini di sospensione pulsante per definire o modificare le tabelle di chiavi primarie ed esterne.

Da lì, puoi indicare le colonne della chiave primaria e della chiave esterna.

Dopo aver definito la chiave primaria ed esterna, fai clic su OK . Quindi torna al designer della tabella e salva le modifiche.

2. Utilizzo del diagramma del database per aggiungere, modificare ed eliminare il vincolo di chiave esterna SQL

È possibile utilizzare il diagramma del database per creare vincoli di chiave esterna SQL. La Figura 5 mostra come creare una relazione tra due tabelle facendo clic sulla tabella della chiave esterna e trascinandola nella tabella della chiave primaria.

Quando rilasci il mouse, vengono visualizzate le Tabelle e colonne si aprirà una finestra come quella in Figura 4. Quindi puoi indicare le colonne della chiave primaria e della chiave esterna. Quindi fare clic su OK.

Per modificare una relazione esistente, fare clic con il pulsante destro del mouse su una relazione nel diagramma. Quindi seleziona Proprietà :

Quindi, nelle Proprietà finestra, espandi Tabelle e colonne e fai clic sui puntini di sospensione pulsante:

Dopo aver fatto clic sui puntini di sospensione pulsante, le Tabelle e colonne apparirà la finestra. È possibile modificare le colonne della chiave primaria ed esterna (fare nuovamente riferimento alla Figura 4 sopra).

Nel frattempo, eliminazione di una relazione richiede il clic con il pulsante destro del mouse su un esistente relazione. Seleziona Elimina relazioni dal database e fai clic su quando richiesto.

3. Utilizzo di T-SQL per aggiungere, modificare ed eliminare il vincolo di chiave esterna SQL

Il terzo modo per aggiungere una chiave esterna è tramite il codice T-SQL. È possibile utilizzare SQL CREATE TABLE e aggiungere il vincolo di chiave esterna. Oppure puoi anche usare ALTER TABLE per aggiungere questo vincolo dopo aver creato la tabella.

Ecco la sintassi per l'utilizzo di 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

Dopo aver definito il nome e il tipo di colonna, è possibile aggiungere RIFERIMENTI a una tabella e a una colonna. La sintassi sopra mostra la Tabella1 tabella su col1 colonna. Tieni presente che i nomi delle colonne su entrambe le tabelle devono essere gli stessi per essere validi per le chiavi esterne.

La sintassi sopra è per chiavi esterne a colonna singola. Se hai bisogno di più colonne come chiavi esterne, usa la clausola FOREIGN KEY come di seguito:

-- 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

Dopo aver creato la tabella, puoi aggiungere chiavi esterne usando ALTER TABLE. Ecco la sintassi:

ALTER TABLE Table2 WITH CHECK ADD CONSTRAINT FK_Table1_Table2_2 FOREIGN KEY(col3)
	REFERENCES Table3(col1)
GO

Per eliminare un vincolo di chiave esterna, puoi utilizzare ALTER TABLE con DROP CONSTRAINT:

ALTER TABLE Table2 
DROP CONSTRAINT FK_Table1_Table2_2
GO

Ora possiamo riassumere 3 modi per aggiungere, modificare ed eliminare chiavi esterne:

Esempi di vincoli di chiave esterna SQL (MySQL)

Tabella figlio con 1 riferimento a una tabella padre

-- 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

Per visualizzare questa relazione, dai un'occhiata alla Figura 9 di seguito:

L'ID continente è la chiave che mette in relazione le due tabelle.

Tabella figlio con riferimenti multipli

La Auto sportiva table ha più riferimenti a tre diverse tabelle:

-- 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

Ecco come appare in un diagramma di database:

Autoriferimento

Le gerarchie di posizioni mostrano l'autoriferimento nella tabella seguente:

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

Il diagramma di questo autoreferenziale è semplice. La linea punta alla stessa tabella come riferimento personale.

Con AGGIORNAMENTO e CANCELLAZIONE

Con ON UPDATE CASCADE, l'aggiornamento di un valore di colonna di chiave primaria aggiornerà anche i valori di chiave esterna nelle tabelle correlate. Nel frattempo, quando usi ON DELETE CASCADE, l'eliminazione di una chiave primaria eliminerà anche le chiavi esterne. L'impostazione predefinita per ON UPDATE e ON DELETE è NESSUNA AZIONE.

Ecco un esempio di 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

Disabilitazione di un vincolo di chiave esterna SQL

Quanto segue disabiliterà un vincolo di chiave esterna esistente. Nota che la relazione esiste ancora.

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

Questa non è l'impostazione predefinita e non è consigliata. Ma per velocizzare gli inserimenti e gli aggiornamenti in blocco, puoi disabilitare temporaneamente la chiave esterna come quella sopra. Al termine, devi ripristinarlo utilizzando CHECK CONSTRAINT.

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

Gotch e correzioni

Questa sezione ti mostrerà cosa succede quando INSERISCI, AGGIORNA o ELIMINA record con chiavi esterne. Ciò presuppone anche che le chiavi esterne siano non disabilitate con VINCOLO NOCHECK. Questo ti aiuterà quando incontri questi problemi comuni.

Su INSERTO

-- 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

Ecco il messaggio di errore:

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.

La correzione :aggiungi CountryID =47 nei Paesi prima il tavolo. Quindi, rieseguire l'istruzione INSERT precedente. La sequenza inizia con l'inserimento di record nella tabella padre, quindi nella tabella figlio.

In aggiornamento

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

Ecco l'errore 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.

La correzione :aggiungi CountryID =47 nei Paesi tavolo. Quindi, riesegui l'istruzione UPDATE.

Su ELIMINA

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

Questo codice attiverà l'errore come di seguito:

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.

La correzione :Elimina i record corrispondenti da SportsCars tabella con ID produttore =108. Quindi, rieseguire l'istruzione DELETE precedente. Un altro modo è abilitare ON DELETE CASCADE se applicabile. La sequenza inizia con l'eliminazione dei record dalle tabelle figlie, quindi – dalla tabella padre.

Da asporto

Quindi, le chiavi esterne ti sono ancora estranee?

Facciamo un riepilogo di ciò che abbiamo imparato finora.

  • Le chiavi straniere collegano due tabelle (o una tabella quando si utilizza l'autoreferenza). Ne hai bisogno per garantire l'integrità referenziale.
  • Puoi utilizzare uno strumento GUI o T-SQL per aggiungere, modificare o eliminare i vincoli di chiave esterna.
  • Per gli strumenti della GUI, puoi utilizzare SQL Server Management Studio o dbForge Studio per SQL Server. Entrambi offrono diagrammi di database e designer di tabelle per creare tabelle con chiavi primarie ed esterne.
  • CREATE TABLE e ALTER TABLE sono adatti per aggiungere ed eliminare i vincoli di chiave esterna.
  • Puoi disabilitare temporaneamente le chiavi esterne con NOCHECK CONSTRAINT in ALTER TABLE. Ciò accelererà gli inserimenti e gli aggiornamenti in blocco. Ma assicurati di riattivarlo con CHECK CONSTRAINT.
  • Per evitare problemi con le chiavi esterne, assicurati di seguire la sequenza corretta. Per INSERT e UPDATE, inserisci prima nella tabella padre, quindi nelle tabelle figlio. Per DELETE, elimina prima i record secondari, quindi elimina i record principali.

Vorresti aggiungere qualcosa per aiutare i neofiti a padroneggiare le chiavi esterne? I Commenti la sezione è aperta alle tue idee brillanti. Se ti piace questo post, condividilo sulle tue piattaforme di social media preferite.