外鍵是關系型數據庫維護參照完整性的核心機制。本文系統梳理 MySQL 外鍵的概念、使用條件、語法詳解、級聯行為及實戰案例。
INT 對 TINYINT 可,INT 對 CHAR 不可)。[CONSTRAINT symbol] FOREIGN KEY [id] (col_name, ...)
REFERENCES tbl_name (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 名稱時,MySQL 自動生成。| 關鍵字 | 行為描述 |
|---|---|
RESTRICT | 阻止父表操作,直到子表無關聯記錄(默認,最安全) |
CASCADE | 同步刪除/更新子表匹配行 |
SET NULL | 子表外鍵列置 NULL(列需允許 NULL) |
SET DEFAULT | 子表外鍵列置默認值 |
NO ACTION | 標準 SQL 行為,MySQL 中等同 RESTRICT |
-- 父表:倉庫表
CREATE TABLE repo_table (
repo_id CHAR(13) NOT NULL PRIMARY KEY,
repo_name CHAR(14) NOT NULL
) ENGINE=InnoDB;
-- 子表:業務表
CREATE TABLE busi_table (
busi_id CHAR(13) NOT NULL PRIMARY KEY,
busi_name CHAR(13) NOT NULL,
repo_id CHAR(13) NOT NULL,
FOREIGN KEY (repo_id) REFERENCES repo_table(repo_id)
) ENGINE=InnoDB;
INSERT INTO repo_table VALUES('12','sz'), ('13','cd'); -- 成功
INSERT INTO busi_table VALUES('1003','cd','13'), ('1002','sz','12'); -- 成功
INSERT INTO busi_table VALUES('1001','gx','11'); -- 失敗:ERROR 1452 父鍵不存在
ALTER TABLE busi_table
ADD CONSTRAINT fk_repo
FOREIGN KEY (repo_id) REFERENCES repo_table(repo_id)
ON DELETE CASCADE
ON UPDATE CASCADE;
現刪除父表 repo_id='12',子表關聯行自動刪除;更新父表主鍵,子表同步更新。
雖然 5.6+ 自動創建,但建議顯式聲明:
CREATE TABLE busi_table (
...
INDEX idx_repo_id (repo_id),
FOREIGN KEY (repo_id) REFERENCES repo_table(repo_id)
) ENGINE=InnoDB;
SET FOREIGN_KEY_CHECKS=0; 導入後重新啟用。