W tym artykule pokazuję, jak utworzyć klucz obcy w SQL Server przy użyciu Transact-SQL. Pokazuję, jak utworzyć klucz obcy w momencie tworzenia tabeli (w przeciwieństwie do aktualizacji istniejącej tabeli).
Klucz obcy to kolumna, która odwołuje się do kolumny klucza podstawowego innej tabeli. Tworzy to relację między tabelami.
Przykład 1 – Przygotowanie
W tym przykładzie stworzę testową bazę danych z jedną tabelą. Ta tabela będzie zawierać klucz podstawowy, do którego będzie się odnosić nasz klucz obcy.
Utwórz bazę danych:
CREATE DATABASE FK_Test;
Teraz utwórz tabelę kluczy podstawowych:
USE FK_Test; CREATE TABLE Country ( CountryId int IDENTITY (1,1) NOT NULL PRIMARY KEY, CountryName nvarchar(60) );
Przykład 2 – Utwórz klucz obcy
Teraz, gdy mamy tabelę z kluczem podstawowym, stwórzmy kolejną tabelę z kluczem obcym, który odwołuje się do tego klucza podstawowego.
CREATE TABLE City ( CityId int IDENTITY (1,1) NOT NULL PRIMARY KEY, CountryId int NOT NULL REFERENCES Country(CountryId), CityName nvarchar(60) );
To najprostszy sposób na utworzenie klucza obcego. Wszystko, co robimy, to dodawanie REFERENCES
(wraz z tabelą i kolumną klucza podstawowego) do kolumny, która będzie miała ograniczenie klucza obcego.
Aby było jasne, część definiująca klucz obcy jest następująca:
REFERENCES Country(CountryId)
Jest to zawarte w definicji kolumny i po prostu stwierdza, że ta kolumna będzie odwoływać się do CountryId
kolumna w Country
tabela.
W tym przypadku zarówno klucz obcy, jak i klucz podstawowy, do którego się odwołuje, mają tę samą nazwę (CountryId
). Nie jest to jednak wymagane — kolumna klucza obcego może mieć zupełnie inną nazwę niż kolumna, do której się odwołuje (chociaż wszystkie kolumny uczestniczące w relacji klucza obcego muszą mieć taką samą długość i skalę).
Ten przykład powoduje, że SQL Server automatycznie generuje nazwę klucza obcego. To dlatego, że nie podałem imienia. Czytaj dalej, aby zobaczyć, jak utworzyć nazwę dla swojego klucza obcego.
Ale najpierw sprawdźmy ograniczenie klucza obcego, które właśnie stworzyliśmy.
Przykład 3 – Sprawdź ograniczenie klucza obcego
Istnieje wiele sposobów na zwrócenie klucza obcego za pomocą T-SQL, a oto jeden z nich:
EXEC sp_fkeys @fktable_name = City;
Wynik (przy użyciu wyjścia pionowego):
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
systemowa procedura składowana zwraca informacje o naszym kluczu obcym, skojarzonym z nim kluczu podstawowym i inne istotne szczegóły. Wystarczy podać nazwę tabeli kluczy obcych lub tabeli kluczy podstawowych, a zwróci ona odpowiednie informacje.
W tym przykładzie przekazuję nazwę tabeli kluczy obcych – City
. W wynikach możemy spojrzeć na
FK_NAME
kolumna, aby zobaczyć, że ta tabela ma ograniczenie klucza obcego o nazwie
FK__City__CountryId__38996AB5
. To właśnie stworzyliśmy.
Więc teraz, gdy utworzyliśmy klucz obcy, za każdym razem, gdy próbujemy wstawić lub zaktualizować wartość w City.CountryId
kolumna, ograniczenie klucza obcego zezwoli na to tylko wtedy, gdy ta sama wartość już istnieje w Country.CountryId
kolumna. Zapewnia to zachowanie integralności referencyjnej w bazie danych.
Przykład 4 – Więcej opcji
Możliwe jest dodanie większej liczby opcji do definicji klucza obcego.
Na przykład możesz podać nazwę klucza obcego. Możesz również określić, co powinno się stać z wartościami w tej kolumnie, jeśli odpowiednia wartość w kluczu podstawowym zostanie zaktualizowana lub usunięta.
Tutaj ponownie tworzę obie tabele, ale tym razem wyraźnie określam te opcje (to samo robię dla kluczy podstawowych):
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) );
W tym przypadku definicja klucza obcego zaczyna się od CONSTRAINT
, po którym następuje nazwa klucza obcego, po którym następuje FOREIGN KEY
, po której następuje kolumna, do której zostanie zastosowane ograniczenie klucza obcego (w nawiasie).
Widzimy wtedy te same REFERENCES
klauzula, którą widzieliśmy w poprzednim przykładzie.
ON DELETE CASCADE
i ON UPDATE CASCADE
klauzule są używane w celu zapewnienia, że zmiany wprowadzone w Country
tabele są automatycznie propagowane do City
stół. Na przykład, jeśli wiersz zostanie usunięty z tabeli nadrzędnej (klucza podstawowego), wszystkie odpowiadające mu wiersze zostaną usunięte z tabeli odniesienia (klucza obcego).
Domyślna wartość dla ON DELETE
i ON UPDATE
to NO ACTION
. W takim przypadku Aparat baz danych zgłasza błąd, a akcja aktualizacji lub usuwania w wierszu w tabeli nadrzędnej jest wycofywana.
Możesz także użyć SET NULL
aby ustawić kolumnę klucza obcego na NULL
(wymaga, aby kolumna klucza obcego miała wartość null) lub SET DEFAULT
aby ustawić ją na wartość domyślną (wymaga, aby kolumna klucza obcego miała domyślną definicję. Jeśli kolumna dopuszcza wartość null i nie ma jawnie ustawionej wartości domyślnej, NULL
staje się domyślną wartością domyślną kolumny).
W tym przykładzie skorzystałem również z okazji, aby nazwać klucze podstawowe. Widać, że składnia klucza podstawowego jest podobna do składni klucza obcego, ale bez REFERENCES
klauzula (i z dodanym CLUSTERED
argument, który jest domyślny dla kluczy podstawowych).
Teraz sprawdź klucz obcy:
EXEC sp_fkeys @fktable_name = City;
Wynik:
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
Widzimy, że nazwa klucza obcego to teraz FK_City_Country a ograniczenie klucza podstawowego kolumny, do której się odwołuje, nazywa się PK_Country_CountryId .
Przykład 5 – klucz obcy w wielu kolumnach
Możesz również utworzyć klucz obcy w wielu kolumnach, który odwołuje się do wielokolumnowego klucza podstawowego. Wielokolumnowe klucze podstawowe są również znane jako złożone klucze podstawowe. Aby utworzyć złożony klucz obcy, po prostu oddziel kolumny przecinkami podczas definiowania klucza.
Tak:
CONSTRAINT FK_FKName FOREIGN KEY (FKColumn1, FKColumn2) REFERENCES PrimaryKeyTable (PKColumn1, PKColumn2)
Zobacz Jak utworzyć złożony klucz obcy w SQL Server, aby uzyskać bardziej szczegółowy przykład.
Czy klucz podstawowy jest naprawdę potrzebny?
Klucz podstawowy nie jest absolutnie niezbędny dla kluczy obcych, ponieważ możesz użyć unikalnego ograniczenia lub unikalnego indeksu. W szczególności dokumentacja firmy Microsoft stwierdza, że:
FOREIGN KEY
ograniczenia mogą odnosić się tylko do kolumn w PRIMARY KEY
lub UNIQUE
ograniczenia w tabeli odniesienia lub w UNIQUE INDEX
na wskazanej tabeli.
Więc chociaż zwykle dobrą praktyką jest posiadanie kluczy podstawowych we wszystkich tabelach, twoje klucze obce nie muszą się do nich odwoływać.