登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  数据库 >  MySQL

MySQL JSON_PRETTY 怎样把 JSON 文档格式化输出

来源:17golang原创

时间:2026-10-18 18:38:44 395浏览 收藏

我在排查 JSON 日志时,常把“内容不对”和“内容太难读”混在一起处理。前者需要检查字段和值,后者只需要把嵌套关系摊开。MySQL 的 JSON_PRETTY() 就是为后一个问题准备的:它把合法 JSON 输出成带换行和缩进的可读文本,不负责类型转换,也不负责统计 JSON 列占了多少磁盘。

官方地址:https://dev.mysql.com/doc/refman/8.4/en/json-utility-functions.html

需要人工查看 JSON 时,对合法 JSON 值调用 JSON_PRETTY() 即可。对象成员和数组元素会分行显示,每层增加两个空格;传入 SQL NULL 返回 NULL,传入无法解析的文本则报错。

下面按一次实际排查的思路展开:先把原始值和格式化值放在同一个查询里,再分别处理对象、数组、标量和异常输入,最后说明 JSON 列场景下哪些指标不应混用。

先把“更易读”和“占用更小”分开

格式化会增加换行和空格,所以 JSON_PRETTY 的结果适合日志、排查和人工复制,不适合拿来判断存储空间。要做容量估算,应另看 JSON_STORAGE_SIZE;要取某个路径的值,应使用 JSON_VALUE 或 JSON_EXTRACT。三类函数解决的是不同问题。

-- 准备同一份合法 JSON,后面并列查看原值和可读值
SET @doc = '{"user":{"id":1001,"roles":["editor","reviewer"]},"active":true}';

-- 原始值用于保留机器输入,格式化值用于人工阅读
SELECT
    @doc AS compact_json,
    JSON_PRETTY(@doc) AS readable_json;

这里的比较基线不是“格式化后变短了多少”,而是“同一份数据是否更容易检查层级”。如果你把 readable_json 写回业务字段,就会把展示格式和数据存储混在一起;更稳妥的做法是查询时格式化,或只在日志输出层格式化。

JSON_PRETTY 将嵌套 JSON 对象和数组转换为带两格缩进的格式化文本的静态结构说明图
图1:JSON_PRETTY 的格式化关系说明图,展示嵌套 JSON 到可读文本的静态映射;这是说明图,不是运行截图。

对象和数组会怎样展开

MySQL 官方规则可以概括为四点:每个对象成员或数组元素单独占一行;每深入一层增加两个空格;对象键和值之间使用冒号加空格;空对象和空数组保持单行。逗号会出现在换行前,这样复制结果时仍然是合法 JSON 结构。

-- 对象、数组和嵌套对象放在一个示例中,便于观察层级变化
SELECT JSON_PRETTY('{"name":"A","items":[1,3,{"enabled":true}],"meta":{}}') AS formatted_json;

-- 标量也可以格式化;它不会凭空变成对象或数组
SELECT
    JSON_PRETTY('123') AS number_value,
    JSON_PRETTY('true') AS boolean_value,
    JSON_PRETTY('"text"') AS string_value;

这个函数不会替你补字段,也不会把字符串里的 JSON 再猜测成另一层对象。输入是 JSON 字符串标量时,输出仍然是字符串标量;输入是对象时,才会出现成员级换行。排查接口数据时,我会先看最外层类型,再决定是否需要继续追某个路径。

NULL、非法 JSON 和特殊字符不能用同一种判断

JSON_PRETTY 的异常边界很明确,但它们在排查脚本里经常被混为“空结果”。SQL NULL 会得到 NULL;合法的空对象和空数组会得到 {} 与 [];非 NULL 但无法解析的文本会触发错误。三者分别代表缺失值、合法空结构和输入格式问题。

-- SQL NULL 表示没有输入值,结果仍是 NULL
SELECT JSON_PRETTY(NULL) AS null_result;

-- 空对象和空数组是合法 JSON,保持单行输出
SELECT
    JSON_PRETTY('{}') AS empty_object,
    JSON_PRETTY('[]') AS empty_array;

-- 非法 JSON 会进入错误路径;调用前应先确认输入来源可解析
SELECT JSON_PRETTY('{"id":}') AS invalid_result;

如果输入来自文本列,可以先用 JSON_VALID() 把“能否解析”作为查询条件,再对合法行调用 JSON_PRETTY。这样做是输入分层,不是把错误吞掉;真正需要修复的仍然是上游写入了不完整 JSON 的原因。

字符串中的引号、反斜杠等特殊字符会按 JSON 的转义规则输出。不要用普通字符串替换去猜测格式化结果,尤其不要把显示出来的转义字符直接当作原始字节序列。

JSON_PRETTY 对合法 JSON、NULL、非法 JSON 和 JSON 列查询的输入边界关系静态说明图
图2:JSON_PRETTY 输入边界说明图,展示合法值、NULL、非法文本与 JSON 列查询的静态关系;这是说明图,不是运行截图。

在 JSON 列查询中只格式化需要查看的字段

JSON_PRETTY 可以直接接收 JSON 列。排查时建议保留主键、原始列和格式化列,先用少量样本确认层级,再决定是否导出。这样读者能同时看到数据身份和展示形式,也不会误以为格式化列改变了原始存储。

-- 用 JSON 类型保存文档;主键帮助把展示结果对应回原记录
CREATE TABLE json_pretty_demo (
    id INT PRIMARY KEY,
    payload JSON NOT NULL
);

-- 插入两个结构不同的合法文档,模拟排查样本
INSERT INTO json_pretty_demo (id, payload) VALUES
    (1, '{"service":"api","limits":{"rps":100,"burst":20}}'),
    (2, '{"service":"worker","queues":["email","report"],"enabled":true}');

-- 原始列保留机器值,格式化列只服务于人工检查
SELECT
    id,
    payload AS raw_payload,
    JSON_PRETTY(payload) AS readable_payload
FROM json_pretty_demo
ORDER BY id;

这个查询适合做排查基线:raw_payload 便于程序继续处理,readable_payload 便于人快速确认层级。若要判断存储大小,应单独调用 JSON_STORAGE_SIZE(payload);若要提取字段,则使用面向路径的函数,不要从格式化文本里再做字符串截取。

我会怎样把它接进一次 JSON 问题排查

我的做法是把判断拆成三列:记录标识、原始 JSON、格式化 JSON。对比时只关心结构和字段,确认后再决定是修复上游输入、增加路径提取,还是转去做容量分析。

想回答的问题优先使用不要混用
嵌套字段怎样更容易看JSON_PRETTY()不要把换行后的字符数当存储空间
某个路径返回什么类型JSON_VALUE() 或 JSON_EXTRACT()不要从展示文本里截取字段
JSON 值或 JSON 列占多少空间JSON_STORAGE_SIZE()不要用 JSON_PRETTY 的输出长度代替
输入是不是合法 JSONJSON_VALID() 或错误处理不要把 NULL、空对象和非法文本都当成空

这张表也是边界检查:JSON_PRETTY 的产物是人类可读的文本,不是新的业务字段语义。只要把它放在查询或日志边缘,通常不会干扰原有 JSON 数据流。

常见疑问

JSON_PRETTY 会改变 JSON 的数据吗?它返回格式化后的文本表示,不是对 JSON 列做原地更新;是否写回取决于你的 SQL。若只是 SELECT,原列不会被修改。

为什么 JSON_PRETTY(NULL) 不是空字符串?因为 SQL NULL 表示没有值,函数会保留这个 NULL 语义。空字符串、空对象和 NULL 不是同一种输入。

非法 JSON 能不能自动修复?不能把 JSON_PRETTY 当修复器。它要求输入是 JSON 值或可解析的 JSON 文本;上游截断、引号缺失等问题应在写入链路修复。

格式化后多出来的空格会占用 JSON 列空间吗?仅在你把格式化文本另存为字符串时才可能影响字符串存储;JSON 列的存储语义应使用 JSON 相关存储函数和引擎指标判断,不能拿展示结果长度代替。

总结一下:用 JSON_PRETTY() 解决的是阅读层级,用 JSON_VALID() 区分输入是否可解析,用 JSON_VALUE() 或 JSON_EXTRACT() 取字段,用 JSON_STORAGE_SIZE() 做空间观察。把格式化留在查询和日志边缘,JSON 排查会清楚很多。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>