| 選項 | 父表 DELETE | 父表 UPDATE | 說明 |
|---|---|---|---|
| RESTRICT / NO ACTION | 阻止 | 阻止 | 默認行為,子表有關聯記錄時拋錯 |
| CASCADE | 級聯刪除子表記錄 | 級聯更新子表外鍵值 | 保證引用完整性,慎用於大表 |
| SET NULL | 子表外鍵置 NULL | 子表外鍵置 NULL | 要求外鍵列允許 NULL |
| SET DEFAULT | 子表外鍵置默認值 | 子表外鍵置默認值 | MySQL 解析但忽略,實際同 RESTRICT |
CREATE DATABASE IF NOT EXISTS fk_demo CHARSET utf8mb4;
USE fk_demo;
-- 父表:用戶主檔
CREATE TABLE `user` (
`id` INT(4) NOT NULL,
`sex` ENUM('f','m') DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
-- 子表:用戶擴展信息
CREATE TABLE `userinfo` (
`sn` INT(4) NOT NULL AUTO_INCREMENT,
`userid` INT(4) NOT NULL,
`info` VARCHAR(20) DEFAULT NULL,
PRIMARY KEY (`sn`),
KEY `idx_userid` (`userid`),
CONSTRAINT `fk_userinfo_user` FOREIGN KEY (`userid`) REFERENCES `user` (`id`)
ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB;
INSERT INTO `user` (`id`,`sex`) VALUES (1,'f'), (2,'m'), (3,'f'); INSERT INTO `userinfo` (`userid`,`info`) VALUES (1,'2005054dsf'), (1,'fdsfewfdsfds'), (1,'gdsgergergrtre'), (2,'et34t5435435werwe'), (2,'435rtgtrhfghfg'), (2,'ret345tr4345'), (3,'fgbdfvbcbfdgr'), (3,'45r2343234were'), (3,'wfyhtyjtyjyjy');
-- 刪除用戶 2 DELETE FROM `user` WHERE `id` = 2; -- 驗證父表 SELECT * FROM `user`; -- 僅剩 1,3 -- 驗證子表:userid=2 的 3 條記錄自動刪除 SELECT * FROM `userinfo`; -- 僅剩 userid=1,3 的 6 條
-- 將用戶 1 的 id 改為 4 UPDATE `user` SET `id` = 4 WHERE `id` = 1; -- 驗證父表 SELECT * FROM `user`; -- id 變為 3,4 -- 驗證子表:userid 自動從 1 更新為 4 SELECT * FROM `userinfo`; -- userid 變為 3,4,數據完整保留
is_deleted)。KEY idx_fk (fk_col),便於審計與跨版本兼容。Seconds_Behind_Master。考慮 slave_parallel_workers + slave_preserve_commit_order=1 並行回放。CONSTRAINT fk_userinfo_user 命名規範:fk_子表_父表,避免 ERROR 1005 (HY000): Can't create table ... errno: 121。高併發、大數據量場景常放棄 DB 級外鍵,改由應用層保證:
SELECT * FROM child LEFT JOIN parent ON child.fk=parent.pk WHERE parent.pk IS NULL。UPDATE parent SET deleted=1 WHERE id=?,夜間批量清理孤兒子表數據。MySQL InnoDB 外鍵級聯功能完整且標準,**適用於中小表、強一致性要求高、寫入頻率低** 的場景。大表高併發建議應用層控制,犧牲部分自動化換取可控的性能與穩定性。