快速上手MySQL中的JSON函数语法------5.x+ / 8.x+
MySQL 对 JSON 的支持分两个关键阶段:MySQL 5.7+(5.7.8 及以上完善支持 JSON 类型) 提供基础 JSON 操作功能,MySQL 8.0+ 在基础上新增大量高级函数并优化性能。以下按「版本支持度」分类,详细介绍核心 JSON 函数的语法、用途及示例:
前置说明
- 5.x 支持范围:仅 MySQL 5.7+(5.6 及以下无原生 JSON 类型/函数),以下「5.x 支持」均指代 5.7+。
- 路径规则 :JSON 路径统一使用
$开头,$即代表根节点,例如:$.key:获取对象的key字段$[index]:获取数组的第index个元素(从 0 开始)$.*/$[*]:匹配对象所有键/数组所有元素
一、JSON 创建函数(构建 JSON 文档)
用于快速生成合法的 JSON 对象/数组。
| 函数名 | 支持版本 | 语法 | 用途 | 示例 |
|---|---|---|---|---|
JSON_OBJECT([key, val[, key, val]...]) |
5.x+、8.x+ | 传入键值对,创建 JSON 对象 | 构建键值对形式的 JSON | SELECT JSON_OBJECT('id',1,'name','张三') → {"id":1,"name":"张三"} |
JSON_ARRAY([val[, val]...]) |
5.x+、8.x+ | 传入多个值,创建 JSON 数组 | 构建有序值集合的 JSON | SELECT JSON_ARRAY(1, 'a', true) → [1,"a",true] |
JSON_QUOTE(string) |
5.x+、8.x+ | 对字符串转义,生成 JSON 格式字符串(加双引号、转义特殊字符) | 确保字符串符合 JSON 语法 | SELECT JSON_QUOTE('a"b') → "a\\\"b"(JSON 格式的 "a\"b") |
JSON_MERGE(json1, json2[, ...]) |
5.x+(8.x 废弃) | 合并多个 JSON,数组拼接、对象合并(冲突键保留所有值) | 5.7 中合并 JSON 数据 | SELECT JSON_MERGE('{"a":1}', '{"b":2}') → {"a":1,"b":2} |
JSON_MERGE_PRESERVE(json1, json2[, ...]) |
8.x+ | 替代 5.x 的 JSON_MERGE,合并后保留所有键(冲突键转数组) |
安全合并不丢失数据 | SELECT JSON_MERGE_PRESERVE('{"a":1}', '{"a":2}') → {"a":[1,2]} |
JSON_MERGE_PATCH(json1, json2[, ...]) |
8.x+ | 合并后冲突键用后者覆盖(类似 HTTP PATCH) | 更新 JSON 并覆盖旧值 | SELECT JSON_MERGE_PATCH('{"a":1}', '{"a":2}') → {"a":2} |
二、JSON 查询函数(提取 JSON 数据)
从 JSON 文档中提取指定路径、值或判断是否存在目标数据。
| 函数名 | 支持版本 | 语法 | 用途 | 示例 |
|---|---|---|---|---|
JSON_EXTRACT(json_doc, path[, path]...) |
5.x+、8.x+ | 按路径提取数据,多路径返回数组 | 核心查询函数 | SELECT JSON_EXTRACT('{"id":1,"name":"张三"}', '$.name') → "张三" |
JSON_KEYS(json_doc[, path]) |
5.x+、8.x+ | 返回 JSON 对象的所有键(数组形式) | 获取对象的键集合 | SELECT JSON_KEYS('{"id":1,"name":"张三"}') → ["id","name"] |
JSON_CONTAINS(json_doc, val[, path]) |
5.x+、8.x+ | 判断 JSON 是否包含目标值(严格匹配类型) | 检查值是否存在 | SELECT JSON_CONTAINS('{"b":[2,3]}', '2', '$.b') → 1(存在) |
JSON_CONTAINS_PATH(json_doc, one_or_all, path[, ...]) |
5.x+、8.x+ | 判断路径是否存在(one:至少一个;all:全部) |
检查路径有效性 | SELECT JSON_CONTAINS_PATH('{"a":1}', 'all', '$.a', '$.c') → 0($.c 不存在) |
JSON_SEARCH(json_doc, one_or_all, search_str[, ...]) |
5.x+、8.x+ | 模糊搜索字符串值,返回路径(支持 %/_ 通配符) |
模糊查询 JSON 字符串 | SELECT JSON_SEARCH('{"a":"apple"}', 'one', 'app%') → "$.a" |
JSON_VALUE(json_doc, path[, RETURNING type]) |
8.x+ | 提取值并转换为指定 SQL 类型(默认字符串) | 替代 JSON_EXTRACT+CAST |
SELECT JSON_VALUE('{"id":123}', '$.id' RETURNING INT) → 123(INT 类型) |
JSON_QUERY(json_doc, path) |
8.x+ | 提取 JSON 片段(返回 JSON 类型,非标量值) | 提取子 JSON 文档 | SELECT JSON_QUERY('{"a":{"b":1}}', '$.a') → {"b":1} |
三、JSON 修改函数(新增/更新/删除数据)
修改 JSON 文档中的键值对或数组元素。
| 函数名 | 支持版本 | 语法 | 用途 | 示例 |
|---|---|---|---|---|
JSON_SET(json_doc, path, val[, ...]) |
5.x+、8.x+ | 路径存在则更新,不存在则新增 | 新增/更新 JSON 数据 | SELECT JSON_SET('{"a":1}', '$.a',2, '$.b',3) → {"a":2,"b":3} |
JSON_INSERT(json_doc, path, val[, ...]) |
5.x+、8.x+ | 仅新增路径(已存在则忽略) | 仅新增不覆盖 | SELECT JSON_INSERT('{"a":1}', '$.a',2, '$.b',3) → {"a":1,"b":3} |
JSON_REPLACE(json_doc, path, val[, ...]) |
5.x+、8.x+ | 仅更新路径(不存在则忽略) | 仅更新不新增 | SELECT JSON_REPLACE('{"a":1}', '$.a',2, '$.b',3) → {"a":2} |
JSON_REMOVE(json_doc, path[, ...]) |
5.x+、8.x+ | 删除指定路径的数据 | 删除键/数组元素 | SELECT JSON_REMOVE('{"a":1,"b":2}', '$.a') → {"b":2} |
JSON_ARRAY_APPEND(json_doc, path, val[, ...]) |
5.x+、8.x+ | 向数组末尾追加值(路径必须是数组) | 扩展 JSON 数组 | SELECT JSON_ARRAY_APPEND('[1,2]', '$',3) → [1,2,3] |
JSON_ARRAY_INSERT(json_doc, path, val[, ...]) |
5.x+、8.x+ | 向数组指定索引插入值(路径格式 $[index]) |
数组中间插入元素 | SELECT JSON_ARRAY_INSERT('[1,3]', '$[1]',2) → [1,2,3] |
四、JSON 判断与验证函数
检查 JSON 文档的合法性、类型、深度等属性。
| 函数名 | 支持版本 | 语法 | 用途 | 示例 |
|---|---|---|---|---|
JSON_VALID(val) |
5.x+、8.x+ | 判断值是否为合法 JSON(1=合法,0=非法) | 验证 JSON 格式 | SELECT JSON_VALID('{"a":1}') → 1;SELECT JSON_VALID('{a:1}') → 0 |
JSON_TYPE(json_val) |
5.x+、8.x+ | 返回 JSON 类型(OBJECT/ARRAY/STRING 等) | 判断 JSON 数据类型 | SELECT JSON_TYPE('{"a":1}') → OBJECT;SELECT JSON_TYPE('[1,2]') → ARRAY |
JSON_DEPTH(json_doc) |
5.x+、8.x+ | 返回 JSON 深度(顶层为 1,嵌套+1) | 查看嵌套层级 | SELECT JSON_DEPTH('{"a":{"b":1}}') → 3 |
JSON_LENGTH(json_doc[, path]) |
5.x+、8.x+ | 返回长度(对象:键值对数量;数组:元素数) | 获取 JSON 大小 | SELECT JSON_LENGTH('{"a":1,"b":2}') → 2;SELECT JSON_LENGTH('[1,2,3]') → 3 |
JSON_EQUALS(json1, json2) |
8.x+ | 判断两个 JSON 语义相等(忽略键顺序/空格) | 对比 JSON 等价性 | SELECT JSON_EQUALS('{"a":1,"b":2}', '{"b":2,"a":1}') → 1 |
JSON_SCHEMA_VALID(schema, json_doc) |
8.0.19+ | 按 JSON Schema 验证 JSON 结构 | 严格校验 JSON 规范 | SET @schema = '{"type":"object","required":["id"]}';SELECT JSON_SCHEMA_VALID(@schema, '{"id":1}') → 1 |
五、JSON 转换与格式化函数
实现 JSON 与其他类型的转换,或美化输出。
| 函数名 | 支持版本 | 语法 | 用途 | 示例 |
|---|---|---|---|---|
JSON_UNQUOTE(json_val) |
5.x+、8.x+ | 去除 JSON 字符串的双引号(还原转义字符) | JSON 字符串转普通字符串 | SELECT JSON_UNQUOTE('"a\\\"b"') → a"b |
CAST(val AS JSON)/CONVERT(val, JSON) |
5.x+、8.x+ | 将字符串/数组转为 JSON 类型(需符合格式) | 类型转换构建 JSON | SELECT CAST('{"a":1}' AS JSON) → {"a":1} |
JSON_PRETTY(json_doc) |
5.7.22+、8.x+ | 格式化 JSON(换行+缩进) | 美化 JSON 输出 | SELECT JSON_PRETTY('{"a":1,"b":[2,3]}') → 格式化后的多行 JSON |
JSON_TO_STRING(json_doc[, options]) |
8.x+ | 自定义 JSON 转字符串(支持日期/数字格式) | 自定义输出格式 | SELECT JSON_TO_STRING('{"dt":"2025-11-27"}', '{"date_format":"%Y/%m/%d"}') → {"dt":"2025/11/27"} |
六、8.x 新增高级 JSON 函数
MySQL 8.0 新增的核心功能,解决 5.x 无法实现的复杂场景。
| 函数名 | 语法 | 用途 | 示例 |
|---|---|---|---|
JSON_TABLE(json_doc, path COLUMNS (col_def...)) |
将 JSON 解析为关系表(虚拟表) | JSON 转表,支持 JOIN/WHERE 等查询 | 见下文详细示例 |
JSON_DIFF(json1, json2) |
返回两个 JSON 的差异(仅保留 doc1 独有的部分) | 对比 JSON 差异 | SELECT JSON_DIFF('{"a":1,"b":2}', '{"a":1,"c":3}') → {"b":2} |
JSON_STORAGE_SIZE(json_doc) |
返回 JSON 存储大小(字节数) | 查看 JSON 占用空间 | SELECT JSON_STORAGE_SIZE('{"a":1}') → 21(因版本略有差异) |
JSON_STORAGE_FREE(json_col) |
返回 JSON 列的空闲存储空间(仅 InnoDB) | 优化存储(如释放删除数据的空间) | SELECT JSON_STORAGE_FREE(json_col) FROM t1 WHERE id=1 |
关键高级函数示例:JSON_TABLE(JSON 转表)
解决 5.x 无法将 JSON 批量转为关系表查询的问题,支持复杂 SQL 操作:
sql
SELECT * FROM JSON_TABLE(
'[{"id":1,"name":"张三","age":20},{"id":2,"name":"李四","age":25}]',
'$[*]' COLUMNS (
id INT PATH '$.id', -- 提取 id 为 INT 类型
name VARCHAR(20) PATH '$.name', -- 提取 name 为字符串
age INT PATH '$.age' DEFAULT 0 -- 缺省值为 0
)
) AS jt; -- 别名 jt 为虚拟表名
-- 输出结果(关系表格式):
id | name | age
1 | 张三 | 20
2 | 李四 | 25
七、JSON 运算符(简化查询)
MySQL 支持简洁运算符替代部分函数,提高可读性:
| 运算符 | 支持版本 | 等价函数 | 用途 | 示例 |
|---|---|---|---|---|
-> |
5.x+、8.x+ | JSON_EXTRACT() |
提取 JSON 数据 | SELECT '{"a":1}'->'$.a' → 1 |
->> |
5.x+、8.x+ | JSON_UNQUOTE(JSON_EXTRACT()) |
提取并去除引号 | SELECT '{"name":"张三"}'->>'$.name' → 张三 |
@> |
5.x+、8.x+ | JSON_CONTAINS() |
判断 JSON 包含关系 | SELECT '{"a":1,"b":[2,3]}' @> '{"b":[2]}' → 1 |
<@ |
5.x+、8.x+ | 反向 JSON_CONTAINS() |
判断被包含关系 | SELECT '{"a":1}' <@ '{"a":1,"b":2}' → 1 |
JSON_OVERLAPS(json1, json2) |
8.x+ | - | 检查数组交集/对象共同键 | SELECT JSON_OVERLAPS('[1,2]', '[2,3]') → 1 |
版本核心差异总结
| 特性 | MySQL 5.7+ | MySQL 8.0+ |
|---|---|---|
| 基础功能 | 支持 JSON 创建、查询、简单修改 | 完全兼容 5.7 功能,且优化性能 |
| 高级功能 | 无 JSON 转表、Schema 验证、差异对比 | 新增 JSON_TABLE、JSON_SCHEMA_VALID、JSON_DIFF 等 |
| 合并函数 | 仅 JSON_MERGE(8.x 废弃) |
新增 JSON_MERGE_PRESERVE/PATCH(更灵活) |
| 提取转换 | 需 JSON_EXTRACT+CAST |
新增 JSON_VALUE(直接指定类型) |
| 性能 | 基础优化 | 针对 JSON 索引、查询速度大幅优化 |
如果需要兼容旧版本(5.7),优先使用 JSON_EXTRACT、JSON_SET 等基础函数;若使用 8.0+,推荐用 JSON_TABLE、JSON_SCHEMA_VALID 等高级函数提升开发效率。