外來鍵
外來鍵又稱外部鍵,是指在關聯式資料庫中,每個資料表都是由關聯來連繫彼此的關係,父資料表(Parent Entity)的主鍵(Primary Key)會放在另一個資料表,當做屬性以建立彼此的關聯,而這個屬性就是外來鍵。
比如,學生跟老師之間是教學的關聯,學生資料表會有個屬性叫指導老師(FK),而這個值就是對應到老師資料表的老師代號(PK),學生的指導老師就是外來鍵。
外來鍵是表中的一組特性,它參照另一個表的主鍵。外來鍵連結這兩個表。另一種說法:在關聯式資料庫的上下文中,外來鍵是一組受某種包含依賴約束的特性,特別是由一個關係R中的外來鍵特性組成的元組必須也存在於其他一些(不一定是不同的)關係S中,而且這些屬性也必須是S中的候選鍵。[1][2][3]簡而言之,外來鍵是一組參照候選鍵的特性。 例如,名為TEAM的表可能有一個屬性 MEMBER_NAME,它參照PERSON表中的候選鍵PERSON_NAME作為外來鍵。 由於MEMBER_NAME是一個外來鍵,任何在TEAM中作為成員名稱存在的值也必須作為人名存在於PERSON表中; 換句話說,一個團隊的每個成員也是一個人。
概述
編輯包含外來鍵的表稱為子表(child table),包含候選鍵的表稱為「被參照表」(referenced )或父表(parent table)。[4]在資料庫關係建模和實現中,候選鍵是一組零個或多個特性,其值對於關係中的每個元組(行)保證是唯一的。任何元組的候選鍵特性的值或值組合不能與該關係中的任何其他元組重複。
由於外來鍵的目的是標識被參照表的某一行,所以一般要求外來鍵等於主表某行的候選鍵,否則沒有值(NULL[2])。此規則稱為兩個表之間的參照完整性約束。[5]因為違反這些約束可能是許多資料庫問題的根源,所以大多數資料庫管理系統提供了確保每個非空外來鍵對應於參照表的一行的機制。[6][7][8]
例如,考慮一個包含兩個表的資料庫:一個包含所有客戶數據的 CUSTOMER 表和一個包含所有客戶訂單的 ORDER 表。假設業務要求每個訂單必須指向一個客戶。為了在資料庫中反映這一點,在 ORDER 表中添加了一個外來鍵列(例如 CUSTOMERID),它參照了 CUSTOMER 的主鍵(例如 ID)。因為表的主鍵必須是唯一的,並且因為 CUSTOMERID 僅包含來自該主鍵欄位的值,所以我們可以假設,當它具有值時,CUSTOMERID 將標識出下訂單的特定客戶。但是,如果在刪除 CUSTOMER 表的行或更改 ID 列時 ORDER 表沒有保持最新,則上述約束不再保證成立,並且使用這些表可能會變得更加困難。許多現實世界的資料庫通過「停用」而不是物理刪除主表外來鍵,或者通過複雜的更新程式來解決這個問題,這些程式在需要更改時修改對外來鍵的所有參照。
外來鍵在資料庫設計中起着至關重要的作用。資料庫設計的一個重要部分是確保真實世界實體之間的關係通過參照反映在資料庫中,使用外來鍵從一個表參照到另一個表。[9]資料庫設計的另一個重要部分是資料庫規範化,其中表被分解並且外來鍵使得它們可以被重構。[10]
參照表(或子表)中的多行可能參照到被參照表(或父表)中的同一行。在這種情況下,兩個表之間的關係稱為參照表和被參照表之間的一對多關係。
此外,實際上,子表和父表可能是同一張表,即外來鍵指向同一張表。這種外來鍵在 SQL:2003 中稱為自參照(self-referencing)或遞歸外來鍵(recursive foreign key)。在資料庫管理系統中,這通常是通過將第一個和第二個參照連結到同一個表來完成的。
一個表可能有多個外來鍵,每個外來鍵可以有不同的父表。每個外來鍵都由資料庫系統獨立執行。因此,可以使用外來鍵建立表之間的級聯關係。
外來鍵定義為關係中的一個特性或一組特性,其值與另一個關係中的主鍵匹配。將此類約束添加到現有表的語法在 SQL:2003 中定義,如下所示。
ALTER TABLE 表名 ADD CONSTRAINT 外键名 FOREIGN KEY(外键字段名)
REFERENCES 外表表名(主键字段名)
[ON DELETE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}]
[ON UPDATE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}]
在REFERENCES
子句中省略列列表意味着外來鍵應參照到被參照表的主鍵。同樣,外來鍵可以定義為CREATE TABLE
陳述式的一部分。
CREATE TABLE child_table (
col1 INTEGER PRIMARY KEY,
col2 CHARACTER VARYING(20),
col3 INTEGER,
col4 INTEGER,
FOREIGN KEY(col3, col4) REFERENCES parent_table(col1, col2) ON DELETE CASCADE
)
如果外來鍵是一個單獨列,則可以使用下屬語法:
CREATE TABLE child_table (
col1 INTEGER PRIMARY KEY,
col2 CHARACTER VARYING(20),
col3 INTEGER,
col4 INTEGER REFERENCES parent_table(col1) ON DELETE CASCADE
)
外來鍵也可以用儲存程序陳述式定義:
sp_foreignkey child_table, parent_table, col3, col4
- child_table:
- parent_table: 該候選鍵必須已經定義了
- col3 和 col4: 外來鍵的名字。包括1列至8列。
參照動作
編輯在對主表做行刪除或修改時,為確保參照完整性,SQL:2003給出了5種「參照動作(referential actions):
CASCADE
編輯在對主表的行刪除或修改時,從表中有匹配的外來鍵值的行也相應被刪除或修改。
ON DELETE CASCADE修改了從表的行為,引入了對從表的自動刪除或修改的行為。
RESTRICT
編輯在對主表的行刪除或修改時,如果子表中有匹配的外來鍵值的行,則主表中相應的行不能被刪除或修改。
ON DELETE RESTRICT是對主表的行為約束,雖然寫在了從表的定義中。
RESTRICT未被Microsoft SQL Server 2012及更早的版本支援。
NO ACTION
編輯NO ACTION和RESTRICT非常像。但NO ACTION在嘗試修改主表後檢查參照完整性。如果在這種檢查之前執行了資料庫觸發器,可能在檢查時就不違背參照完整性。
SET NULL, SET DEFAULT
編輯從表中的外來鍵列被分別設為NULL或預設值。
Triggers
編輯參照動作通常被實現為隱含的觸發器(即通常是隱藏的、具有系統生成名稱的觸發器)。因此,它們受到與用戶定義觸發器相同的限制,並且它們相對於其他觸發器的執行順序可能需要經過考慮;在某些情況下,可能需要將參照操作替換為其等效的用戶定義觸發器,以確保正確的執行順序,或解決變異表(mutating-table)的限制。
另一個重要限制出現在事務隔離時:對行的更改可能無法完全級聯,這是因為該行被事務無法「看到」的數據所參照,因此無法級聯。一個例子:當事務嘗試重新編號客戶帳戶時,同時另一事務正在嘗試為同一客戶新增發票;雖然 CASCADE 規則可能會修改事務可以看到的所有發票行以使其與重新編號的客戶行保持一致,但它不會進入另一個事務來修改那裏的數據;因為資料庫不能保證兩個事務提交時數據一致,所以其中一個事務將被強制轉返(通常是先到先得)。
CREATE TABLE account (acct_num INT, amount DECIMAL(10,2));
CREATE TRIGGER ins_sum BEFORE INSERT ON account
FOR EACH ROW SET @sum = @sum + NEW.amount;
例子
編輯一個簡單的關係:
Supplier (SupplierNumber, Name, Address) Invoice (InvoiceNumber, Text, SupplierNumber)
資料定義語言陳述式為:
CREATE TABLE Supplier (
SupplierNumber INTEGER NOT NULL,
Name VARCHAR(20) NOT NULL,
Address VARCHAR(50) NOT NULL,
CONSTRAINT supplier_pk PRIMARY KEY(SupplierNumber),
CONSTRAINT number_value CHECK(SupplierNumber > 0)
)
CREATE TABLE Invoice (
InvoiceNumber INTEGER NOT NULL,
Text VARCHAR(4096),
SupplierNumber INTEGER NOT NULL,
CONSTRAINT invoice_pk PRIMARY KEY(InvoiceNumber),
CONSTRAINT inumber_value CHECK (InvoiceNumber > 0),
CONSTRAINT supplier_fk
FOREIGN KEY(SupplierNumber) REFERENCES Supplier(SupplierNumber)
ON UPDATE CASCADE ON DELETE RESTRICT
)
參考文獻
編輯- ^ Coronel, Carlos. Database Systems: Design, Implementation, and Management. Independence KY: South-Western/Cengage Learning. 2010: 65. ISBN 978-0-538-74884-1.
- ^ 2.0 2.1 Elmasri, Ramez. Fundamentals of Database Systems . Addison-Wesley. 2011: 73–74. ISBN 978-0-13-608620-8.
- ^ Date, C. J. A guide to the SQL standard. Addison-Wesley. 1996: 206. ISBN 978-0201964264.
- ^ Sheldon, Robert. Beginning MySQL. John Wiley & Sons. 2005: 119–122. ISBN 0-7645-7950-9.
- ^ Database Basics — Foreign Keys. [2010-03-13]. (原始內容存檔於2010-01-10).
- ^ MySQL AB. MySQL Administrator's Guide and Language Reference. Sams Publishing. 2006: 40. ISBN 0-672-32870-4.
- ^ Powell, Gavin. Oracle SQL: Jumpstart with Examples . Elsevier. 2004: 11. ASIN B008IU3AHY.
- ^ Mullins, Craig. DB2 developer's guide. IBM Press. 2012. ASIN B007Y6K9TK.
- ^ Sheldon, Robert. Beginning MySQL. John Wiley & Sons. 2005: 156. ISBN 0-7645-7950-9.
- ^ Garcia-Molina, Hector. Database Systems: The Complete Book . Prentice Hall. 2009: 93–95. ISBN 978-0-13-187325-4.