CREATE TABLE ... LIKE 能完整复制原表结构、索引、自增属性、字符集和排序规则,但不复制数据、注释、触发器及外键约束;跨库复制需显式指定库名,且不自动转换字符集。

用 CREATE TABLE ... LIKE 复制结构和索引最直接
这是 MySQL 原生支持的最快方式,能完整复制原表的列定义、主键、唯一键、普通索引、自增属性、字符集和排序规则,但不复制数据、触发器、外键约束(注意:外键定义本身也不会被复制)。
实操建议:
- 语法是
CREATE TABLE new_table LIKE old_table;,new_table必须不存在 - 目标库需有
CREATE权限,源表需有SELECT权限(尽管不查数据,MySQL 仍会校验) - 如果原表用了
ENGINE=InnoDB,新表默认也是 InnoDB;但若当前会话设置了default_storage_engine,可能意外变成 MyISAM(尤其老版本 MySQL),建议显式指定:CREATE TABLE new_table LIKE old_table; ALTER TABLE new_table ENGINE=InnoDB; - 该语句不复制
COMMENT,字段注释和表注释都会丢失
用 SHOW CREATE TABLE + CREATE TABLE 更可控
当需要保留注释、调整引擎、修改部分字段或跳过某些索引时,这是更稳妥的选择。本质是人工“重放”建表语句。
实操建议:
- 先执行
SHOW CREATE TABLE old_table;,复制输出中的CREATE TABLE语句 - 把表名替换成新表名,删掉
AUTO_INCREMENT值(避免后续插入冲突),检查并修正ENGINE、DEFAULT CHARSET等参数 - 字段注释(
COMMENT 'xxx')和表注释(COMMENT='yyy')都在输出里,别漏掉 - 如果原表有外键,
SHOW CREATE TABLE输出中会包含CONSTRAINT定义,但新建时若引用的父表不在当前库,会报错;此时应手动删掉外键定义再执行
复制结构后,为什么 INSERT INTO new_table SELECT * FROM old_table 报错?
常见于字段类型不兼容、严格模式开启、或目标表有非空约束但源数据含 NULL——这说明“结构复制”只是第一步,数据迁移还需额外校验。
容易踩的坑:
-
sql_mode含STRICT_TRANS_TABLES时,哪怕源表某列为TINYINT存了 200,目标表同为TINYINT也会因超范围插入失败 - 源表有
NOT NULL字段但没默认值,而源数据存在隐式 NULL(比如未显式赋值的 INSERT),复制时会触发报错 -
ENUM或SET类型的值列表顺序必须完全一致,否则SELECT *可能写入错误序号 - 建议先用
INSERT IGNORE或INSERT ... ON DUPLICATE KEY UPDATE试探性导入少量数据,再确认字段映射是否真的一致
跨库复制时,LIKE 语法要注意路径写法
MySQL 允许在 LIKE 中使用数据库前缀,但格式固定:CREATE TABLE db2.new_table LIKE db1.old_table;。不能省略库名,也不能用反引号包裹整个带库名的标识符。
关键细节:
- 源库
db1和目标库db2必须都存在,且当前用户对两者都有相应权限 - 如果两个库字符集不同(如
db1是utf8mb4,db2是latin1),新表仍按源表定义创建,但后续插入中文可能乱码——结构复制不自动做字符集转换 - 跨库操作无法用
SHOW CREATE TABLE db1.old_table直接生成带库名的语句,输出中表名不含库前缀,需手动补全
实际中最容易被忽略的是外键和注释的缺失,以及跨库时字符集/排序规则的隐式继承。如果业务依赖表注释做文档,或者下游工具靠外键推导关系,光靠 LIKE 就不够。


















