複製鏈接
請複製以下鏈接發送給好友

外鍵

鎖定
如果公共關鍵字在一個關係中是主關鍵字,那麼這個公共關鍵字被稱為另一個關係的外鍵。由此可見,外鍵表示了兩個關係之間的相關聯繫。以另一個關係的外鍵作主關鍵字的表被稱為主表,具有此外鍵的表被稱為主表的從表。外鍵又稱作外關鍵字
中文名
外鍵
外文名
foreign key
別    名
外碼
應用學科
數據庫
作    用
保持數據一致性完整性

外鍵定義

外鍵定義 外鍵定義
設F是基本關係R的一個或一組屬性,但不是關係的鍵,Ks是基本關係S的主鍵。如果F與Ks相對應,則稱F是R的外鍵,並稱基本關係R為參照關係,基本關係S為被參照關係或目標關係。
換而言之,如果關係模式R中的某屬性集不是R的主鍵,而是另一個關係R1的主鍵則該屬性集是關係模式R的外鍵,通常在數據庫設計中縮寫為FK
在實際操作中,將一個表的值放入第二個表來表示關聯,所使用的值是第一個表的主鍵值(在必要時可包括複合主鍵值)。此時,第二個表中保存這些值的屬性稱為外鍵(foreign key)。 [1] 
顯然目標關係的主碼和參照關係的外碼必須定義在一個或同一組的域上。關係R和S不一定是不同的關係,即外鍵不一定要與相應的主鍵同名。如在學生(學號,姓名,性別,專業號,年齡,班長)關係中,“學號”是主鍵,“班長”屬性表示該學生所在班級的班長的學號,它引用了本關係中“學號”屬性,因此“班長”是外鍵,這裏學生關係既是參照關係也是被參照關係。不過在實際應用中為了便於識別,當主鍵與相應的外鍵屬於不同關係時,往往取相同的名字。 [2] 

外鍵作用

保持數據一致性,完整性,主要目的是控制存儲在外鍵表中的數據。 使兩張表形成關聯,外鍵只能引用外表中的列的值或使用空值。 [3] 
圖1 控制存儲在外鍵表中的數據 圖1 控制存儲在外鍵表中的數據
學號在成績表(表2)中是主鍵,在學生表(表1)中是外鍵。如果不使用外鍵,表1的學號字段插了一個值(比如20140999999),但是這個值在表2中並沒有,這個時候,數據庫允許插入,並不會對插入的數據做關係檢查。然而在設置外鍵的情況下,插入表1學號字段的值必須要求在表1的學號字段能找到。 同時,如果要刪除表2的某個學號字段,必須保證表2中沒有引用該字段值的列,否則就沒法刪除。這就是所謂的保持數據的一致性和完整性。如圖1,如果表1還引用表2的某個學號,卻把表1中的這個學號刪了,表2就不知道這個學號對應的學生是哪個學生。
數據庫中的表必須符合規範,才能杜絕數據冗餘、插入異常、刪除異常等現象。規範的過程是分解表的過程。經過分解,同一事物的代表屬性出現在不同的表中。顯然,它們應該保持一致。外鍵的值或者是另外一個表的主鍵值或者為空值。學號在學生表裏是主鍵,在成績表裏是外鍵。成績表裏的學號一定要是學生表裏的學號。於是,學生表裏的學號和成績表裏的學號就一致了。可以直觀地理解,外鍵的功能是實現同一事物在不同表中的標誌一致性。功能的實現由外鍵聯繫的兩個表,在單獨操作時,外鍵功能由兩種方法實現 [4] 
阻止執行
  • 從表插入新行,其外鍵值不是主表的主鍵值便阻止插入;
  • 從表修改外鍵值,新值不是主表的主鍵值便阻止修改;
  • 主表刪除行,其主鍵值在從表裏存在便阻止刪除(要想刪除,必須先刪除從表的相關行);
  • 主表修改主鍵值,舊值在從表裏存在便阻止修改(要想修改,必須先刪除從表的相關行)。
級聯執行
  • 主表刪除行,連帶從表的相關行一起刪除;
  • 主表修改主鍵值,連帶從表相關行的外鍵值一起修改。兩種方法提供給用户選擇。無論選取哪種方法,從表裏都不會有多餘行。從另一個角度理解,用拒絕同一事物在從表中的標誌與主表不一致來實現與主表中的標誌一致。
兩種實現方法,通過下面方式選擇:
  • 界面:設級聯更新、級聯刪除兩個選擇方框,選取則級聯執行、不選取則阻止執行;
  • 命令:設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 表的外鍵恢復有效性即可。
參考資料