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 写回业务字段,就会把展示格式和数据存储混在一起;更稳妥的做法是查询时格式化,或只在日志输出层格式化。

对象和数组会怎样展开
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 列查询中只格式化需要查看的字段
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 的输出长度代替 |
| 输入是不是合法 JSON | JSON_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 排查会清楚很多。
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
501 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习