外來鍵

外來鍵又稱外部鍵，是指在關聯式資料庫中，每個資料表都是由關聯來連繫彼此的關係，父資料表會放在另一個資料表，當做屬性以建立彼此的關聯，而這個屬性就是外來鍵。比如，學生跟老師之間是教學的關聯，學生資料表會有個屬性叫指導老師(FK)，而這個值就是對應到老師資料表的老師代號(PK)，學生的指導老師就是外來鍵。外來鍵是表中的一組特性，它引用另一個表的主鍵。外來鍵連結這兩個表。另一種說法：在關係資料庫的上下文中，外來鍵是一組受某種包含依賴約束的特性，特別是由一個關係R中的外來鍵特性組成的元組必須也存在於其他一些關係S中，而且這些屬性也必須是S中的候選鍵。簡而言之，外來鍵是一組引用候選鍵的特性。 例如，名為TEAM的表可能有一個屬性 MEMBER_NAME，它引用PERSON表中的候選鍵PERSON_NAME作為外來鍵。 由於MEMBER_NAME是一個外來鍵，任何在TEAM中作為成員名稱存在的值也必須作為人名存在於PERSON表中； 換句話說，一個團隊的每個成員也是一個人。概述.包含外來鍵的表稱為子表(child table)，包含候選鍵的表稱為“被引用表”(referenced )或父表(parent table)。在資料庫關係建模和實現中，候選鍵是一組零個或多個特性，其值對於關係中的每個元組保證是唯一的。任何元組的候選鍵特性的值或值組合不能與該關係中的任何其他元組重複。由於外來鍵的目的是標識被引用表的某一行，所以一般要求外來鍵等於主表某行的候選鍵，否則沒有值。此規則稱為兩個表之間的參照完整性約束。因為違反這些約束可能是許多資料庫問題的根源，所以大多數資料庫管理系統提供了確保每個非空外來鍵對應於引用表的一行的機制。例如，考慮一個包含兩個表的資料庫：一個包含所有客戶資料的 CUSTOMER 表和一個包含所有客戶訂單的 ORDER 表。假設業務要求每個訂單必須指向一個客戶。為了在資料庫中反映這一點，在 ORDER 表中添加了一個外來鍵列。因為表的主鍵必須是唯一的，並且因為 CUSTOMERID 僅包含來自該主鍵欄位的值，所以我們可以假設，當它具有值時，CUSTOMERID 將標識出下訂單的特定客戶。但是，如果在刪除 CUSTOMER 表的行或更改 ID 列時 ORDER 表沒有保持最新，則上述約束不再保證成立，並且使用這些表可能會變得更加困難。許多現實世界的資料庫透過“停用”而不是物理刪除主表外來鍵，或者透過複雜的更新程式來解決這個問題，這些程式在需要更改時修改對外來鍵的所有引用。外來鍵在資料庫設計中起著至關重要的作用。資料庫設計的一個重要部分是確保真實世界實體之間的關係透過引用反映在資料庫中，使用外來鍵從一個表引用到另一個表。資料庫設計的另一個重要部分是資料庫規範化，其中表被分解並且外來鍵使得它們可以被重構。引用表中的同一行。在這種情況下，兩個表之間的關係稱為引用表和被引用表之間的一對多關係。此外，實際上，子表和父表可能是同一張表，即外來鍵指向同一張表。這種外來鍵在 中稱為自引用(self-referencing)或遞迴外來鍵(recursive foreign key)。在資料庫管理系統中，這通常是透過將第一個和第二個引用連結到同一個表來完成的。一個表可能有多個外來鍵，每個外來鍵可以有不同的父表。每個外來鍵都由資料庫系統獨立執行。因此，可以使用外來鍵建立表之間的級聯關係。外來鍵定義為關係中的一個特性或一組特性，其值與另一個關係中的主鍵匹配。將此類約束新增到現有表的語法在 中定義，如下所示。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}]在codice_1子句中省略列列表意味著外來鍵應引用到被引用表的主鍵。同樣，外來鍵可以定義為codice_2語句的一部分。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引用動作.在對主表做行刪除或修改時，為確保引用完整性，給出了5種“引用動作：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 accountFOR 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 &gt; 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 &gt; 0),CONSTRAINT supplier_fkFOREIGN KEY(SupplierNumber) REFERENCES Supplier(SupplierNumber)ON UPDATE CASCADE ON DELETE RESTRICT