show create table 是唯一能获取服务端真实建表语句的方式,包含外键、engine、charset、collate、注释、json字段、生成列等全部信息,但需手动校验engine、default charset、collate三处关键字段,并检查分号、反引号、依赖顺序及字段级字符集覆盖等细节。

SHOW CREATE TABLE 是唯一能拿到服务端真实建表语句的方式,它比任何 GUI 工具导出的结构都全——外键、ENGINE、CHARSET、COLLATE、注释、JSON 字段、生成列,全在输出里。但直接复制粘贴就执行,大概率出错。
SHOW CREATE TABLE 输出必须手动校验三处关键字段
DDL 看着像,跑起来崩,90% 出在这三个地方:
-
ENGINE=InnoDB:生产库禁用MyISAM,否则事务、行锁、外键全失效 -
DEFAULT CHARSET=utf8mb4:别写utf8,那是 MySQL 的假 utf8,存 emoji 或生僻字直接丢数据 -
COLLATE=utf8mb4_0900_ai_ci(MySQL 8.0)或utf8mb4_unicode_ci(5.7):排序规则不一致会导致ORDER BY结果错乱、索引失效
如果目标库是主从架构,还要确认 sql_mode 是否含 STRICT_TRANS_TABLES,否则默认值插入可能静默失败。
复制结果前必须检查反引号和分号
GUI 工具或命令行输出有时会漏掉末尾分号,或对含横线、中文的表名没加反引号,导致 source 执行卡住或报错:
- 确保整行输出以分号
;结尾,否则 MySQL 客户端不会执行 - 表名如
order_log_2024或用户信息必须被`包裹,否则语法错误 - 复制时别误选到第二列(即
Create Table列)以外的内容;SHOW CREATE TABLE user_profile返回两列,只取第二列整段
执行前先建临时表做 DESCRIBE 对比验证
别一上来就 DROP TABLE 或覆盖原表。稳妥做法是:
- 在目标库建临时表:
CREATE TABLE tmp_user_profile LIKE user_profile(若原表还在) - 或用
SHOW CREATE TABLE导出后,改表名为tmp_user_profile再执行 - 然后运行
DESCRIBE user_profile和DESCRIBE tmp_user_profile对比字段类型、是否为空、默认值 - 再用
SHOW INDEX FROM user_profile和SHOW INDEX FROM tmp_user_profile核查索引数量与字段顺序是否一致
外键约束不会被 LIKE 复制,必须从 SHOW CREATE TABLE 输出里单独提取 ALTER TABLE ... ADD CONSTRAINT 语句补上。
批量还原时别直接用 mysqldump --no-data
它快,但默认不带 IF NOT EXISTS,也不保证外键依赖顺序:
- 加
--add-drop-table后,务必手动把DROP TABLE IF EXISTS替成CREATE TABLE IF NOT EXISTS,避免误删线上表 - 有外键依赖的表(比如
order引用user),mysqldump按字母序输出,可能先建order再建user,导致建表失败 - 真要批量处理,先查依赖链:
SELECT table_name, referenced_table_name FROM information_schema.KEY_COLUMN_USAGE WHERE referenced_table_name IS NOT NULL AND table_schema = 'db_name',按依赖关系排序后再导出
最易被忽略的点:字符集和排序规则在 CREATE TABLE 里是全局级声明,但字段级定义(比如某个 VARCHAR 显式指定 CHARSET gbk)会覆盖它——这种细节,只有 SHOW CREATE TABLE 能完整保留,其他方式基本丢光。











