MySQL 透過外鍵約束維護表與表之間的參考完整性,確保資料一致性並支援級聯操作。僅 InnoDB 儲存引擎支援(MyISAM 不支援)。
[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}]
若省略 CONSTRAINT symbol,MySQL 自動生成名稱(如 table_ibfk_1)。
| 參數 | 行為 |
|---|---|
| RESTRICT | 阻止父表刪除/更新(預設) |
| CASCADE | 同步刪除/更新子表關聯行 |
| SET NULL | 子表外鍵欄位設為 NULL(欄位需允許 NULL) |
| SET DEFAULT | 設為預設值(較少用) |
| NO ACTION | 同 RESTRICT,標準 SQL 語法 |
-- 建表
CREATE TABLE `dage` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(32) DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
CREATE TABLE `xiaodi` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`dage_id` INT(11) DEFAULT NULL,
`name` VARCHAR(32) DEFAULT '',
PRIMARY KEY (`id`),
KEY `dage_id` (`dage_id`),
CONSTRAINT `xiaodi_ibfk_1` FOREIGN KEY (`dage_id`) REFERENCES `dage` (`id`)
) ENGINE=InnoDB;
-- 插入測試資料
INSERT INTO dage(name) VALUES('銅鑼灣');
INSERT INTO xiaodi(dage_id, name) VALUES(1, '銅鑼灣_小弟A');
-- 預設 RESTRICT:無法刪除有小弟的大哥
DELETE FROM dage WHERE id=1; -- ERROR 1451
-- 改為 CASCADE 後重試
ALTER TABLE xiaodi DROP FOREIGN KEY xiaodi_ibfk_1;
ALTER TABLE xiaodi ADD FOREIGN KEY(dage_id) REFERENCES dage(id) ON DELETE CASCADE ON UPDATE CASCADE;
DELETE FROM dage WHERE id=1; -- 成功,小弟同步被刪
外鍵完整性檢查會消耗資源,尤其在複雜關聯樹下。若追求極致寫入效能且業務層已保證一致性,可考慮 MyISAM 或應用層維護;若需資料庫層面強一致性,InnoDB + 外鍵是標準選擇。