CREATE TABLE ... LIKE 能复制表结构是因为它直接拷贝源表的列定义、索引、自增值、字符集和排序规则等元数据,但不复制数据、触发器、外键约束和注释。

CREATE TABLE LIKE 为什么能复制表结构
CREATE TABLE ... LIKE 是 MySQL 原生支持的语法,它会完整拷贝源表的列定义、索引(包括主键、唯一键、普通 KEY)、自增起始值、字符集和排序规则,但不复制数据、触发器、外键约束(注意:外键定义本身也不会被复制)、注释(MySQL 5.7+ 对部分注释有保留,但不可靠)。
它本质是“结构快照”,不是 DDL 解析重写,所以速度快、语义明确、跨存储引擎也基本可用(比如从 InnoDB LIKE 出 MyISAM 表结构是允许的,但实际建表时需显式指定 ENGINE)。
执行 CREATE TABLE LIKE 的正确姿势
最简命令就是:CREATE TABLE new_table LIKE old_table;。但真实场景中常需调整,必须注意以下几点:
- 目标表名
new_table必须不存在,否则报错ERROR 1050 (42S01): Table 'xxx' already exists - 如果要改存储引擎,必须在
LIKE后显式加ENGINE=xxx,例如:CREATE TABLE new_table ENGINE=InnoDB LIKE old_table;—— 仅靠DEFAULT_STORAGE_ENGINE不生效 - 如果源表有分区,
LIKE会复制分区定义(MySQL 5.6+),但若目标 MySQL 版本不支持该分区类型(如 NDB),会直接失败 - 目标库必须有
CREATE和SELECT权限;如果跨库操作,要用db_name.table_name全限定名
为什么不能用 CREATE TABLE AS SELECT 复制结构
CREATE TABLE new_table AS SELECT * FROM old_table LIMIT 0; 看似能“空跑”出结构,但它只复制列定义和 NOT NULL 属性,**完全丢失索引、主键、自增值、默认值表达式、生成列定义、CHECK 约束等关键元数据**。
常见后果包括:
- 新表查起来慢——因为没索引,
EXPLAIN显示全表扫描 - 插入时报错——比如原表主键自增,新表没主键,或主键存在但没
AUTO_INCREMENT - 应用逻辑崩——依赖
DEFAULT CURRENT_TIMESTAMP或生成列的字段变成 NULL 或报错
它适合临时导出“带数据的轻量结构”,但绝不能替代 LIKE 做结构迁移。
复制后还要做什么才真正可用
CREATE TABLE LIKE 只解决“结构冷拷贝”,离生产可用还差几步:
- 手动补外键:
ALTER TABLE new_table ADD CONSTRAINT ... FOREIGN KEY (...) REFERENCES ...——LIKE不带外键,必须自己加 - 检查并补注释:用
SHOW CREATE TABLE old_table对比COMMENT字段,手工ALTER TABLE ... COMMENT='xxx' - 确认字符集:如果源表是
utf8mb4_unicode_ci,而目标库默认是latin1,新建表可能意外用了错误 collation,建议显式声明:CREATE TABLE new_table CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci LIKE old_table; - 触发器、存储过程、视图——这些完全不在
LIKE范围内,得单独导出再导入
结构复制只是起点,真正还原一张表,索引、约束、上下文元数据一个都不能少,漏掉任意一项都可能在某次查询或写入时突然暴露。










