I denne artikel demonstrerer jeg, hvordan man opretter en fremmednøgle i SQL Server ved hjælp af Transact-SQL. Jeg demonstrerer, hvordan man opretter en fremmednøgle på tidspunktet for oprettelse af tabellen (i modsætning til at opdatere en eksisterende tabel).
En fremmednøgle er en kolonne, der refererer til en anden tabels primære nøglekolonne. Dette skaber et forhold mellem tabellerne.
Eksempel 1 – Forberedelse
I dette eksempel vil jeg oprette en testdatabase med en tabel. Denne tabel vil indeholde den primære nøgle, som vores fremmednøgle refererer til.
Opret databasen:
CREATE DATABASE FK_Test;
Opret nu primærnøgletabellen:
USE FK_Test; CREATE TABLE Country ( CountryId int IDENTITY (1,1) NOT NULL PRIMARY KEY, CountryName nvarchar(60) );
Eksempel 2 – Opret fremmednøgle
Nu hvor vi har en tabel med en primær nøgle, lad os oprette en anden tabel med en fremmednøgle, der refererer til den primære nøgle.
CREATE TABLE City ( CityId int IDENTITY (1,1) NOT NULL PRIMARY KEY, CountryId int NOT NULL REFERENCES Country(CountryId), CityName nvarchar(60) );
Dette er den enkleste måde at oprette en fremmednøgle på. Alt vi gør er at tilføje REFERENCES
klausul (sammen med den primære nøgletabel og kolonne) til den kolonne, der vil have den fremmede nøgle-begrænsning.
For at være klar er den del, der definerer fremmednøglen, denne:
REFERENCES Country(CountryId)
Dette er inkluderet i kolonnedefinitionen og angiver blot, at denne kolonne vil referere til CountryId
kolonnen i Country
tabel.
I dette tilfælde deler både fremmednøglen og den primære nøgle, som den refererer til, det samme navn (CountryId
). Dette er dog ikke et krav – din fremmednøglekolonne kan have et helt andet navn end den kolonne, den refererer til (selvom alle kolonner, der deltager i et fremmednøgleforhold, skal defineres med samme længde og skala).
Dette eksempel får SQL Server til automatisk at generere navnet på den fremmede nøgle. Det er fordi jeg ikke har oplyst et navn. Læs videre for at se, hvordan du kan oprette et navn til din fremmednøgle.
Men lad os først tjekke den fremmednøglebegrænsning, vi lige har oprettet.
Eksempel 3 – Tjek begrænsningen for fremmednøgle
Der er mange måder at returnere en fremmednøgle ved hjælp af T-SQL, og her er en af dem:
EXEC sp_fkeys @fktable_name = City;
Resultat (ved hjælp af lodret output):
PKTABLE_QUALIFIER | FK_Test PKTABLE_OWNER | dbo PKTABLE_NAME | Country PKCOLUMN_NAME | CountryId FKTABLE_QUALIFIER | FK_Test FKTABLE_OWNER | dbo FKTABLE_NAME | City FKCOLUMN_NAME | CountryId KEY_SEQ | 1 UPDATE_RULE | 1 DELETE_RULE | 1 FK_NAME | FK__City__CountryId__38996AB5 PK_NAME | PK__Country__10D1609FC8BFA7F2 DEFERRABILITY | 7
sp_fkeys
Systemlagret procedure returnerer information om vores fremmednøgle, dens tilknyttede primærnøgle og andre relevante detaljer. Du indtaster blot navnet på fremmednøgletabellen eller primærnøgletabellen, og den vil returnere den relevante information.
I dette eksempel videregiver jeg navnet på tabellen med fremmednøgle – City
. I resultaterne kan vi se på
FK_NAME
kolonne for at se, at denne tabel har en fremmednøglebegrænsning kaldet
FK__City__CountryId__38996AB5
. Det er den, vi lige har oprettet.
Så nu hvor vi har oprettet fremmednøglen, hver gang vi forsøger at indsætte eller opdatere en værdi i City.CountryId
kolonne, vil den fremmede nøgle-begrænsning kun tillade det, hvis den samme værdi allerede findes i Country.CountryId
kolonne. Dette sikrer, at referentiel integritet opretholdes i databasen.
Eksempel 4 – Flere muligheder
Det er muligt at tilføje flere muligheder til din udenlandsk nøgledefinition.
For eksempel kan du angive et navn til fremmednøglen. Du kan også angive, hvad der skal ske med værdier i denne kolonne, hvis den tilsvarende værdi i primærnøglen opdateres eller slettes.
Her opretter jeg begge tabeller igen, men denne gang angiver jeg eksplicit disse muligheder (jeg gør det samme for primærnøglerne):
CREATE TABLE Country ( CountryId int IDENTITY (1,1) NOT NULL, CONSTRAINT PK_Country_CountryId PRIMARY KEY CLUSTERED (CountryId), CountryName nvarchar(60) ); CREATE TABLE City ( CityId int IDENTITY (1,1) NOT NULL, CONSTRAINT PK_City_CityId PRIMARY KEY CLUSTERED (CityId), CountryId int NOT NULL, CONSTRAINT FK_City_Country FOREIGN KEY (CountryID) REFERENCES Country (CountryID) ON DELETE CASCADE ON UPDATE CASCADE, CityName nvarchar(60) );
I dette tilfælde starter fremmednøgledefinitionen med CONSTRAINT
, efterfulgt af navnet på den fremmede nøgle, efterfulgt af FOREIGN KEY
, efterfulgt af kolonnen, som den fremmede nøgle-begrænsning vil blive anvendt på (indsat i parentes).
Vi ser så de samme REFERENCES
klausul, som vi så i det foregående eksempel.
ON DELETE CASCADE
og ON UPDATE CASCADE
klausuler bruges til at sikre, at ændringer foretages i Country
tabellen overføres automatisk til City
bord. For eksempel, hvis en række slettes fra den overordnede (primære nøgle) tabel, slettes alle tilsvarende rækker fra referencetabellen (fremmed nøgle).
Standardværdien for ON DELETE
og ON UPDATE
er NO ACTION
. I dette tilfælde rejser databasemotoren en fejl, og opdaterings- eller sletningshandlingen på rækken i den overordnede tabel rulles tilbage.
Du kan også bruge SET NULL
for at indstille fremmednøglekolonnen til NULL
(kræver, at fremmednøglekolonnen er nullbar), eller SET DEFAULT
for at indstille den til sin standardværdi (kræver, at fremmednøglekolonnen har en standarddefinition. Hvis en kolonne er nullbar, og der ikke er angivet nogen eksplicit standardværdi, skal NULL
bliver den implicitte standardværdi for kolonnen).
I dette eksempel benyttede jeg også lejligheden til at navngive de primære nøgler. Du kan se, at den primære nøglesyntaks ligner den fremmede nøglesyntaks, men uden REFERENCES
klausul (og med en tilføjet CLUSTERED
argument, som er standard for primærnøgler).
Tjek nu den fremmede nøgle:
EXEC sp_fkeys @fktable_name = City;
Resultat:
PKTABLE_QUALIFIER | FK_Test PKTABLE_OWNER | dbo PKTABLE_NAME | Country PKCOLUMN_NAME | CountryId FKTABLE_QUALIFIER | FK_Test FKTABLE_OWNER | dbo FKTABLE_NAME | City FKCOLUMN_NAME | CountryId KEY_SEQ | 1 UPDATE_RULE | 0 DELETE_RULE | 0 FK_NAME | FK_City_Country PK_NAME | PK_Country_CountryId DEFERRABILITY | 7
Vi kan se, at den fremmede nøgles navn nu er FK_City_Country og den primære nøglebegrænsning for kolonnen, som den refererer til, kaldes PK_Country_CountryId .
Eksempel 5 – Fremmednøgle på flere kolonner
Du kan også oprette en fremmednøgle på flere kolonner, der refererer til en primærnøgle med flere kolonner. Primære nøgler med flere kolonner er også kendt som sammensatte primærnøgler. For at oprette en sammensat fremmednøgle skal du blot adskille kolonnerne med et komma, når du definerer nøglen.
Sådan:
CONSTRAINT FK_FKName FOREIGN KEY (FKColumn1, FKColumn2) REFERENCES PrimaryKeyTable (PKColumn1, PKColumn2)
Se Sådan oprettes en sammensat fremmednøgle i SQL Server for et mere detaljeret eksempel.
Er den primære nøgle virkelig nødvendig?
En primær nøgle er ikke absolut nødvendig for fremmednøgler, da du kan bruge en unik begrænsning eller unikt indeks. Specifikt hedder det i Microsoft-dokumentationen:
FOREIGN KEY
begrænsninger kan kun referere til kolonner i PRIMARY KEY
eller UNIQUE
begrænsninger i den refererede tabel eller i et UNIQUE INDEX
på den refererede tabel.
Så selvom det normalt er god praksis at have primærnøgler på alle tabeller, er dine fremmednøgler ikke forpligtet til at henvise til dem.