create table ... like 是首选,因它直接拷贝源表元数据快照,继承列定义、索引、auto_increment值、字符集等,但不继承外键、触发器、注释和生成列;而 as select 仅推导字段类型,丢失索引、主键、约束等关键结构。

直接用 CREATE TABLE ... LIKE,这是最快、最原生、语义最明确的方式。 它不是“模拟”结构,而是直接拷贝元数据快照,比任何导出再改写都可靠。
为什么 CREATE TABLE ... LIKE 是首选
它在 MySQL 内部跳过 SQL 解析重写,直接读取源表的 frm(或数据字典)信息,所以速度快、兼容性好、不依赖字符集或引擎是否匹配(比如从 InnoDB LIKE 出 MyISAM 表结构是允许的,只要建表时显式指定 ENGINE)。
- 会继承:列定义、主键、所有索引(
UNIQUE、FULLTEXT、空间索引)、AUTO_INCREMENT当前值、CHARSET和COLLATE、分区定义(MySQL 5.6+) - 不会继承:外键约束、触发器、注释(
COMMENT)、默认值表达式(如DEFAULT CURRENT_TIMESTAMP,部分版本会变成字面字符串)、生成列(GENERATED)的计算逻辑 - 目标表名必须不存在,否则报错
ERROR 1050 (42S01)
CREATE TABLE ... AS SELECT * FROM ... LIMIT 0 为什么不能替代
这个写法看似“没数据”,但本质是基于查询结果推导建表结构,丢失大量关键元数据:
- 完全丢掉索引、主键、
NOT NULL以外的所有约束(CHECK、FOREIGN KEY) -
AUTO_INCREMENT属性消失,新表插入时可能报主键冲突或自增从 1 开始 - 默认值表达式(如
DEFAULT UUID())被忽略,字段变成NULL或报错 - 字符集/排序规则可能退化为库级默认值,而非原表实际设定
- 对
ENUM/SET值顺序、隐藏列(如ROWID模拟字段)等细节不可控
跨库、调参或补漏时该怎么做
如果要改存储引擎、字符集,或需要外键和注释,LIKE 只是起点,后续必须手动干预:
- 改引擎:必须显式写
CREATE TABLE new_table ENGINE=InnoDB LIKE old_table;,靠default_storage_engine不生效 - 补外键:先用
SHOW CREATE TABLE old_table;查原外键定义,再ALTER TABLE new_table ADD CONSTRAINT ... FOREIGN KEY ... - 补注释:
ALTER TABLE new_table COMMENT='xxx'; - 检查默认值是否异常:运行
SHOW CREATE TABLE new_table;对比原表,尤其留意CURRENT_TIMESTAMP是否被固化为字符串 - 大表分区或全文索引复制后,确认目标 MySQL 版本支持对应特性(如
InnoDB全文索引需 5.6+)
可视化工具里“复制表”常悄悄失效
DBeaver、Navicat、MySQL Workbench 等工具点“复制表”时,底层往往走的是 SHOW CREATE TABLE + 字符串替换路径。这在简单表上没问题,但遇到以下情况容易翻车:
-
ENUM('a','B','c')复制后大小写或顺序错乱(工具解析不严格) - 嵌套
COLLATE(如字段级 collation 覆盖表级)被简化丢弃 - JSON 列、虚拟列、隐藏系统列未被识别,建出来类型不对
- GUI 默认不勾选“复制外键”或“保留注释”,界面无提示
真要保险,别信右键菜单——切到 SQL 编辑器,手敲 CREATE TABLE ... LIKE,再用 SHOW CREATE TABLE 核对。











