CREATE TABLE LIKE 能复制列定义(含 NOT NULL、DEFAULT、AUTO_INCREMENT)、主键、所有索引、字符集、排序规则和自增起始值;不能复制外键、触发器、表注释(8.0.23+ 支持列注释)、分区、生成列或 CHECK 约束。

CREATE TABLE LIKE 能复制哪些结构
CREATE TABLE LIKE 是纯 DDL 操作,不读数据、不扫描行,毫秒级完成。它能复制:列定义(含 NOT NULL、DEFAULT、AUTO_INCREMENT)、主键、所有索引(PRIMARY KEY、UNIQUE KEY、KEY)、字符集(CHARSET)和排序规则(COLLATE)、自增起始值(如 AUTO_INCREMENT=1001)。
不能复制的包括:FOREIGN KEY 约束(只留列和索引,不建 CONSTRAINT)、触发器、表注释(MySQL 8.0.23+ 才支持)、分区定义、生成列(GENERATED ALWAYS AS)、CHECK 约束(即使 8.0.16+ 启用,LIKE 也不复制)。
常见翻车点:DESCRIBE new_table 看起来一模一样,但执行 INSERT 时爆出 ERROR 1452 (23000): Cannot add or update a child row——其实是外键没被复制,新表根本没约束,只是字段名碰巧对得上。
为什么 CREATE TABLE LIKE 会报错 Table 'xxx' already exists
这个错误不是语法问题,而是目标表已存在。CREATE TABLE LIKE 不支持 IF NOT EXISTS(MySQL 目前仍不支持),所以必须提前检查或手动清理。
安全做法是加一层判断(在应用层或存储过程里):
- 先查
SELECT 1 FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = 'new_table' - 或者直接用
DROP TABLE IF EXISTS new_table再执行CREATE TABLE new_table LIKE old_table(注意:线上环境慎用DROP)
别指望 CREATE TABLE IF NOT EXISTS new_table LIKE old_table —— 这句语法错误,MySQL 不识别。
跨库复制结构时字符集可能降级
如果源表在 db_a(字符集 utf8mb4_unicode_ci),你在 db_b 执行 CREATE TABLE db_b.new_t LIKE db_a.old_t,新表大概率还是 utf8mb4_unicode_ci;但如果 db_b 的默认字符集是 latin1,且没显式指定库级设置,某些旧版本 MySQL(如 5.7.33 之前)会 fallback 到库默认值。
验证方式很简单:SHOW CREATE TABLE new_t,看输出里 DEFAULT CHARSET= 和 COLLATE= 是否与原表一致。
补救办法只有重建:DROP TABLE new_t,然后在目标库先执行 ALTER DATABASE db_b CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci,再重试 LIKE。
复制后怎么补外键和注释
CREATE TABLE LIKE 不动外键和注释,这两项必须手动补。
提取原表外键最稳妥的方式是:SHOW CREATE TABLE old_table,复制其中以 CONSTRAINT `fk_... 开头的整段 ADD CONSTRAINT 语句,把表名替换成新表名,再执行。
表注释补起来更简单:ALTER TABLE new_table COMMENT = '这里是原表注释'。
注意:如果原表有多个外键,SHOW CREATE TABLE 输出里它们是分散在不同位置的,别漏掉;也别直接照抄 CREATE TABLE 语句开头那段——那只是建表部分,约束在后面。
真正容易被忽略的是:外键列上的索引必须已存在(LIKE 已复制),否则 ADD CONSTRAINT 会失败并报 ERROR 1822 (HY000)。


















