In dit artikel laat ik zien hoe je een externe sleutel in SQL Server maakt met Transact-SQL. Ik laat zien hoe je een externe sleutel maakt op het moment dat de tabel wordt gemaakt (in tegenstelling tot het bijwerken van een bestaande tabel).
Een refererende sleutel is een kolom die verwijst naar de primaire-sleutelkolom van een andere tabel. Dit creëert een relatie tussen de tabellen.
Voorbeeld 1 – Voorbereiding
In dit voorbeeld maak ik een testdatabase met één tabel. Deze tabel bevat de primaire sleutel waarnaar onze externe sleutel zal verwijzen.
Maak de database:
CREATE DATABASE FK_Test;
Maak nu de primaire sleuteltabel:
USE FK_Test; CREATE TABLE Country ( CountryId int IDENTITY (1,1) NOT NULL PRIMARY KEY, CountryName nvarchar(60) );
Voorbeeld 2 – Maak de externe sleutel
Nu we een tabel met een primaire sleutel hebben, gaan we een andere tabel maken met een externe sleutel die naar die primaire sleutel verwijst.
CREATE TABLE City ( CityId int IDENTITY (1,1) NOT NULL PRIMARY KEY, CountryId int NOT NULL REFERENCES Country(CountryId), CityName nvarchar(60) );
Dit is de eenvoudigste manier om een externe sleutel te maken. Het enige wat we doen is de REFERENCES
. toevoegen clausule (samen met de primaire sleuteltabel en kolom) naar de kolom met de externe sleutelbeperking.
Voor alle duidelijkheid, het deel dat de externe sleutel definieert is dit:
REFERENCES Country(CountryId)
Dit is opgenomen in de kolomdefinitie en stelt eenvoudigweg dat deze kolom zal verwijzen naar de CountryId
kolom in het Country
tafel.
In dit geval hebben zowel de refererende sleutel als de primaire sleutel waarnaar deze verwijst dezelfde naam (CountryId
). Dit is echter geen vereiste – uw externe-sleutelkolom kan een geheel andere naam hebben dan de kolom waarnaar deze verwijst (hoewel alle kolommen die deelnemen aan een externe-sleutelrelatie moeten worden gedefinieerd met dezelfde lengte en schaal).
Dit voorbeeld zorgt ervoor dat SQL Server automatisch de naam van de refererende sleutel genereert. Dat komt omdat ik geen naam heb gegeven. Lees verder om te zien hoe u een naam voor uw externe sleutel kunt maken.
Maar laten we eerst eens kijken naar de beperking van de refererende sleutel die we zojuist hebben gemaakt.
Voorbeeld 3 – Controleer de Foreign Key-beperking
Er zijn veel manieren om een externe sleutel te retourneren met T-SQL, en hier is er een van:
EXEC sp_fkeys @fktable_name = City;
Resultaat (met verticale uitvoer):
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
De sp_fkeys
systeem opgeslagen procedure retourneert informatie over onze externe sleutel, de bijbehorende primaire sleutel en andere relevante details. U geeft gewoon de naam van de refererende-sleuteltabel of de primaire-sleuteltabel door, en het zal de relevante informatie retourneren.
In dit voorbeeld geef ik de naam van de refererende sleuteltabel door - City
. In de resultaten kunnen we kijken naar de
FK_NAME
kolom om te zien of deze tabel een externe sleutelbeperking heeft met de naam
FK__City__CountryId__38996AB5
. Dit is degene die we zojuist hebben gemaakt.
Dus nu we de externe sleutel hebben gemaakt, telkens wanneer we proberen een waarde in te voegen of bij te werken in de City.CountryId
kolom, staat de externe-sleutelbeperking dit alleen toe als dezelfde waarde al bestaat in de Country.CountryId
kolom. Dit zorgt ervoor dat de referentiële integriteit binnen de database behouden blijft.
Voorbeeld 4 – Meer opties
Het is mogelijk om meer opties toe te voegen aan uw buitenlandse sleuteldefinitie.
U kunt bijvoorbeeld een naam voor de externe sleutel opgeven. U kunt ook specificeren wat er met de waarden in deze kolom moet gebeuren als de corresponderende waarde in de primaire sleutel wordt bijgewerkt of verwijderd.
Hier maak ik beide tabellen opnieuw, maar deze keer specificeer ik expliciet deze opties (ik doe hetzelfde voor de primaire sleutels):
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) );
In dit geval begint de definitie van de refererende sleutel met CONSTRAINT
, gevolgd door de naam van de externe sleutel, gevolgd door FOREIGN KEY
, gevolgd door de kolom waarop de externe-sleutelbeperking wordt toegepast (tussen haakjes ingevoegd).
We zien dan dezelfde REFERENCES
clausule die we in het vorige voorbeeld zagen.
De ON DELETE CASCADE
en ON UPDATE CASCADE
clausules worden gebruikt om ervoor te zorgen dat wijzigingen in Country
tabel worden automatisch doorgegeven aan de City
tafel. Als een rij bijvoorbeeld wordt verwijderd uit de bovenliggende (primaire sleutel) tabel, worden alle bijbehorende rijen verwijderd uit de verwijzende (buitenlandse sleutel) tabel.
De standaardwaarde voor ON DELETE
en ON UPDATE
is NO ACTION
. In dit geval genereert de database-engine een fout en wordt de update- of verwijderactie op de rij in de bovenliggende tabel teruggedraaid.
U kunt ook SET NULL
. gebruiken om de externe sleutelkolom in te stellen op NULL
(vereist dat de externe sleutelkolom nullable is), of SET DEFAULT
om het in te stellen op de standaardwaarde (vereist dat de externe sleutelkolom een standaarddefinitie heeft. Als een kolom nullable is en er geen expliciete standaardwaarde is ingesteld, NULL
wordt de impliciete standaardwaarde van de kolom).
In dit voorbeeld heb ik ook van de gelegenheid gebruik gemaakt om de primaire sleutels een naam te geven. U kunt zien dat de primaire sleutelsyntaxis vergelijkbaar is met de externe sleutelsyntaxis, maar zonder de REFERENCES
clausule (en met een toegevoegde CLUSTERED
argument, wat de standaard is voor primaire sleutels).
Controleer nu de externe sleutel:
EXEC sp_fkeys @fktable_name = City;
Resultaat:
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
We kunnen zien dat de naam van de refererende sleutel nu FK_City_Country is en de primaire sleutelbeperking van de kolom waarnaar deze verwijst heet PK_Country_CountryId .
Voorbeeld 5 – Foreign key op meerdere kolommen
U kunt ook een externe sleutel maken op meerdere kolommen die verwijst naar een primaire sleutel met meerdere kolommen. Primaire sleutels met meerdere kolommen worden ook wel samengestelde primaire sleutels genoemd. Om een samengestelde externe sleutel te maken, scheidt u de kolommen eenvoudig met een komma bij het definiëren van de sleutel.
Zoals dit:
CONSTRAINT FK_FKName FOREIGN KEY (FKColumn1, FKColumn2) REFERENCES PrimaryKeyTable (PKColumn1, PKColumn2)
Zie Een samengestelde externe sleutel maken in SQL Server voor een gedetailleerder voorbeeld.
Is de primaire sleutel echt nodig?
Een primaire sleutel is niet absoluut noodzakelijk voor externe sleutels, omdat u een unieke beperking of unieke index kunt gebruiken. In de Microsoft-documentatie staat dit specifiek:
FOREIGN KEY
beperkingen kunnen alleen verwijzen naar kolommen inPRIMARY KEY
ofUNIQUE
beperkingen in de tabel waarnaar wordt verwezen of in eenUNIQUE INDEX
op de tabel waarnaar wordt verwezen.
Dus hoewel het meestal een goede gewoonte is om primaire sleutels op alle tabellen te hebben, zijn uw externe sleutels niet verplicht om ernaar te verwijzen.