InnoDB 外鍵約束定義了父表記錄變更時子表的聯動行為。正確選擇 ON DELETE/ON UPDATE 規則對數據一致性與業務邏輯至關重要。
| 動作 | 父表 DELETE/UPDATE 時子表行為 | 適用場景 | MySQL 版本支援 |
|---|---|---|---|
| CASCADE | 同步刪除/更新匹配的子表記錄 | 強一致性、從屬關係明確(訂單-明細、分類-商品) | DELETE: 3.23.50+ UPDATE: 4.0.8+ |
| SET NULL | 將子表外鍵列置 NULL | 弱關聯、子表記錄需保留(日誌、審計、用戶刪除後文章保留) | DELETE: 3.23.50+ UPDATE: 4.0.8+ |
| NO ACTION | 若有匹配子記錄則拒絕父表操作(標準 SQL 延遲檢查) | 需應用層顯式處理子記錄、防止誤刪 | 4.0.8+ (ANSI SQL-92) |
| RESTRICT | 同 NO ACTION,但立即檢查(InnoDB 實際同義) | 同 NO ACTION | 所有版本 |
| SET DEFAULT | 解析器識別,但 InnoDB 不支援(報錯) | 不可用 | — |
NO ACTION 延遲至語句結束檢查,允許中間狀態暫時違反;RESTRICT 立即檢查。CREATE TABLE parent (
id INT PRIMARY KEY
) ENGINE=InnoDB;
CREATE TABLE child (
id INT PRIMARY KEY,
parent_id INT,
CONSTRAINT fk_child_parent
FOREIGN KEY (parent_id) REFERENCES parent(id)
ON DELETE CASCADE
ON UPDATE SET NULL
) ENGINE=InnoDB;
CASCADE DELETE 不會激活子表 BEFORE/AFTER DELETE TRIGGER。SET NULL 要求子表外鍵列允許 NULL(無 NOT NULL)。CASCADE DELETE 可能引發鎖升級、複製表膨脹,評估改為應用層分批刪除。SELECT TABLE_NAME, CONSTRAINT_NAME, DELETE_RULE, UPDATE_RULE, REFERENCED_TABLE_NAME, REFERENCED_COLUMN_NAME FROM information_schema.REFERENTIAL_CONSTRAINTS WHERE CONSTRAINT_SCHEMA = 'your_db';