最可靠方式是用 INFORMATION_SCHEMA 三视图拼装表结构并手动处理 JSON 转义:COLUMNS 取字段基础信息,KEY_COLUMN_USAGE 补主外键,TABLES 拿引擎等元数据,同时对 NULL、特殊字符、类型名称、时间默认值统一规范化。

用 INFORMATION_SCHEMA 查表结构再转 JSON 最可靠
MySQL 本身不提供直接导出表定义为 JSON 的内置命令,但 INFORMATION_SCHEMA 是唯一跨版本稳定可用的元数据来源。绕开 SHOW CREATE TABLE 的文本解析陷阱,从 COLUMNS、KEY_COLUMN_USAGE、TABLES 这三张视图拼装结构,才能保证字段顺序、约束类型、默认值等细节不丢。
实操建议:
- 优先查
INFORMATION_SCHEMA.COLUMNS获取字段名、类型、是否为空、默认值(COLUMN_DEFAULT)、注释(COLUMN_COMMENT) - 用
INFORMATION_SCHEMA.KEY_COLUMN_USAGE补全主键、外键信息,注意CONSTRAINT_NAME = 'PRIMARY'才是主键 -
INFORMATION_SCHEMA.TABLES拿引擎、行格式、注释,避免硬编码ENGINE=InnoDB - 别依赖
SHOW FULL COLUMNS FROM tbl—— 它不返回外键引用目标,且Extra字段内容格式不统一(比如auto_increment和on update CURRENT_TIMESTAMP混在一起)
JSON 生成必须手动处理 NULL 和特殊字符
MySQL 的 JSON_OBJECT() 和 JSON_ARRAYAGG() 在遇到 NULL 字段(如无默认值、无注释)时会静默跳过该键,导致 JSON 结构缺失;更麻烦的是字段注释里常含换行、双引号、反斜杠,直接拼接会破坏 JSON 合法性。
实操建议:
- 所有字符串字段用
IFNULL(col, '')或COALESCE(col, '')防止键丢失 - 注释、默认值这类用户输入内容,必须过一遍
REPLACE(REPLACE(REPLACE(col, '\', '\\'), '"', '\"'), ' ', '\n') - 类型字段(
DATA_TYPE)要映射为标准名称,比如把tinyint统一转成TINYINT,避免大小写混用影响下游解析 - 别用
CONCAT('{', ... , '}')拼 JSON —— 一旦某处少个逗号或引号,整个 JSON 就无效,且 MySQL 不报错
用存储过程封装比临时 SQL 更易复用
单次查一张表还行,但批量导出几十张表时,手写多层 JOIN + GROUP_CONCAT + JSON_OBJECT 很容易漏掉外键关联或索引信息。写成存储过程后,传入 table_name 和 db_name 就能输出标准 JSON,还能加开关控制是否包含索引、分区、触发器等可选部分。
实操建议:
- 过程内用
SELECT ... INTO @json存结果,最后SELECT @json返回,避免游标性能损耗 - 外键目标表名在
KEY_COLUMN_USAGE里是REFERENCED_TABLE_NAME,但只在有外键时非空,需用LEFT JOIN+IFNULL处理 - 如果目标是生成文档,建议额外加一个
is_document_mode参数:开启时补上字段中文名(从COLUMN_COMMENT提取)、示例值、是否敏感字段标记 - 别在过程里用
PREPARE/EXECUTE动态拼库名 —— 权限和 SQL 注入风险高,直接用CONCAT('SELECT ... FROM ', db_name, '.COLUMNS')更安全
导出后校验 JSON 合法性不能只靠 JSON_VALID()
JSON_VALID() 只检查语法,不保证结构符合预期。比如字段数组为空、主键字段没标 "primary_key": true、外键没带 "ref_table" 字段,它都判为合法。真正落地用时,这些缺失会导致文档渲染失败或代码生成报错。
实操建议:
- 导出后立刻用
JSON_EXTRACT(@json, '$.columns')确认字段数组存在且长度 > 0 - 检查必有字段:
JSON_CONTAINS_PATH(@json, 'one', '$.name')、JSON_CONTAINS_PATH(@json, 'one', '$.engine') - 如果下游是前端展示,额外验证
JSON_EXTRACT(@json, '$.columns[0].type')是否为字符串,避免数字类型被当成 JSON 数字而丢失引号 - 本地快速校验:把结果复制进 VS Code,装 JSON Tools 插件按
Ctrl+Shift+P → JSON: Format,格式化失败说明有隐藏非法字符(比如不可见的零宽空格)
最麻烦的其实是时间类型字段的默认值 —— CURRENT_TIMESTAMP 在 COLUMN_DEFAULT 里存的是字符串,但有些版本带括号,有些不带,有些还带小数秒,得统一归一化成 "CURRENT_TIMESTAMP" 字面量,否则 JSON 解析器可能当普通字符串处理。


















