外鍵是關係型資料庫維護引用完整性的核心機制。MySQL 僅 InnoDB 引擎支援外鍵,本文系統梳理建立條件、語法選項、級聯行為與實戰注意事項。
INT 對應 INT/BIGINT/SMALLINT,CHAR(10) 對應 VARCHAR(10)),嚴禁 INT 對應 CHAR 等跨類別映射。[CONSTRAINT symbol] FOREIGN KEY [id] (index_col_name, ...)
REFERENCES tbl_name (index_col_name, ...)
[ON DELETE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}]
[ON UPDATE {RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT}]
CREATE TABLE 時定義ALTER TABLE 時添加若省略 CONSTRAINT symbol,MySQL 自動生成名稱(如 tbl_name_ibfk_1)。
| 選項 | 父表刪除/更新時,子表行為 | 適用場景 |
|---|---|---|
RESTRICT | 阻止父表操作,拋出錯誤 | 嚴格保護歷史數據,防止誤刪(預設) |
CASCADE | 同步刪除/更新子表關聯行 | 訂單-明細、分類-商品等強生命週期綁定 |
SET NULL | 子表外鍵列置 NULL(需列允許 NULL) | 用戶-文章、客戶-訂單等弱關聯,保留子記錄 |
NO ACTION | 同 RESTRICT(標準 SQL 語義) | 明確語義表達 |
SET DEFAULT | 子表外鍵列置預設值(需列有 DEFAULT) | 極少用,MySQL 解析器識別但 InnoDB 拒絕執行 |
-- 父表
CREATE TABLE departments (
dept_id INT PRIMARY KEY,
name VARCHAR(50)
) ENGINE=InnoDB;
-- 子表,員工歸屬部門
CREATE TABLE employees (
emp_id INT PRIMARY KEY,
name VARCHAR(50),
dept_id INT,
INDEX idx_dept (dept_id),
CONSTRAINT fk_emp_dept
FOREIGN KEY (dept_id) REFERENCES departments(dept_id)
ON DELETE SET NULL
ON UPDATE CASCADE
) ENGINE=InnoDB;
innodb_lock_wait_timeout 適當調大,應用層捕獲重試。SET FOREIGN_KEY_CHECKS=0; 導入後 SET FOREIGN_KEY_CHECKS=1;。mysqldump 自動處理順序;手動恢復需先導入父表再導入子表。SELECT * FROM information_schema.TABLE_CONSTRAINTS WHERE CONSTRAINT_TYPE='FOREIGN KEY';