sql >> Databasteknik >  >> RDS >> Sqlserver

Hur man skapar en främmande nyckel i SQL Server (T-SQL-exempel)

I den här artikeln visar jag hur man skapar en främmande nyckel i SQL Server med Transact-SQL. Jag visar hur man skapar en främmande nyckel vid tidpunkten för att skapa tabellen (i motsats till att uppdatera en befintlig tabell).

En främmande nyckel är en kolumn som refererar till en annan tabells primärnyckelkolumn. Detta skapar en relation mellan tabellerna.

Exempel 1 – Förberedelser

I det här exemplet skapar jag en testdatabas med en tabell. Den här tabellen kommer att innehålla primärnyckeln som vår främmande nyckel refererar till.

Skapa databasen:

CREATE DATABASE FK_Test;

Skapa nu den primära nyckeltabellen:

USE FK_Test;

CREATE TABLE Country
(
    CountryId int IDENTITY (1,1) NOT NULL PRIMARY KEY,
    CountryName nvarchar(60)
);

Exempel 2 – Skapa den främmande nyckeln

Nu när vi har en tabell med en primärnyckel, låt oss skapa en annan tabell med en främmande nyckel som refererar till den primärnyckeln.

CREATE TABLE City
(
    CityId int IDENTITY (1,1) NOT NULL PRIMARY KEY,
    CountryId int NOT NULL REFERENCES Country(CountryId),
    CityName nvarchar(60)
);

Detta är det enklaste sättet att skapa en främmande nyckel. Allt vi gör är att lägga till REFERENCES sats (tillsammans med primärnyckeltabellen och kolumnen) till kolumnen som kommer att ha den främmande nyckeln.

För att vara tydlig är den del som definierar den främmande nyckeln denna:

REFERENCES Country(CountryId)

Detta ingår i kolumndefinitionen och anger helt enkelt att denna kolumn refererar till CountryId kolumnen i Country bord.

I det här fallet har både den främmande nyckeln och primärnyckeln som den refererar till samma namn (CountryId ). Detta är dock inget krav – din främmande nyckelkolumn kan ha ett helt annat namn än kolumnen som den refererar till (även om alla kolumner som deltar i en främmande nyckelrelation måste definieras med samma längd och skala).

Detta exempel gör att SQL Server automatiskt genererar namnet på den främmande nyckeln. Det beror på att jag inte angav något namn. Läs vidare för att se hur du kan skapa ett namn för din främmande nyckel.

Men först, låt oss kontrollera den främmande nyckelbegränsningen som vi just skapade.

Exempel 3 – Kontrollera begränsningen för främmande nyckel

Det finns många sätt att returnera en främmande nyckel med T-SQL, och här är ett av dem:

EXEC sp_fkeys @fktable_name = City;

Resultat (med vertikal utdata):

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 Systemlagrad procedur returnerar information om vår främmande nyckel, dess associerade primärnyckel och andra relevanta detaljer. Du anger helt enkelt namnet på den främmande nyckeltabellen eller den primära nyckeltabellen, och den kommer att returnera relevant information.

I det här exemplet skickar jag namnet på tabellen med främmande nyckel – City . I resultaten kan vi titta på FK_NAME kolumn för att se att den här tabellen har en främmande nyckel-begränsning som heter FK__City__CountryId__38996AB5 . Det här är den vi nyss skapade.

Så nu när vi har skapat den främmande nyckeln, när vi försöker infoga eller uppdatera ett värde i City.CountryId kolumnen, tillåter den främmande nyckelbegränsningen det endast om samma värde redan finns i Country.CountryId kolumn. Detta säkerställer att referensintegriteten upprätthålls i databasen.

Exempel 4 – Fler alternativ

Det är möjligt att lägga till fler alternativ till din definition av främmande nyckel.

Du kan till exempel ange ett namn för den främmande nyckeln. Du kan också ange vad som ska hända med värden i den här kolumnen om motsvarande värde i primärnyckeln uppdateras eller tas bort.

Här skapar jag båda tabellerna igen, men den här gången anger jag uttryckligen dessa alternativ (jag gör samma sak för primärnycklarna):

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 det här fallet börjar den främmande nyckeldefinitionen med CONSTRAINT , följt av namnet på den främmande nyckeln, följt av FOREIGN KEY , följt av kolumnen som den främmande nyckeln kommer att tillämpas på (infogas inom parentes).

Vi ser då samma REFERENCES klausul som vi såg i föregående exempel.

ON DELETE CASCADE och ON UPDATE CASCADE satser används för att säkerställa att ändringar görs i Country tabellen förs automatiskt till City tabell. Till exempel, om en rad raderas från den överordnade (primära nyckeln) tabellen, tas alla motsvarande rader bort från referenstabellen (främmande nyckel).

Standardvärdet för ON DELETE och ON UPDATE är NO ACTION . I det här fallet skapar databasmotorn ett fel och uppdaterings- eller raderingsåtgärden på raden i den överordnade tabellen återställs.

Du kan också använda SET NULL för att ställa in den främmande nyckelkolumnen till NULL (kräver att den främmande nyckelkolumnen är nullbar), eller SET DEFAULT för att ställa in det till dess standardvärde (kräver att den främmande nyckelkolumnen har en standarddefinition. Om en kolumn är nullbar och det inte finns något explicit standardvärde inställt, NULL blir det implicita standardvärdet för kolumnen).

I det här exemplet passade jag även på att namnge primärnycklarna. Du kan se att syntaxen för primärnyckeln liknar syntaxen för den främmande nyckeln, men utan REFERENCES klausul (och med en tillagd CLUSTERED argument, som är standard för primärnycklar).

Kontrollera nu den främmande nyckeln:

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 att den främmande nyckelns namn nu är FK_City_Country och den primära nyckelbegränsningen för kolumnen som den refererar till kallas PK_Country_CountryId .

Exempel 5 – Utländsk nyckel på flera kolumner

Du kan också skapa en främmande nyckel på flera kolumner som refererar till en primärnyckel med flera kolumner. Primärnycklar med flera kolumner är också kända som sammansatta primärnycklar. För att skapa en sammansatt främmande nyckel, separera helt enkelt kolumnerna med ett kommatecken när du definierar nyckeln.

Så här:

CONSTRAINT FK_FKName FOREIGN KEY
 (FKColumn1, FKColumn2)
REFERENCES PrimaryKeyTable (PKColumn1, PKColumn2)

Se Hur man skapar en sammansatt främmande nyckel i SQL Server för ett mer detaljerat exempel.

Är den primära nyckeln verkligen nödvändig?

En primärnyckel är inte absolut nödvändig för främmande nycklar, eftersom du kan använda en unik begränsning eller unikt index. Specifikt säger Microsofts dokumentation detta:

FOREIGN KEY begränsningar kan endast referera till kolumner i PRIMARY KEY eller UNIQUE begränsningar i den refererade tabellen eller i ett UNIQUE INDEX på den refererade tabellen.

Så även om det vanligtvis är bra att ha primärnycklar på alla tabeller, är dina främmande nycklar inte skyldiga att referera till dem.


  1. Rails 3.2 Postgres Save Error ActiveRecord::StatementInvalid:PG::Error:ERROR:Syntaxfel nära 'T' vid position 5

  2. Är COUNT(rovid) snabbare än COUNT(*)?

  3. Omvända en sträng i SQL och PL/SQL Ett exempel

  4. Entity-Attribute-Value Tabelldesign