В тази статия демонстрирам как да създадете външен ключ в SQL Server с помощта на Transact-SQL. Демонстрирам как се създава външен ключ в момента на създаване на таблицата (за разлика от актуализирането на съществуваща таблица).
Външният ключ е колона, която препраща към колоната с първичен ключ на друга таблица. Това създава връзка между таблиците.
Пример 1 – Подготовка
В този пример ще създам тестова база данни с една таблица. Тази таблица ще съдържа първичния ключ, който нашият външен ключ ще препраща.
Създайте базата данни:
СЪЗДАВАНЕ НА БАЗА ДАННИ FK_Test;
Сега създайте таблицата с първичен ключ:
ИЗПОЛЗВАЙТЕ FK_Test;СЪЗДАЙТЕ ТАБЛИЦА Country( CountryId int IDENTITY (1,1) NOT NULL PRIMARY KEY, CountryName nvarchar(60));
Пример 2 – Създаване на външния ключ
Сега, когато имаме таблица с първичен ключ, нека създадем друга таблица с външен ключ, който препраща към този първичен ключ.
СЪЗДАВАНЕ НА ТАБЛИЦА Град( CityId int IDENTITY (1,1) NOT NULL PRIMARY KEY, CountryId int NOT NULL REFERENCE Country(CountryId), CityName nvarchar(60));
Това е най-простият начин за създаване на външен ключ. Всичко, което правим, е да добавим REFERENCES клауза (заедно с таблицата и колоната с първичен ключ) към колоната, която ще има ограничението за външен ключ.
За да бъде ясно, частта, която дефинира външния ключ, е следната:
РЕФЕРЕНЦИИ Country(CountryId)
Това е включено в дефиницията на колоната и просто посочва, че тази колона ще препраща към CountryId колона в Country таблица.
В този случай и външният ключ, и първичният ключ, който препраща, споделят едно и също име (CountryId ). Това обаче не е изискване – вашата колона с външен ключ може да има напълно различно име от колоната, която препраща (въпреки че всички колони, участващи във връзка с външен ключ, трябва да бъдат дефинирани със същата дължина и мащаб).
Този пример кара SQL Server автоматично да генерира името на външния ключ. Това е, защото не посочих име. Прочетете, за да видите как можете да създадете име за вашия външен ключ.
Но първо, нека проверим ограничението на външния ключ, което току-що създадохме.
Пример 3 – Проверете ограничението на външния ключ
Има много начини за връщане на външен ключ с помощта на T-SQL и ето един от тях:
EXEC sp_fkeys @fktable_name =Град;
Резултат (с помощта на вертикален изход):
PKTABLE_QUALIFIER | FK_TestPKTABLE_OWNER | dboPKTABLE_NAME | CountryPKCOLUMN_NAME | CountryIdFKTABLE_QUALIFIER | FK_TestFKTABLE_OWNER | dboFKTABLE_NAME | CityFKCOLUMN_NAME | CountryIdKEY_SEQ | 1UPDATE_RULE | 1DELETE_RULE | 1FK_NAME | FK__City__CountryId__38996AB5PK_NAME | PK__Country__10D1609FC8BFA7F2ОТЛОЖЕНИЕ | 7
sp_fkeys системната съхранена процедура връща информация за нашия външен ключ, свързания с него първичен ключ и други подходящи подробности. Просто предавате името на таблицата с външни ключове или таблицата с първичен ключ и тя ще върне съответната информация.
В този пример предавам името на таблицата с външни ключове – City . В резултатите можем да разгледаме
FK_NAME
колона, за да видите, че тази таблица има ограничение за външен ключ, наречено
FK__City__CountryId__38996AB5
. Това е този, който току-що създадохме.
И така, сега, когато създадохме външния ключ, всеки път, когато се опитаме да вмъкнем или актуализираме стойност в City.CountryId колона, ограничението на външния ключ ще го позволи само ако същата стойност вече съществува в Country.CountryId колона. Това гарантира, че референтната цялост се поддържа в базата данни.
Пример 4 – Още опции
Възможно е да добавите повече опции към вашата дефиниция за външен ключ.
Например можете да посочите име за външния ключ. Можете също да посочите какво да се случи със стойностите в тази колона, ако съответната стойност в първичния ключ бъде актуализирана или изтрита.
Тук отново създавам и двете таблици, но този път изрично посочвам тези опции (правя същото за първичните ключове):
СЪЗДАВАНЕ НА ТАБЛИЦА Country( CountryId int IDENTITY (1,1) NOT NULL, CONSTRAINT PK_Country_CountryId ПЪРВИЧЕН КЛУСТЕР (CountryId), CountryName nvarchar(60));CREATE TABLE City( CityId int IDENTITY (1,1) CONSTRAINT NULL PK_City_CityId ПЪРВЕН КЛУСТЕР (CityId), CountryId int NOT NULL, ОГРАНИЧЕНИЕ FK_City_Country ВЪНШЕН КЛЮЧ (CountryID) СПРАВКИ Държава (CountryID) ПРИ ИЗТРИВАНЕ НА КАСКАДА ПРИ АКТУАЛИЗИРАНЕ НА КАСКАДА, CityName0));6)В този случай дефиницията на външния ключ започва с
CONSTRAINT, последвано от името на външния ключ, последвано отFOREIGN KEY, последвано от колоната, към която ще бъде приложено ограничението за външния ключ (вмъкнато в скоби).След това виждаме същите
REFERENCESклауза, която видяхме в предишния пример.
ON DELETE CASCADEиON UPDATE CASCADEклаузите се използват, за да се гарантира, че промените, направени вCountryтаблицата автоматично се разпространяват вCityмаса. Например, ако един ред бъде изтрит от таблицата родител (първичен ключ), всички съответни редове се изтриват от таблицата за препращане (външен ключ).Стойността по подразбиране за
ON DELETEиON UPDATEеNO ACTION. В този случай Database Engine повдига грешка и действието за актуализиране или изтриване на реда в родителската таблица се отменя.Можете също да използвате
SET NULLза да зададете колоната за външен ключ наNULL(изисква колоната с външния ключ да бъде нула) илиSET DEFAULTза да го зададете на стойността му по подразбиране (изисква колоната с външния ключ да има дефиниция по подразбиране. Ако колона е нула и няма изрично зададена стойност по подразбиране,NULLстава неявната стойност по подразбиране на колоната).В този пример също се възползвах от възможността да наименувам първичните ключове. Можете да видите, че синтаксисът на първичния ключ е подобен на синтаксиса на външния ключ, но без
REFERENCESклауза (и с добавенCLUSTEREDаргумент, който е по подразбиране за първични ключове).Сега проверете външния ключ:
EXEC sp_fkeys @fktable_name =Град;Резултат:
PKTABLE_QUALIFIER | FK_TestPKTABLE_OWNER | dboPKTABLE_NAME | CountryPKCOLUMN_NAME | CountryIdFKTABLE_QUALIFIER | FK_TestFKTABLE_OWNER | dboFKTABLE_NAME | CityFKCOLUMN_NAME | CountryIdKEY_SEQ | 1UPDATE_RULE | 0DELETE_RULE | 0FK_NAME | FK_City_CountryPK_NAME | PK_Country_CountryIdDEFERRABILITY | 7Можем да видим, че името на външния ключ вече е FK_City_Country и ограничението на първичния ключ на колоната, която препраща, се нарича PK_Country_CountryId .
Пример 5 – Външен ключ върху множество колони
Можете също да създадете външен ключ в множество колони, който препраща към многоколонен първичен ключ. Многоколонните първични ключове са известни още като съставни първични ключове. За да създадете съставен външен ключ, просто разделете колоните със запетая, когато дефинирате ключа.
Като това:
ОГРАНИЧЕНИЕ FK_FKName ВЪНШЕН КЛЮЧ (FKColumn1, FKColumn2)РЕФЕРЕНЦИИ PrimaryKeyTable (PKColumn1, PKColumn2)Вижте Как да създадете композитен външен ключ в SQL Server за по-подробен пример.
Наистина ли е необходим първичният ключ?
Първичният ключ не е абсолютно необходим за външни ключове, тъй като можете да използвате уникално ограничение или уникален индекс. По-конкретно, документацията на Microsoft гласи това:
FOREIGN KEYограниченията могат да препращат само към колони вPRIMARY KEYилиUNIQUEограничения в посочената таблица или вUNIQUE INDEXна посочената таблица.Така че, докато обикновено е добра практика да имате първични ключове във всички таблици, външните ви ключове не са длъжни да ги препращат.