外來鍵又稱外部鍵，是指在關聯式資料庫中，每個資料表都是由關聯來連繫彼此的關係，父資料表的主鍵會放在另一個資料表，當做屬性以建立彼此的關聯，而這個屬性就是外來鍵。 比如，學生跟老師之間是教學的關聯，學生資料表會有個屬性叫指導老師 FK，而這個值就是對應到老師資料表的老師代號 PK，學生的指導老師就是外來鍵。 外部索引鍵是表中的一組特性，它引用另一個表的主鍵。外部索引鍵連結這兩個表。另一種說法：在關係資料庫的上下文中，外部索引鍵是一組受某種包含依賴約束的特性，特別是由一個關係 R 中的外部索引鍵特性組成的元組必須也存在於其他一些（不一定是不同的）關係 S 中，而且這些屬性也必須是 S 中的候選鍵。簡而言之，外部索引鍵是一組引用候選鍵的特性。 例如，名為 TEAM 的表可能有一個屬性 MEMBER_NAME，它引用 PERSON 表中的候選鍵 PERSON_NAME 作為外部索引鍵。 由於 MEMBER_NAME 是一個外部索引鍵，任何在 TEAM 中作為成員名稱存在的值也必須作為人名存在於 PERSON 表中； 換句話說，一個團隊的每個成員也是一個人。 概述 包含外部索引鍵的表稱為子表 child table，包含候選鍵的表稱為 被引用表referenced 或父表 parent table。在資料庫關係建模和實現中，候選鍵是一組零個或多個特性，其值對於關係中的每個元組（行）保證是唯一的。任何元組的候選鍵特性的值或值組合不能與該關係中的任何其他元組重複。 由於外部索引鍵的目的是標識被引用表的某一行，所以一般要求外部索引鍵等於主表某行的候選鍵，否則沒有值（NULL）。此規則稱為兩個表之間的參照完整性約束。因為違反這些約束可能是許多資料庫問題的根源，所以大多數資料庫管理系統提供了確保每個非空外部索引鍵對應於引用表的一行的機制。 例如，考慮一個包含兩個表的資料庫：一個包含所有客戶資料的 CUSTOMER 表和一個包含所有客戶訂單的 ORDER 表。假設業務要求每個訂單必須指向一個客戶。為了在資料庫中反映這一點，在 ORDER 表中添加了一個外部索引鍵列（例如 CUSTOMERID），它引用了 CUSTOMER 的主鍵（例如 ID）。因為表的主鍵必須是唯一的，並且因為 CUSTOMERID 僅包含來自該主鍵欄位的值，所以我們可以假設，當它具有值時，CUSTOMERID 將標識出下訂單的特定客戶。但是，如果在刪除 CUSTOMER 表的行或更改 ID 列時 ORDER 表沒有保持最新，則上述約束不再保證成立，並且使用這些表可能會變得更加困難。許多現實世界的資料庫透過 停用 而不是物理刪除主表外部索引鍵，或者透過複雜的更新程式來解決這個問題，這些程式在需要更改時修改對外部索引鍵的所有引用。 外部索引鍵在資料庫設計中起著至關重要的作用。資料庫設計的一個重要部分是確保真實世界實體之間的關係透過引用反映在資料庫中，使用外部索引鍵從一個表引用到另一個表。資料庫設計的另一個重要部分是資料庫規範化，其中表被分解並且外部索引鍵使得它們可以被重構。 引用表（或子表）中的多行可能引用到被引用表（或父表）中的同一行。在這種情況下，兩個表之間的關係稱為引用表和被引用表之間的一對多關係。 此外，實際上，子表和父表可能是同一張表，即外部索引鍵指向同一張表。這種外部索引鍵在 SQL2003 中稱為自引用 selfreferencing 或遞迴外部索引鍵 recursive foreign key。在資料庫管理系統中，這通常是透過將第一個和第二個引用連結到同一個表來完成的。 一個表可能有多個外部索引鍵，每個外部索引鍵可以有不同的父表。每個外部索引鍵都由資料庫系統獨立執行。因此，可以使用外部索引鍵建立表之間的級聯關係。 外部索引鍵定義為關係中的一個特性或一組特性，其值與另一個關係中的主鍵匹配。將此類約束新增到現有表的語法在 SQL2003 中定義，如下所示。 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 列。 引用動作 在對主表做行刪除或修改時，為確保引用完整性，SQL2003 給出了 5 種 引用動作（referential actions）： CASCADE RESTRICT NO ACTION SET NULL SET DEFAULT 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 引用動作通常被實現為隱含的觸發器（即通常是隱藏的、具有系統生成名稱的觸發器）。因此，它們受到與使用者定義觸發器相同的限制，並且它們相對於其他觸發器的執行順序可能需要經過考慮；在某些情況下，可能需要將引用操作替換為其等效的使用者定義觸發器，以確保正確的執行順序，或解決變異表 mutatingtable 的限制。 另一個重要限制出現在事務隔離時：對行的更改可能無法完全級聯，這是因為該行被事務無法 看到 的資料所引用，因此無法級聯。一個例子：當事務嘗試重新編號客戶帳戶時，同時另一事務正在嘗試為同一客戶建立新發票；雖然 CASCADE 規則可能會修改事務可以看到的所有發票行以使其與重新編號的客戶行保持一致，但它不會進入另一個事務來修改那裡的資料；因為資料庫不能保證兩個事務提交時資料一致，所以其中一個事務將被強制回滾（通常是先到先得）。 CREATE TABLE account acct_num INT amount DECIMAL 102 CREATE TRIGGER ins_sum BEFORE INSERT ON account FOR EACH ROW SET sum sum NEWamount 例子 一個簡單的關係： 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 參考文獻 外部連結 一個詳細介紹外部索引鍵的網站 SQL99 Foreign Keys PostgreSQL Foreign Keys MySQL Foreign Keys FirebirdSQL primary Keys SQLite support for Foreign Keys Microsoft SQL 2012 table_constraint TransactSQL Category 資料庫管理系統