首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL 外鍵約束完整指南:建立語法、級聯動作、效能影響與最佳實踐

     編輯:MySQL 資料庫相關知識

外鍵核心作用

  • 參考完整性:子表外鍵值必須存在於父表主鍵/唯一鍵中。
  • 級聯傳播:父表刪除/更新時,自動處理子表關聯資料。
  • 防止孤兒資料:避免邏輯刪除導致子表殘留無效引用。

建立語法


-- 父表
CREATE TABLE parent (
  id INT PRIMARY KEY,
  name VARCHAR(50)
) ENGINE=InnoDB;

-- 子表建立外鍵
CREATE TABLE child (
  id INT PRIMARY KEY,
  parent_id INT,
  data VARCHAR(100),
  CONSTRAINT fk_child_parent 
    FOREIGN KEY (parent_id) 
    REFERENCES parent(id)
    ON DELETE CASCADE
    ON UPDATE CASCADE
) ENGINE=InnoDB;

-- 或 ALTER TABLE 新增
ALTER TABLE child 
ADD CONSTRAINT fk_child_parent 
FOREIGN KEY (parent_id) REFERENCES parent(id)
ON DELETE RESTRICT ON UPDATE RESTRICT;

五種級聯動作 (ON DELETE / ON UPDATE)

動作行為適用場景風險
CASCADE父變 → 子同步變 (刪父刪子、改父改子)強關聯、生命週期綁定 (訂單-明細)誤刪父表導致大量子資料連鎖刪除
SET NULL父變 → 子外鍵設 NULL (需欄位允許 NULL)弱關聯、子資料保留 (文章-分類)查詢需處理 NULL,語義變「未分類」
SET DEFAULT父變 → 子外鍵設預設值有明確預設分類/狀態MySQL 解析支援但**不執行**,實際同 RESTRICT
RESTRICT / NO ACTION父有子資料時禁止刪改 (預設)嚴格保護、需手動清理子資料應用層需捕獲錯誤碼 1451/1452

前置條件 (必檢清單)

  1. 父表被引用欄位為 **PRIMARY KEY** 或 **UNIQUE NOT NULL** 索引。
  2. 子表外鍵欄位**資料型別、長度、字符集、校對規則**與父表**完全一致**。
  3. 兩表皆為 **InnoDB** 引擎 (MyISAM 不支援外鍵)。
  4. 若父表有資料,子表外鍵值必須全數存在於父表,否則建立失敗。

效能與鎖影響

  • 插入/更新子表:需共享鎖 (S-lock) 鎖定父表對應記錄,驗證存在性,高併發下可能阻塞。
  • 刪除/更新父表:需排他鎖 (X-lock) 掃描子表匹配行,CASCADE 時鎖定更多行。
  • 死鎖風險:雙向外鍵、複雜事務易產生死鎖,應用層需重試邏輯。
  • 備份/遷移:mysqldump 預設導出外鍵定義,還原時需關閉檢查 SET FOREIGN_KEY_CHECKS=0;。

查看與管理


-- 查看表外鍵
SHOW CREATE TABLE child;
SELECT * FROM information_schema.TABLE_CONSTRAINTS WHERE TABLE_NAME='child';

-- 臨時關閉外鍵檢查 (匯入/大量操作)
SET FOREIGN_KEY_CHECKS=0;
-- 操作完成
SET FOREIGN_KEY_CHECKS=1;

-- 刪除外鍵
ALTER TABLE child DROP FOREIGN KEY fk_child_parent;

最佳實踐建議

  1. 核心業務強一致性場景 (訂單-明細、用戶-帳戶) 使用 CASCADE,配合應用層軟刪除 (is_deleted) 降低硬刪除風險。
  2. 弱關聯/分類標籤 使用 SET NULL,子表保留歷史資料。
  3. 高併發寫入服務:考慮**應用層維護完整性**,資料庫層**不建外鍵**,用分散式事務/事件總線保證最終一致性,避免鎖爭用。
  4. 命名規範:fk_子表_父表,便於 information_schema 查詢管理。
  5. 監控:關注 InnoDB_row_lock_waits、InnoDB_deadlocks 指標。

總結

外鍵是資料完整性「最後防線」,但帶來鎖爭用、死鎖、遷移複雜度。**微服務/高併發架構傾向應用層保證完整性,資料庫層弱化外鍵**;單體應用、內部管理系統、報表庫則建議啟用外鍵降低業務邏輯複雜度。根據架構層級權衡選擇。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved