只读权限下批量生成建表语句的唯一可靠方式是查询information_schema;因SHOW CREATE TABLE不支持批量且易中断,需通过COLUMNS、KEY_COLUMN_USAGE、STATISTICS和TABLES四张系统表拼接字段、主键、索引及引擎等信息,并注意MySQL 5.7与8.0在column_default、extra、table_collation等字段的兼容性差异。

只读权限下,能批量生成建表语句的唯一可靠方式是查 information_schema —— 其他方法(如 Navicat 右键导出、存储过程、JDBC 工具)要么需要写权限,要么依赖外部环境,生产库上基本不可用。
为什么不能直接用 SHOW CREATE TABLE?
因为 SHOW CREATE TABLE 一次只能查一张表,且无法用通配符或 IN 列表批量执行。如果要导出 258 张表,就得手动敲 258 次命令,中间任何一次失败或漏掉都会导致结构不全。
更麻烦的是,部分 MySQL 版本(尤其是 5.7+ 开启了 sql_mode=STRICT_TRANS_TABLES)在 SHOW CREATE TABLE 遇到视图、临时表或权限不足时会直接报错中断,而不是跳过。
所以真实场景里,必须绕过这条命令,改从系统表拼 SQL。
用 information_schema.COLUMNS + information_schema.KEY_COLUMN_USAGE 拼建表语句
核心思路:把建表语句拆成字段定义 + 主键/索引/外键三部分,分别从 information_schema.COLUMNS、information_schema.KEY_COLUMN_USAGE、information_schema.STATISTICS 中查,再用字符串拼接组装。
实际操作建议:
- 先筛出目标表名列表,比如存在一个临时表
target_tables,或用WHERE table_name IN ('t_user', 't_order', ...)硬编码(注意长度限制,超长需分批) -
COLUMNS表里重点取:column_name、data_type、is_nullable、column_default、extra(判断 AUTO_INCREMENT)、column_comment - 主键信息必须从
KEY_COLUMN_USAGE查,过滤constraint_name = 'PRIMARY';普通索引得结合STATISTICS表,且要注意SEQ_IN_INDEX = 1才是首列 - 别忘了
ENGINE和CHARACTER SET—— 这俩得从information_schema.TABLES里单独查,字段是engine和table_collation(从中反推 charset)
容易被忽略的兼容性坑
MySQL 5.7 和 8.0 对 information_schema 字段返回值有差异:
-
column_default在 5.7 返回 NULL 表示无默认值,在 8.0 可能返回NULL字符串,拼接时得用IFNULL(column_default, 'NULL')统一处理 -
extra字段在 8.0 新增了STORED GENERATED、VIRTUAL GENERATED,老脚本若没覆盖会漏掉生成列定义 -
table_collation值如utf8mb4_0900_ai_ci是 8.0 默认,但建表语句里写CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci更通用,避免跨版本 restore 失败 - 分区表的
CREATE_OPTIONS字段在TABLES表里,但只在 8.0+ 才包含完整 DDL,5.7 下为空,得额外判断是否分区表并跳过或警告
真正难的不是拼出语法正确的语句,而是让生成结果能在目标环境(尤其是低版本 MySQL)上无报错执行 —— 字符集、引擎、生成列、JSON 类型支持度都得对齐。手动检查几条典型表的输出,比跑完全部再验证更省时间。


















