create table ... like 是唯一能完整复制列定义、主键、索引(含前缀长度)、auto_increment、字符集和collate的原生命令,但不复制数据、外键和表注释。

用 CREATE TABLE ... LIKE 是最直接的方式
它能完整复制列定义、主键、唯一索引、普通索引、AUTO_INCREMENT 值、字符集和 COLLATE,但不带任何数据。执行后新表是空的,结构与源表完全一致。
常见错误现象:有人误用 CREATE TABLE ... SELECT * FROM ... WHERE 0,结果发现主键和索引全丢了——因为这种写法只推导字段类型,不继承约束和索引。
-
CREATE TABLE new_table LIKE original_table;是唯一能原样保留索引定义的原生命令 - 若源表有前缀索引(如
INDEX idx_name (name(10))),LIKE会完整保留长度参数 - MySQL 8.0+ 中由
innodb_force_primary_key=ON引入的隐藏主键不会被复制,需手动确认SHOW CREATE TABLE输出
为什么 SHOW CREATE TABLE + 手动建表不是首选
虽然它能拿到完整 DDL,但人工修改表名、引擎、注释等容易出错,尤其当表定义里有反引号、特殊字符或动态生成的列时,复制粘贴极易引入语法错误。
使用场景:仅在需要跨库迁移且目标库默认存储引擎不同(比如源是 InnoDB,目标库默认是 MyISAM)时才值得手动调整 DDL;否则纯属增加出错概率。
- 手动改 DDL 时容易漏掉
STATS_PERSISTENT=1或ALGORITHM=INSTANT这类隐式参数 - 列注释可能被保留,但表注释一定丢失,需额外补
ALTER TABLE ... COMMENT = 'xxx' - 如果源表用了生成列(
GENERATED ALWAYS AS),部分旧版本 MySQL(如 5.7)解析 DDL 时可能报错
跨库或升级环境时,mysqldump --no-data 更可靠
它导出的是显式、可读、带兼容性控制的 SQL,比 LIKE 更适合非同版本或非同配置环境。
性能 / 兼容性影响:在 MySQL 8.0 向 5.7 迁移时,LIKE 可能因默认 ROW_FORMAT 或 KEY_BLOCK_SIZE 不兼容而静默降级;而 mysqldump 会按目标版本能力生成适配语句(前提是用对应版本的客户端执行 dump)。
- 命令示例:
mysqldump -u user -p --no-data db_name table_name > struct.sql - 加
--add-drop-table可避免重复创建报错,加--skip-triggers可排除触发器干扰(即使源表没触发器,也建议显式跳过) - 导入前记得检查
struct.sql中的ENGINE和CHARSET是否符合目标库规范
容易被忽略的关键点:索引顺序和外键
LIKE 复制的索引顺序与源表严格一致,但如果你后续执行过 DROP INDEX 再重建,顺序就变了——而某些 ORM 或监控工具依赖索引顺序做判断。
外键根本不会被复制,哪怕源表有 FOREIGN KEY (col) REFERENCES other_table(id),新表只会留下 col 字段和对应索引,CONSTRAINT 定义彻底消失。
- 必须用
ALTER TABLE new_table ADD CONSTRAINT ... FOREIGN KEY ...单独补全 - 补外键前要确保引用表已存在、字符集一致、字段类型完全匹配(比如不能是
INT对BIGINT) - 若源表有多个外键,
SHOW CREATE TABLE是唯一能一次性看清全部定义的方式











