JSON 修改函数是什么
MySQL 有三个修改 JSON 文档的函数,分工明确:JSON_SET 有则改、无则插;JSON_INSERT 只在键不存在时插入;JSON_REPLACE 只在键存在时修改。PostgreSQL 用 jsonb_set 统一处理,配合 - 与 #- 运算符删除键或数组元素。
基本信息
| JSON_SET | 路径存在就改值,不存在就新增,最常用 |
|---|---|
| JSON_INSERT | 只新增不存在的路径,已存在时静默不动 |
| JSON_REPLACE | 只修改已存在的路径,不存在时静默不动 |
| JSON_REMOVE | 删除指定路径上的键或数组元素 |
| PostgreSQL 修改 | jsonb_set(target, path, value[, create_missing]) |
| PostgreSQL 删除 | 用 - 删除键,用 #- 删除路径上的元素 |
MySQL 四个函数
MySQL 四个函数
-- 有则改、无则插
SELECT JSON_SET(doc, '$.status', 'paid') FROM orders;
-- 只插:键已存在时什么都不做
SELECT JSON_INSERT(doc, '$.vip', true) FROM users;
-- 只改:键不存在时什么都不做
SELECT JSON_REPLACE(doc, '$.status', 'paid') FROM orders;
-- 删除键
SELECT JSON_REMOVE(doc, '$.temp') FROM orders;
-- 落库:整列替换,注意并发下的读改写
UPDATE orders SET doc = JSON_SET(doc, '$.status', 'paid') WHERE id = 1;PostgreSQL 写法
PostgreSQL 写法
-- 字符串值要写成 JSON 字面量:先加双引号再转 jsonb
UPDATE orders
SET doc = jsonb_set(doc, '{status}', '"paid"'::jsonb)
WHERE id = 1;
-- create_missing = false:路径不存在时原样返回,不报错也不新增
SELECT jsonb_set(doc, '{vip}', 'true', false) FROM users;
-- 删除键与删除路径上的数组元素
SELECT doc - 'temp' AS del_key, doc #- '{a,0}' AS del_elem FROM orders;三个 MySQL 函数的分工
| 函数 | 路径已存在 | 路径不存在 |
|---|---|---|
| JSON_SET | 改成新值 | 新增该键 |
| JSON_INSERT | 保持原值不动 | 新增该键 |
| JSON_REPLACE | 改成新值 | 文档保持不变 |
| JSON_REMOVE | 删除该键 | 无任何影响 |
典型使用场景
- 订单状态流转:把状态与时间写进 JSON 明细
- 用户偏好设置:只新增不覆盖已有配置
- 审计信息追加:写操作备注、来源等字段
- 灰度开关切换:批量更新配置文档里的开关值
- 清理临时字段:删除调试期留下的键
- 回调落地:把上游返回的补充信息合并进已有文档
PostgreSQL 的 jsonb_set 不会自动补齐中间路径:要写 doc->'a'->'b' 里的 b,前提是 a 已经存在;否则需要先把 a 建成空对象再写入,或者改用 jsonb 的合并运算构造新文档。
MySQL 这三个函数在路径不存在时的行为完全不同,JSON_INSERT 与 JSON_REPLACE 都会静默跳过而不报错。写完后务必回读一条数据确认改动真的生效,别把 bug 留到上线之后。