外鍵約束
如果公共關鍵字在一個關係中是主關鍵字,那麼這個公共關鍵字被稱爲另一個關係的外鍵
外鍵(FOREIGN KEY)
什麼是外鍵
假設有有A
、B
兩張數據表,A
表有一個字段id
用來唯一標識A
中的一條記錄,B
表有一個字段a_id
來關聯A
表的一條記錄,則字段a_id
被稱爲B
表的外鍵。
外鍵、主鍵的區別
-
定義
主鍵
:唯一標識一條記錄,不能有重複,不允許爲空,一張數據表只能有一個主鍵外鍵
:表的外鍵是另一張表中可以唯一標識的字段(如主鍵,一般都是主鍵),外鍵可以有重複值,可以是空值,一張數據表可以有多個外鍵
-
作用
主鍵
:用來保證數據完整性外鍵
:用來關聯其他數據表,保持數據一致性,完整性,主要目的是控制存儲在外鍵表中的數據
外鍵的功能
外鍵功能具有兩種形式。
1、 阻止執行
- 從表插入新行,其外鍵值不是主表的主鍵值便阻止插入
- 從表修改外鍵值,新值不是主表的主鍵值便阻止修改
- 主表刪除行,其主鍵值在從表裏存在便阻止刪除(要想刪除,必須先刪除從表的相關行)
- 主表修改主鍵值,舊值在從表裏存在便阻止修改(要想修改,必須先刪除從表的相關行)
2、級聯執行
- 主表刪除行,連帶從表的相關行一起刪除
- 主表修改主鍵值,連帶從表相關行的外鍵值一起修改
兩種方法提供給用戶選擇。無論選取哪種方法,從表裏都不會有多餘行。從另一個角度理解,用拒絕同一事物在從表中的標誌與主表不一致來實現與主表中的標誌一致。
MySQL中外鍵的介紹
- MySQL中只有
InnoDB
支持外鍵
- 由數據庫自身保證數據一致性,完整性,更可靠,因爲程序很難100%保證數據的完整性,而用
外鍵
即使在數據庫服務器當機或者出現其他問題的時候,也能夠最大限度的保證數據的一致性和完整性。 - 設置
外鍵約束
的兩個表之間會具有父子關係,即子表中外鍵
的字段的取值範圍由父表所決定 - 設置
外鍵
一定程度上降低數據庫的速度 - 子表的外鍵字段的數據類型和父表中要一致
外鍵約束的相關語法(MySQL)
創建標識生成外鍵約束(CREATE TABLE)
語法
CREATE TABLE table_name
(
.
.
key_name ...
...
CONSTRAINT constraint_name
FOREIGN KEY foreign_key_name (column_name1)
REFERENCES parent_table (column_name2)
ON DELETE action1
ON UPDATE action2
)
語法關鍵字詳解:
key_name
:用來當做外鍵的字段,用於下面FOREIGN KEY
子句CONSTRAINT
:爲外鍵約束定義約束名稱constraint_name
,如果省略它,MySQL將自動生成一個名稱FOREIGN KEY
:指定子表中關聯父表中記錄的字段column_name1
,可以在FOREIGN KEY
子句後放置一個外鍵名稱foreign_key_name
,或者MySQL自動創建一個名稱REFERENCES
:指定父表parent_table
及其在子表中被引用的列column_name2
ON DELETE
:定義當父表中的記錄被刪除時,子表的記錄要執行的操作action1
,如果省略ON DELETE
子句並刪除父表中的記錄,則MySQL將拒絕刪除子表中相關聯的數據。action1
有以下幾個選項:RESTRICT
(約束):當在父表(即外鍵的來源表)中刪除一條或多條記錄時,首先檢查該記錄是否有對應外鍵,如果有則不允許刪除。NO ACTION
:在MySQL中,同RESTRICT
,如果存在從數據,不允許刪除主數據CASCADE
(級聯):當在父表(即外鍵的來源表)中刪除一條或多條記錄記錄時,首先檢查該記錄是否有對應外鍵,如果有則也刪除外鍵在子表(即包含外鍵的表)中的記錄。SET NULL
:當在父表(即外鍵的來源表)中刪除一條或多條記錄時,首先檢查該記錄是否有對應外鍵,如果有則設置子表中該外鍵值爲null(注意:此時要求該外鍵允許爲null)
ON UPDATE
:定義在父表中的記錄更新時,子表中的記錄要執行的操作action2
,當父表中的行被更新時,如果省略ON UPDATE
子句,MySQL將拒絕對子表中的行的任何更新。action2
有以下幾個選項:RESTRICT
(約束):當在父表(即外鍵的來源表)中更新一條或多條記錄時,首先檢查該記錄是否有對應外鍵,如果有則不允許更新。NO ACTION
:在MySQL中,同RESTRICT
,如果存在從數據,不允許更新主數據CASCADE
(級聯):當在父表(即外鍵的來源表)中更新一條或多條記錄的主鍵值時,首先檢查該記錄是否有對應外鍵,有則更新子表中對應外鍵的值SET NULL
:當在父表(即外鍵的來源表)中更新一條或多條記錄時,首先檢查該記錄是否有對應外鍵,如果有則設置子表中該外鍵值爲null(注意:此時要求該外鍵允許爲null)。
示例
收貨地址表中用戶IDuser_id
設置爲外鍵,並定義約束
CREATE TABLE `address` (
`id` int(11) NOT NULL,
`user_id` int(11) DEFAULT NULL,
`address` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `c_user_id` FOREIGN KEY (`user_id`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
修改表結構時添加外鍵約束(ALTER TABLE)
語法
ALTER table_name
ADD CONSTRAINT constraint_name
FOREIGN KEY foreign_key_name(column_name1)
REFERENCES parent_table(column_name2)
ON DELETE action1
ON UPDATE action2;
語法關鍵字含義同上
示例
創建收貨地址表address
,給該表增加外鍵約束:用戶IDuser_id
設置爲外鍵,並定義約束
# 生成address表
CREATE TABLE `address` (
`id` int(11) NOT NULL,
`user_id` int(11) DEFAULT NULL,
`address` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
# 添加外鍵約束
ALTER `address`
ADD CONSTRAINT `c_user_id`
FOREIGN KEY `fk_user_id`(`user_id`)
REFERENCES `users`(`id`)
ON DELETE CASCADE
ON UPDATE CASCADE;
撤銷外鍵約束
ALTER TABLE table_name DROP FOREIGN KEY constraint_name;
語法關鍵字含義同上
示例
ALTER TABLE `address` DROP FOREIGN KEY `c_user_id`;