bigywater.tech
MySQL / InnoDB · 88

JSON_TABLE

用一段真实带嵌套数组的JSON,对比JSON_TABLE加不加NESTED PATH的区别,看嵌套数组是怎么真实被拍平成关系型多行的。

2行→3行
加上NESTED PATH后tags数组真实被展开的行数
等价于一次JOIN
效果真实和关系型一对多JOIN完全一样

做的事:一段真实的JSON数组,用JSON_TABLE转成关系型的行

代码SET @j = '[ {"id":1,"name":"Alice","tags":["admin","dev"]}, {"id":2,"name":"Bob","tags":["user"]} ]'; SELECT * FROM JSON_TABLE(@j, '$[*]' COLUMNS ( id INT PATH '$.id', name VARCHAR(20) PATH '$.name', tags JSON PATH '$.tags' )) AS jt;

验证:不拆嵌套数组,一行对应一个用户

实测 · 本机执行输出
id  name    tags
1   Alice   ["admin", "dev"]
2   Bob     ["user"]

这一步真实只是把JSON数组的每个对象映射成一行,tags这个内部数组本身没有被展开,原样以JSON文本的形式塞进了一个字段里。

验证:加上NESTED PATH,tags数组真实被拆成了独立的行

代码SELECT * FROM JSON_TABLE(@j, '$[*]' COLUMNS ( id INT PATH '$.id', name VARCHAR(20) PATH '$.name', NESTED PATH '$.tags[*]' COLUMNS (tag VARCHAR(20) PATH '$') )) AS jt;
实测 · 本机执行输出
id  name    tag
1   Alice   admin
1   Alice   dev     ← Alice带2个tag,真实拆成了2行
2   Bob     user    ← Bob只带1个tag,真实还是1行
加上NESTED PATH '$.tags[*]'之后,JSON_TABLE真实对每个用户对象里的tags数组做了一次展开:Alice有2个tag,真实生成2行(id和name重复出现);Bob只有1个tag,真实只生成1行——这个效果和真实用户表JOIN一张标签关联表得到的结果完全一样,只是数据源从关系型表换成了一段JSON文本。这个特性真实解决的问题是:当上游系统(比如一个返回JSON的API、或者一份日志文件)吐出的是嵌套JSON结构,而下游分析真实需要按行处理时,不需要先写代码把JSON拍平,直接在SQL里用JSON_TABLE就能完成这一步,还能利用SQL原生的GROUP BY、JOIN继续加工。

分步演示:从一整坨JSON到关系型的多行结果

每一步都是本文上面用真实JSON_TABLE查询跑出来的原始结果。

NESTED PATH真实把嵌套数组拍成了行
这一步新验证的展开

    本文用到的工具

    • 本机 MySQL 26.7.0(InnoDB),真实的JSON数组,用JSON_TABLE + NESTED PATH展开
    • JSON_TABLE(json_doc, path COLUMNS (...)):MySQL 8.0.4起支持
    京ICP备2026067502号-1京公网安备11010502063487号