萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 資料庫 >> MySQL 教學

MySQL 外鍵約束完整指南:建立、級聯刪除更新、錯誤代碼 1451/1452 排查

前置條件

  • 兩表皆為 InnoDB 引擎(MyISAM 不支援外鍵)。
  • 外鍵欄位**必須有索引**(5.6+ 建立外鍵自動創建,舊版需手動)。
  • 關聯欄位**資料型別相容**(如 INT 對 INT、BIGINT 對 BIGINT,不可 INT 對 VARCHAR)。

建立外鍵語法

ALTER TABLE `child_table`
ADD CONSTRAINT `fk_name`
FOREIGN KEY (`child_col`)
REFERENCES `parent_table` (`parent_col`)
ON DELETE CASCADE
ON UPDATE CASCADE;

參照動作(ON DELETE / ON UPDATE)

動作行為適用場景
CASCADE父表刪除/更新 → 子表關聯行同步刪除/更新強一致性,如 訂單-明細、文章-評論
SET NULL父表刪除/更新 → 子表外鍵欄位設 NULL(需欄位允許 NULL)保留子記錄但解除關聯,如 用戶-文章(用戶刪除文章保留)
RESTRICT / NO ACTION拒絕父表刪除/更新(有子行存在時)保護主資料不被誤刪,預設行為
SET DEFAULTInnoDB 不支援—

實戰案例:文章-分類

建表

CREATE TABLE `category` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    `name` CHAR(16) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `article` (
    `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    `category_id` INT NOT NULL,
    `name` CHAR(16) NOT NULL,
    KEY `fk_cat` (`category_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

加外鍵(預設 RESTRICT)

ALTER TABLE `article`
ADD CONSTRAINT `fk_cat` FOREIGN KEY (`category_id`) REFERENCES `category` (`id`);

測試預設行為

  • 刪除分類 DELETE FROM category WHERE id=1 → 報錯 1451:Cannot delete or update a parent row。
  • 新增不存在分類的文章 INSERT INTO article(category_id,name) VALUES(2,'x') → 報錯 1452:Cannot add or update a child row。

改為級聯刪除/更新

ALTER TABLE article DROP FOREIGN KEY fk_cat;
ALTER TABLE `article`
ADD CONSTRAINT `fk_cat` FOREIGN KEY (`category_id`)
REFERENCES `category` (`id`)
ON DELETE CASCADE ON UPDATE CASCADE;
  • 刪除分類 → 關聯文章同步刪除。
  • 更新分類 ID → 文章外鍵同步更新。

常見錯誤代碼速查

  • 1451:父表操作被子表記錄阻擋(RESTRICT/NO ACTION)。
  • 1452:子表插入/更新的外鍵值在父表不存在。
  • 1215:Cannot add foreign key constraint(型別不符、缺索引、引擎非 InnoDB、字元集/排序規則不一致)。

效能與架構建議

  • 高並發寫入場景慎用外鍵(鎖競爭、死鎖風險),改由應用層維護一致性。
  • 大表 ALTER TABLE ADD FOREIGN KEY 會鎖表,建議低峰期或用 pt-online-schema-change。
  • 複寫環境下外鍵可能導致從庫 SQL 線程阻塞,評估風險後再啟用。
copyright © 萬盛學電腦網 all rights reserved