定義
設F是基本關係R的一個或一組屬性,但不是關係的鍵,Ks是基本關係S的主鍵。如果F與Ks相對應,則稱F是R的外鍵,並稱基本關係R為參照關係,基本關係S為被參照關係或目標關係。
換而言之,如果關係模式R中的某屬性集不是R的主鍵,而是另一個關係R1的主鍵則該屬性集是關係模式R的外鍵,通常在資料庫設計中縮寫為F。
在實際操作中,將一個表的值放入第二個表來表示關聯,所使用的值是第一個表的主鍵值(在必要時可包括複合主鍵值)。此時,第二個表中保存這些值的屬性稱為外鍵(foreign key)。
顯然目標關係的主碼和參照關係的外碼必須定義在一個或同一組的域上。關係R和S不一定是不同的關係,即外鍵不一定要與相應的主鍵同名。如在學生(學號,姓名,性別,專業號,年齡,班長)關係中,“學號”是主鍵,“班長”屬性表示該學生所在班級的班長的學號,它引用了本關係中“學號”屬性,因此“班長”是外鍵,這裡學生關係既是參照關係也是被參照關係。不過在實際套用中為了便於識別,當主鍵與相應的外鍵屬於不同關係時,往往取相同的名字。
作用
保持數據一致性,完整性,主要目的是控制存儲在外鍵表中的數據。 使兩張表形成關聯,外鍵只能引用外表中的列的值或使用空值。
如果不使用外鍵,表2的學號欄位插了一個值(比如20140999999),但是這個值在表1中並沒有,這個時候,資料庫允許插入,並不會對插入的數據做關係檢查。然而在設定外鍵的情況下,你插入表2學號欄位的值必須要求在表1的學號欄位能找到。 同時,如果你要刪除表1的某個學號欄位,必須保證表2中沒有引用該欄位值的列,否則就沒法刪除。這就是所謂的保持數據的一致性和完整性。如右圖,如果表2還引用表1的某個學號,你卻把表1中的這個學號刪了,表2就不知道這個學號對應的學生是哪個學生。
資料庫中的表必須符合規範,才能杜絕數據冗餘、插入異常、刪除異常等現象。規範的過程是分解表的過程。經過分解,伺一事物的代表屬性出現在不同的表中。顯然,它們應該保持一致。例如,某學生的代表數據是學號012,在學生表里是012,在成績表里也應該是012。這種一致性由外鍵實現。外鍵的功能是:它的值一定是另一個表的主鍵值。學號在學生表里是主鍵,在成績表里是外鍵。成績表里的學號一定要是學生表里的學號。於是,學生表里的學號和成績表里的學號就一致了。可以直觀地理解,外鍵的功能是實現同一事物在不同表中的標誌一致性。2功能的實現由外鍵聯繫的兩個表,在單獨操作時,外鍵功能由兩種方法實現 :
阻止執行
•從表插入新行,其外鍵值不是主表的主鍵值便阻止插入;
•從表修改外鍵值,新值不是主表的主鍵值便阻止修改;
•主表刪除行,其主鍵值在從表里存在便阻止刪除(要想刪除,必須先刪除從表的相關行);
•主表修改主鍵值,舊值在從表里存在便阻止修改(要想修改,必須先刪除從表的相關行)。
級聯執行
•主表刪除行,連帶從表的相關行一起刪除;
•主表修改主鍵值,連帶從表相關行的外鍵值一起修改。兩種方法提供給用戶選擇。無論選取哪種方法,從表里都不會有多餘行。從另一個角度理解,用拒絕同一事物在從表中的標誌與主表不一致來實現與主表中的標誌一致。
兩種實現方法,通過下面方式選擇:
•界面:設級聯更新、級聯刪除兩個選擇方框,選取則級聯執行、不選取則阻止執行;
•命令:設E)kSCM)E、RESTRICT兩個可選項,CASCADE為級聯執行、RESTRICT為阻止執行。
套用
示例
student(s#,sname,d#),即學生這個關係有三個屬性:學號,姓名,所在系別。
dep(d#,dname),即院系有兩個屬性:系號、系名。
則s#、d#是主鍵,也是各自所在關係的唯一候選鍵,d#是student的外鍵。
建立外鍵的前提: 本表的列必須與外鍵類型相同(外鍵必須是外表主鍵)。
指定外鍵關鍵字: foreign key(列名)
引用外鍵關鍵字: references <主表名>(主表主鍵)
事件觸發限制: on delete和on update , 可設參數cascade(跟隨外鍵改動), restrict(限制外表中的外鍵改動),set Null(設空值),set Default(設默認值),[默認]no action
例如:
outTable表主鍵id 類型 int
創建含有外鍵的表:
create table temp(
id int,
name char(20),
foreign key(id) references outTable(id) on delete cascade on update cascade);
說明:把id列 設為外鍵 參照外表outTable的id列 當外鍵的值刪除 本表中對應的列刪除 當外鍵的值改變 本表中對應的列值改變。
註:在創建表中增加外鍵的觸發事件是不行的,
create table temp(
id int,
name char(20),
foreign key(id) references outTable(id));
使用原則
1、 為關聯欄位創建外鍵。
2、 所有的鍵都必須唯一。
3、避免使用複合鍵。
4、外鍵總是關聯唯一的鍵欄位。
使用方法
主鍵表和外建表:
使用設計界面創建外鍵時,出現主鍵表和外建表問題,上述使個人理解有誤:
CREATE TABLE TABLE1
(
[ID] INT IDENTITY(1,1) PRIMARY KEY
)
GO
CREATE TABLE TABLE2
(
[ID] INT NOT NULL,
FOREIGN KEY ([ID]) REFERENCES [TABLE1]([ID])
)
GO
TABLE2 中引用了TABLE1,在此TABLE1為主鍵表,而TABLE2 為外鍵表。
總結:主鍵表是被引用的表,外鍵表是引用其他表的表。
有效性
有很多時候,程式設計師會發現欄位缺少、多餘問題或者是創建外鍵以後就不能添加沒有受約束的行[特殊情況下是有必要的],這個時候不想對表結構進行操作,就可以使用約束失效。
以 Northwind 為例:想給產品表【Products表】添加一條不受種類表【Categories表】限制的數據。可以使產品表中的 Categories 約束失效。
寫法:ALTER TABLE dbo.Products NOCHECKCONSTRAINT FK_Products_Categories
添加完成後再使其有效:
ALTER TABLE dbo.Products CHECK CONSTRAINT FK_Products_Categories
這樣就完成不受某表約束的數據添加了。
還有一個好處是:如上述例子。修改 Categories 表時 添加欄位時 要把所有引用 Categories 表的外鍵給失效。等給 Categories 表添加欄位完成後再使所有套用 Categories 表的外鍵恢復有效性即可。