MySQL JSON_ARRAY_APPEND 怎样把值追加到嵌套数组
如果一列 JSON 里还有订单、事件或标签等嵌套数组,想在末尾加入一个新值,MySQL 的 JSON_ARRAY_APPEND() 比先取出整段 JSON、在应用层改完再写回更直接。它按 JSON 路径定位数组并追加值;路径命中标量时会自动包装成数组,路径没有匹配对象时则忽略这一对参数。
官方地址:https://dev.mysql.com/doc/refman/8.4/en/json-modification-functions.html
最稳妥的记法是:JSON_ARRAY_APPEND(json_doc, path, value)只负责“在命中的位置末尾追加”,不负责“插到第几个位置”。嵌套数组用完整路径定位;如果需要指定下标,应改看JSON_ARRAY_INSERT()。
JSON_ARRAY_APPEND 追加的到底是什么
函数的基本形态是 JSON_ARRAY_APPEND(json_doc, path, val[, path, val] ...)。第一个参数是合法 JSON 文档,之后每两个参数组成一对路径和值。路径指向数组时,新值进入数组末尾;如果指向的是对象或数字、字符串这样的标量,MySQL 会先把它自动包装成数组再追加。

例如订单文档中有一个 items 数组,可以把新的商品对象作为 JSON 值传入:
-- 给第一个订单的 items 数组追加一个商品对象
SELECT JSON_ARRAY_APPEND(
'{"orders":[{"items":[{"sku":"A1"}]}]}',
'$.orders[0].items',
JSON_OBJECT('sku', 'B2', 'qty', 1)
) AS updated_doc;
这里的路径先进入 orders 数组的第一个元素,再进入它的 items 成员。JSON_OBJECT() 返回的是 JSON 对象,所以追加结果中的新元素是对象,而不是带引号的普通字符串。
嵌套数组路径怎样写才不会追加错层级
嵌套数据最容易出错的地方,是把“订单数组”“订单对象”和“订单对象里的 items 数组”混成同一层。先把文档的层级写出来,再把每个数组下标和对象键连起来,路径就比较清楚:
-- 目标是 orders[0] 对象里的 items 数组,不是整个 orders 数组
SET @doc = '{"orders":[{"id":101,"items":["book"]}]}';
-- 在嵌套 items 数组末尾追加一个字符串值
SELECT JSON_ARRAY_APPEND(@doc, '$.orders[0].items', 'pen') AS updated_doc;
-- 让追加值保持对象形态,避免把对象文本当成普通字符串
SELECT JSON_ARRAY_APPEND(
@doc,
'$.orders[0].items',
JSON_OBJECT('sku', 'P01', 'qty', 2)
) AS updated_doc;
如果路径命中了标量,结果不会报“目标不是数组”,而是发生自动包装:
-- c 原来是数字,命中后会先变成 [4],再追加 9
SELECT JSON_ARRAY_APPEND(
'{"a":[2,3],"c":4}',
'$.c',
9
) AS updated_doc;
-- 不存在的 missing 路径不会自动创建成员,结果保持不变
SELECT JSON_ARRAY_APPEND(
'{"a":[2,3]}',
'$.missing.items',
'x'
) AS unchanged_doc;
这两个边界决定了排障方向:看到数组结构突然多了一层,先查路径是否实际指向了标量;看到结果没有变化,先查对象键是否存在以及路径表达式是否有效。
一次追加多个值时要按左到右阅读
同一次调用可以传多组 path, value。MySQL 会从左到右求值,前一对参数产生的文档会成为后一对参数的输入,因此不要把所有路径都当成针对原始文档独立执行。

-- 两对路径按左到右处理,第二对基于第一对产生的文档继续追加
SELECT JSON_ARRAY_APPEND(
'{"tags":["mysql"],"meta":{"labels":["sql"]}}',
'$.tags', 'json',
'$.meta.labels', 'database'
) AS updated_doc;
如果多组参数里任意参数是 SQL NULL,函数会返回 NULL;非法 JSON 文档、非法路径或包含 *、** 通配符的路径会报错。JSON 文档里的字符串值则应使用合法 JSON 文本或 JSON 构造函数,避免把本来想追加的对象写成带引号的字符串。
放进 UPDATE 时怎样保留原文档结构
真正更新 JSON 列时,把原列作为第一个参数,并用明确的 WHERE 限定记录。下面的写法只修改目标行的 events 数组:
-- 只给指定订单追加一次发货事件,避免无条件更新整张表
UPDATE order_log
SET payload = JSON_ARRAY_APPEND(
payload,
'$.events',
JSON_OBJECT(
'type', 'shipped',
'carrier', 'standard'
)
)
WHERE order_id = 101;
-- 读取更新后的数组,确认查询路径和写入路径保持一致
SELECT JSON_EXTRACT(payload, '$.events') AS events
FROM order_log
WHERE order_id = 101;
需要指定插入位置时,不能靠调整 JSON_ARRAY_APPEND() 的路径来实现。JSON_ARRAY_INSERT() 才是按数组下标插入的函数;两者都按多路径从左到右处理,但插入会改变后续数组位置,追加则只关心末尾。
| 需求 | 函数 | 注意点 |
|---|---|---|
| 事件、标签追加到数组末尾 | JSON_ARRAY_APPEND() | 目标为标量时会自动包装 |
| 插入到指定下标前 | JSON_ARRAY_INSERT() | 后续下标可能因前一次插入而变化 |
| 只在路径不存在时写入 | JSON_INSERT() | 已有路径不会覆盖 |
| 覆盖已有成员或元素 | JSON_SET() | 应单独确认是否需要部分更新语义 |
常见问题
为什么追加对象后变成了字符串? 如果把对象 JSON 直接作为普通 SQL 字符串传入,结果可能保留字符串形态。用 JSON_OBJECT() 或明确的 JSON 值构造方式传参,更容易保持对象结构。
路径不存在时能否自动创建数组? JSON_ARRAY_APPEND() 不会因为路径未命中就创建缺失成员。需要初始化结构时,应先用合适的 JSON 写入函数建立路径,再执行追加。
怎样向数组开头添加值? 这不是追加语义,应使用 JSON_ARRAY_INSERT() 指定 $[0] 等位置,并重新检查后续路径的下标变化。
记住“路径命中谁、值是什么类型、参数按什么顺序求值”这三个问题,就能稳定处理 MySQL JSON 中的嵌套数组追加。
MySQL EXCHANGE PARTITION 怎样把历史数据移到归档表
- 上一篇
- MySQL EXCHANGE PARTITION 怎样把历史数据移到归档表
- 下一篇
- MySQL复制延迟从状态表判断
-
- 数据库 · MySQL | 35分钟前 |
- MySQL复制延迟从状态表判断
- 134浏览 收藏
-
- 数据库 · MySQL | 40分钟前 |
- MySQL EXCHANGE PARTITION 怎样把历史数据移到归档表
- 277浏览 收藏
-
- 数据库 · MySQL | 43分钟前 | mysql innodb lock ALTER TABLE 元数据锁 ALGORITHM 在线DDL
- MySQL在线DDL降低表变更影响
- 358浏览 收藏
-
- 数据库 · MySQL | 44分钟前 | MySQL · 索引 · uuid · mysql innodb UUID_TO_BIN BIN_TO_UUID BINARY(16)
- MySQL UUID_TO_BIN 的 swap 参数怎样让时间型 UUID 保持索引顺序
- 176浏览 收藏
-
- 数据库 · MySQL | 45分钟前 | 事务 · 并发控制 · InnoDB · MySQL教程 · mysql innodb 事务隔离级别 Serializable READ COMMITTED REPEATABLE READ
- MySQL事务隔离级别选择
- 188浏览 收藏
-
- 数据库 · MySQL | 50分钟前 |
- MySQL命令行为什么把二进制结果显示成0x开头
- 462浏览 收藏
-
- 数据库 · MySQL | 54分钟前 |
- MySQL怎样只移除登录路径中的已保存密码
- 382浏览 收藏
-
- 数据库 · MySQL | 1小时前 | MySQL教程 · mysql SRID 空间函数 GIS ST_Buffer ST_Buffer_Strategy
- MySQL ST_Buffer 怎样为几何对象生成缓冲区
- 235浏览 收藏
-
- 数据库 · MySQL | 1小时前 |
- MySQL生成列配合函数索引
- 295浏览 收藏
-
- 数据库 · MySQL | 1小时前 | mysql 空间函数 ST_PointAtDistance
- MySQL ST_PointAtDistance为何报距离越界
- 275浏览 收藏
-
- 数据库 · MySQL | 15小时前 | MySQL · 错误排查 · mysql 空间数据 长度单位 ST_FrechetDistance SRID 0 ER_GEOMETRY_IN_UNKNOWN_LENGTH_UNIT
- MySQL ST_FrechetDistance 指定米单位为什么报错
- 360浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 1035次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 1033次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 1178次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 1139次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 981次使用
-
- 用查询属性把页面或请求来源传给当前 SQL 并在服务器端读取
- 2026-11-05 501浏览
-
- MySQL JSON_TABLE 展开数组时如何保留缺失字段
- 2026-09-10 501浏览
-
- MySQL 分区表怎么处理跨分区唯一键:分区列约束与建表取舍
- 2026-08-30 501浏览
-
- MySQL权限管理设置全攻略
- 2026-03-29 501浏览
-
- MySQL分片实现方法及常见方案解析
- 2025-06-24 501浏览

