MySQL 支援外鍵,允許跨表格交叉參照相關資料,以及外鍵約束,有助於保持相關資料的一致性。
外鍵關聯涉及一個包含初始欄位值的父表格,以及一個具有參照父表格欄位值的欄位值的子表格。外鍵約束定義在子表格上。
以下範例透過單欄外鍵將 parent
和 child
表格關聯起來,並展示外鍵約束如何強制執行參照完整性。
使用以下 SQL 陳述式建立父表格和子表格
CREATE TABLE parent (
id INT NOT NULL,
PRIMARY KEY (id)
) ENGINE=INNODB;
CREATE TABLE child (
id INT,
parent_id INT,
INDEX par_ind (parent_id),
FOREIGN KEY (parent_id)
REFERENCES parent(id)
) ENGINE=INNODB;
將一列插入父表格,如下所示
mysql> INSERT INTO parent (id) VALUES ROW(1);
驗證資料是否已插入。您只需從 parent
選取所有列即可執行此操作,如下所示
mysql> TABLE parent;
+----+
| id |
+----+
| 1 |
+----+
使用以下 SQL 陳述式將一列插入子表格
mysql> INSERT INTO child (id,parent_id) VALUES ROW(1,1);
插入操作成功,因為父表格中存在 parent_id
1。
將 parent_id
值不在父表格中的列插入子表格會被拒絕並出現錯誤,如下所示
mysql> INSERT INTO child (id,parent_id) VALUES ROW(2,2);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails
(`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`)
REFERENCES `parent` (`id`))
操作失敗,因為父表格中不存在指定的 parent_id
值。
嘗試從父表格中刪除先前插入的列也會失敗,如下所示
mysql> DELETE FROM parent WHERE id VALUES = 1;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails
(`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`)
REFERENCES `parent` (`id`))
此操作失敗,因為子表格中的記錄包含參照的 id (parent_id
) 值。
當操作影響父表格中具有子表格中相符列的索引鍵值時,結果取決於 FOREIGN KEY
子句的 ON UPDATE
和 ON DELETE
子句指定的參照動作。省略 ON DELETE
和 ON UPDATE
子句(如目前的子表格定義中所示)與指定 RESTRICT
選項相同,該選項會拒絕影響父表格中具有父表格中相符列的索引鍵值的操作。
為了示範 ON DELETE
和 ON UPDATE
參照動作,請捨棄子表格並重新建立它,以包含具有 CASCADE
選項的 ON UPDATE
和 ON DELETE
子句。CASCADE
選項會在刪除或更新父表格中的列時,自動刪除或更新子表格中的相符列。
DROP TABLE child;
CREATE TABLE child (
id INT,
parent_id INT,
INDEX par_ind (parent_id),
FOREIGN KEY (parent_id)
REFERENCES parent(id)
ON UPDATE CASCADE
ON DELETE CASCADE
) ENGINE=INNODB;
使用此處顯示的陳述式將一些列插入子表格
mysql> INSERT INTO child (id,parent_id) VALUES ROW(1,1), ROW(2,1), ROW(3,1);
驗證資料是否已插入,如下所示
mysql> TABLE child;
+------+-----------+
| id | parent_id |
+------+-----------+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
+------+-----------+
使用此處顯示的 SQL 陳述式,將父表格中的 ID 從 1 更新為 2
mysql> UPDATE parent SET id = 2 WHERE id = 1;
透過從父表格中選取所有列來驗證更新是否成功,如下所示
mysql> TABLE parent;
+----+
| id |
+----+
| 2 |
+----+
驗證 ON UPDATE CASCADE
參照動作是否已更新子表格,如下所示
mysql> TABLE child;
+------+-----------+
| id | parent_id |
+------+-----------+
| 1 | 2 |
| 2 | 2 |
| 3 | 2 |
+------+-----------+
為了示範 ON DELETE CASCADE
參照動作,請從 parent_id = 2
的父表格中刪除記錄;這會刪除父表格中的所有記錄。
mysql> DELETE FROM parent WHERE id = 2;
因為子表格中的所有記錄都與 parent_id = 2
相關聯,所以 ON DELETE CASCADE
參照動作會從子表格中刪除所有記錄,如下所示
mysql> TABLE child;
Empty set (0.00 sec)
如需外鍵約束的更多資訊,請參閱第 15.1.20.5 節,「外鍵約束」。