MySQL 僅 InnoDB 支援外鍵約束。本文提供標準建表語法、ALTER TABLE 事後加外鍵、命名慣例、錯誤常見原因(引擎、欄位型別不符、索引缺失)。
DROP TABLE IF EXISTS `blog`;
CREATE TABLE `blog` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`title` VARCHAR(100) DEFAULT NULL,
`content` TEXT,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
DROP TABLE IF EXISTS `comment`;
CREATE TABLE `comment` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`user` VARCHAR(50) DEFAULT NULL,
`email` VARCHAR(100) DEFAULT NULL,
`content` TEXT,
`add_time` DATETIME DEFAULT NULL,
`blog_id` INT(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FK_comment_blog` (`blog_id`),
CONSTRAINT `FK_comment_blog` FOREIGN KEY (`blog_id`) REFERENCES `blog` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 1. 先確保有索引
ALTER TABLE `comment` ADD INDEX `idx_blog_id` (`blog_id`);
-- 2. 新增外鍵約束
ALTER TABLE `comment`
ADD CONSTRAINT `FK_comment_blog`
FOREIGN KEY (`blog_id`) REFERENCES `blog` (`id`);
FOREIGN KEY (`blog_id`) REFERENCES `blog` (`id`)
ON DELETE CASCADE -- 刪除文章時,級聯刪除留言
ON UPDATE CASCADE -- 文章 ID 變更時,同步更新留言
-- 其他選項:SET NULL, RESTRICT, NO ACTION, SET DEFAULT
| 錯誤 | 原因 | 解決 |
|---|---|---|
| Can't create table (errno: 150) | 引擎非 InnoDB | 兩表皆設 ENGINE=InnoDB |
| Data type mismatch | 參考欄位型別/長度/簽名不一致 | 主鍵 INT(11),外鍵必須同為 INT(11) |
| No index on referenced column | 主表主鍵無索引(極罕見) | 主鍵自動有索引,檢查是否被刪 |
| No index on foreign key column | 子表外鍵欄位無索引 | 建立索引 KEY (blog_id) |
| Charset/Collation mismatch | 兩表字符集/排序規則不同 | 統一 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci |
SHOW CREATE TABLE comment\G
-- 或
SELECT * FROM information_schema.TABLE_CONSTRAINTS
WHERE CONSTRAINT_TYPE='FOREIGN KEY' AND TABLE_SCHEMA='db_name'
ALTER TABLE comment DROP FOREIGN KEY FK_comment_blog;