MySQL 删除 JSON 类型的数据实战

前言:MySQL JSON 的删除分两个层面:① 删除 JSON 文档内部的 key / 数组元素(JSON_REMOVE);② 删除整条包含 JSON 字段的数据行。很多人容易混淆,本文把两种场景的用法、示例、坑点一次性讲清楚。

一、准备测试表

sql 复制代码
CREATE TABLE user_info (
    id INT PRIMARY KEY AUTO_INCREMENT,
    ext JSON COMMENT '用户扩展信息'
);

INSERT INTO user_info(ext) 
VALUES ('{"name":"张三","age":22,"phone":"13800138000","tags":["后端","MySQL","开发"],"address":{"city":"重庆","area":"渝北"}}');

二、删除JSON内部的key:JSON_REMOVE

语法:JSON_REMOVE(json_doc, path[, path] ...)

作用:移除 JSON 文档指定路径的数据,返回新的 JSON 文档。支持一次性删除多个key。

1. 删除一级key

删除 phone 字段:

sql 复制代码
UPDATE user_info
SET ext = JSON_REMOVE(ext, '$.phone')
WHERE id = 1;

2. 删除嵌套对象内的key

删除 address 里面的 area:

sql 复制代码
UPDATE user_info
SET ext = JSON_REMOVE(ext, '$.address.area')
WHERE id = 1;

3. 一次性删除多个key

同时删除 age 和 address:

sql 复制代码
UPDATE user_info
SET ext = JSON_REMOVE(ext, '$.age', '$.address')
WHERE id = 1;

三、删除JSON数组中的元素

数组下标从 0 开始,同样使用 JSON_REMOVE。

原始数据:"tags":["后端","MySQL","开发"]

删除下标1的元素(MySQL):

sql 复制代码
UPDATE user_info
SET ext = JSON_REMOVE(ext, '$.tags[1]')
WHERE id = 1;

⚠️ 重要特性:删除数组元素后,数组下标会自动前移 。

例如:[A,B,C] 删除下标1(B),数组变成 [A,C],C 的下标从2变成1。

如果循环删除数组元素,必须从后往前删,否则下标错乱。

示例:从后往前删除数组多个元素,避免下标偏移问题

sql 复制代码
UPDATE user_info
SET ext = JSON_REMOVE(ext, '$.tags[2]','$.tags[1]')
WHERE id = 1;

四、清空JSON字段(置为空对象/空数组)

  1. 将JSON字段设置为空对象 {}
sql 复制代码
UPDATE user_info SET ext = JSON_OBJECT() WHERE id = 1;
  1. 将JSON字段设置为空数组 []
sql 复制代码
UPDATE user_info SET ext = JSON_ARRAY() WHERE id = 1;
  1. 直接置为NULL
sql 复制代码
UPDATE user_info SET ext = NULL WHERE id = 1;

五、删除整行数据(整条记录)

如果不需要这条记录,直接 DELETE,JSON字段会跟着一起删除:

sql 复制代码
-- 删除id=1的整行
DELETE FROM user_info WHERE id = 1;

六、根据JSON内部条件删除行

根据JSON内部key的值,筛选并删除整条记录:

sql 复制代码
-- 删除 ext->name = '张三' 的行
DELETE FROM user_info
WHERE ext->>'$.name' = '张三';

七、高频踩坑点

  1. JSON_REMOVE 不会修改原数据,必须赋值回字段
sql 复制代码
-- ❌ 错误写法,不会生效
UPDATE user_info SET JSON_REMOVE(ext, '$.phone') WHERE id=1;
-- ✅ 正确写法,函数返回新json,要赋值给ext
UPDATE user_info SET ext = JSON_REMOVE(ext, '$.phone') WHERE id=1;
  1. 路径不存在不会报错,直接原样返回
    写了错误的path,SQL执行成功,但是数据没有任何变化,不会抛出异常。调试时先用SELECT验证路径:
sql 复制代码
SELECT JSON_REMOVE(ext, '$.not_exist_key') FROM user_info WHERE id=1;
  1. ext字段为NULL时,JSON_REMOVE返回NULL

    如果ext本身是NULL,JSON_REMOVE无法操作,不会自动创建JSON对象。

  2. 生成列索引影响

    如果JSON创建了生成列(STORED),删除JSON内对应的key,生成列会同步更新,索引会自动维护,会产生少量性能开销。

  3. 数组删除下标偏移大坑

    数组顺序删除下标0、1、2会出错。因为删掉下标0之后,原来下标1的数据变成下标0。删除多个数组元素,永远从最大下标往最小下标删。

八、选型小结

  • 删除JSON内部key/数组元素:JSON_REMOVE + UPDATE
  • 清空JSON字段:JSON_OBJECT() / JSON_ARRAY() / NULL
  • 删除整条记录:DELETE,支持JSON内部条件过滤
  • 数组批量删除:从后往前删除下标,防止下标错位

小提示:如果业务频繁对JSON数组做增删操作,且需要根据数组元素检索,MySQL原生JSON数组性能较差,建议拆成独立子表。

相关推荐
卿卿的产品经理日记2 小时前
【AI产品经理实战】Day 37|拆开 JSON 与 EXE:数据都有格式
人工智能·笔记·python·json·产品经理
iCxhust2 小时前
51单片机电力载波应用开发(九)51产品化
c语言·数据库·嵌入式硬件·mysql·51单片机·软件工程·c51
whbi3 小时前
基于阿里云的datax现有功能开发的一个可以自动生成.json的配置文件功能或者脚本
json
tryxr3 小时前
如何分析一个慢sql
数据库·sql·mysql·慢sql
tryxr3 小时前
什么情况下索引会失效
数据库·mysql·索引失效·索引
撸串-研究生3 小时前
社区流浪宠物领养救助系统【附源码】
mysql·springboot·宠物·社区公益服务
我命由我123454 小时前
LRU 缓存淘汰策略
数据结构·redis·学习·mysql·算法·缓存·学习方法
mengzhi啊4 小时前
qt把结构体数据存入json文件
qt·json
PHP实战开发录5 小时前
PHP上传文件为什么会被覆盖
数据库·mysql·php