相關文件 下載本手冊
PDF (美式信紙) - 40.0Mb
PDF (A4) - 40.1Mb
Man Pages (TGZ) - 258.2Kb
Man Pages (Zip) - 365.3Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 9.0 參考手冊  /  ...  /  使用外鍵

5.6.6 使用外鍵

MySQL 支援外鍵,允許跨表格交叉參照相關資料,以及外鍵約束,有助於保持相關資料的一致性。

外鍵關聯涉及一個包含初始欄位值的父表格,以及一個具有參照父表格欄位值的欄位值的子表格。外鍵約束定義在子表格上。

以下範例透過單欄外鍵將 parentchild 表格關聯起來,並展示外鍵約束如何強制執行參照完整性。

使用以下 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 UPDATEON DELETE 子句指定的參照動作。省略 ON DELETEON UPDATE 子句(如目前的子表格定義中所示)與指定 RESTRICT 選項相同,該選項會拒絕影響父表格中具有父表格中相符列的索引鍵值的操作。

為了示範 ON DELETEON UPDATE 參照動作,請捨棄子表格並重新建立它,以包含具有 CASCADE 選項的 ON UPDATEON 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 節,「外鍵約束」