MySQL中查询和操作JSON类型的数据

前言:MySQL5.7 开始正式支持原生JSON字段,8.0进一步增强JSON函数能力。很多开发会直接把JSON存成VARCHAR,但原生JSON会校验格式,并且提供内置函数方便读取、修改、删除JSON内的key和数组。这篇博客包含建表、查询、新增、修改、删除JSON数据,附带常用函数和避坑点。

一、测试表准备

sql 复制代码
CREATE TABLE product (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100) NOT NULL,
    attr JSON COMMENT '商品扩展JSON属性'
);

-- 插入测试数据
INSERT INTO product(name, attr) VALUES 
('手机', '{"color":"黑色","price":3999,"tags":["旗舰","5G"],"detail":{"weight":"200g","screen":"6.7英寸"}}'),
('耳机', '{"color":"白色","price":299,"tags":["蓝牙","降噪"],"detail":{"weight":"8g","screen":null}}');

二、JSON查询操作

1. -> 和 ->> 提取JSON字段值(最常用)

  • ->:返回带双引号的JSON原始值
  • ->>:返回去掉双引号的字符串,日常查询优先用 ->>
sql 复制代码
-- 查询商品名称、颜色、价格
SELECT 
    name,
    attr->>'$.color' AS color,
    attr->>'$.price' AS price
FROM product;

读取嵌套对象:

sql 复制代码
SELECT name, attr->>'$.detail.weight' AS weight FROM product;

读取数组指定下标元素:

sql 复制代码
-- 获取tags数组第0个元素
SELECT name, attr->>'$.tags[0]' AS tag1 FROM product;

2. JSON_EXTRACT()

-> 本质就是 JSON_EXTRACT() 的简写形式

sql 复制代码
-- 等价 attr->>'$.color'
SELECT JSON_UNQUOTE(JSON_EXTRACT(attr, '$.color')) FROM product;

3. 根据JSON内的值作为WHERE条件过滤

sql 复制代码
-- 查询颜色为黑色的商品
SELECT name FROM product WHERE attr->>'$.color' = '黑色';

-- 查询价格大于1000
SELECT name FROM product WHERE attr->>'$.price' > 1000;

查找数组中是否包含指定元素

sql 复制代码
-- 查询tags数组里面包含"降噪"的商品
SELECT name FROM product 
WHERE JSON_SEARCH(attr, 'one', '降噪', null, '$.tags') IS NOT NULL;

参数说明:one 找到第一个匹配;all 查找全部匹配。

5. JSON_KEYS 获取JSON对象所有key

sql 复制代码
SELECT JSON_KEYS(attr) FROM product;

三、JSON写入(插入)

直接传入标准JSON字符串,或者使用JSON_OBJECT、JSON_ARRAY构造JSON:

sql 复制代码
-- 方式1:直接字符串
INSERT INTO product(name,attr) VALUES ('平板','{"color":"灰色","price":2499}');

-- 方式2:函数构造,不用手动写引号,不容易出错
INSERT INTO product(name,attr) VALUES (
'手表',
JSON_OBJECT("color","银色","price",1299,"tags",JSON_ARRAY("智能","防水"))
);

四、JSON更新操作

JSON_SET:有则更新,无则新增(开发首选)

sql 复制代码
UPDATE product
SET attr = JSON_SET(attr, '$.color', '深空灰', '$.stock', 100)
WHERE id = 1;

JSON_REPLACE:只更新已存在key,不存在则不处理

sql 复制代码
UPDATE product
SET attr = JSON_REPLACE(attr, '$.price', 3699)
WHERE id = 1;

JSON_INSERT:只新增key,已有key不会覆盖

sql 复制代码
UPDATE product
SET attr = JSON_INSERT(attr, '$.stock', 200)
WHERE id = 1;

JSON数组追加:JSON_ARRAY_APPEND

sql 复制代码
UPDATE product
SET attr = JSON_ARRAY_APPEND(attr, '$.tags', '快充')
WHERE id = 1;

JSON数组指定位置插入:JSON_ARRAY_INSERT

sql 复制代码
UPDATE product
SET attr = JSON_ARRAY_INSERT(attr, '$.tags[0]', '新品')
WHERE id = 1;

五、JSON删除操作 JSON_REMOVE

删除JSON对象key、数组元素

sql 复制代码
-- 删除stock字段
UPDATE product
SET attr = JSON_REMOVE(attr, '$.stock')
WHERE id = 1;

-- 删除数组下标1的元素
UPDATE product
SET attr = JSON_REMOVE(attr, '$.tags[1]')
WHERE id = 1;

⚠️ 删除数组多个元素:从大下标往小下标删,删除后数组下标自动前移,顺序正向删除会导致下标错乱。

六、JSON生成列 + 索引(性能优化重点)

原生JSON字段内部key查询不走索引,大数据量查询会全表扫描。可以创建生成列并建立索引:

sql 复制代码
-- 创建生成列,提取color字段
ALTER TABLE product ADD COLUMN color VARCHAR(50) GENERATED ALWAYS AS (attr->>'$.color') STORED;
-- 建立索引
CREATE INDEX idx_product_color ON product(color);

STORED:实际存储数据;VIRTUAL(默认)不占用存储空间,查询时实时计算,不支持加索引。

七、常见踩坑汇总

  1. **路径语法 不能省略** ,`.key,嵌套 .obj.key`(.obj.key`;数组 `) `.arr[0]`
  2. -> 带引号,->> 不带引号,做等值判断WHERE条件必须用 ->>
  3. JSON函数返回新JSON文档,UPDATE时必须赋值回字段 attr=JSON_SET(...),否则不生效
  4. JSON字段本身为NULL时,JSON_SET / JSON_REMOVE都会返回NULL,可用IFNULL(attr, JSON_OBJECT())兜底
  5. JSON数组查找JSON_SEARCH只能匹配字符串;数字类型无法直接搜索,需要转换
  6. 不要用LIKE模糊匹配JSON字符串,JSON内部空格、顺序变化会导致匹配失效
  7. 频繁查询JSON内部字段,优先拆成独立字段;JSON适合存储不常检索的扩展属性

八、函数速查表

函数 作用
JSON_EXTRACT 提取JSON值
JSON_SET 更新/新增key
JSON_REPLACE 仅更新已有key
JSON_INSERT 仅新增key
JSON_REMOVE 删除key/数组元素
JSON_ARRAY_APPEND 数组末尾追加
JSON_ARRAY_INSERT 数组指定位置插入
JSON_SEARCH 查找数组/对象内文本
JSON_OBJECT 构建JSON对象
JSON_ARRAY 构建JSON数组
相关推荐
z06.18 分钟前
MySQL索引
数据库·mysql
考虑考虑24 分钟前
Posrgresql恢复.backup文件
数据库·后端·postgresql
云祺vinchin37 分钟前
中小企业备份软件选型从恢复需求到总体成本评估
数据库·数据备份·中小企业备份·容灾备份软件
翊众建站1 小时前
用 JSON-LD 给企业官网做结构化数据:LocalBusiness 与 FAQPage 实践笔记
人工智能·搜索引擎·json
Zenova EdgeOS1 小时前
Go 工业边缘错误处理实战:用 errors 构建可追溯错误链
开发语言·数据库·golang
KKKlucifer1 小时前
国内数据安全服务的产品智能化转型:大模型赋能下的技术能力重构分析
大数据·数据库·重构
字节跳动开源2 小时前
OpenViking 上线原生 3D 内容理解模型
数据库·开源
CCIE-Yasuo4 小时前
网络安全-学习数据库-Mysql-2
数据库·学习·mysql
这个DBA有点耶4 小时前
内核级AI与多模融合:AI数据库在海外场景的落地要点
数据库·人工智能·架构
涛思数据(TDengine)4 小时前
从工业本体到 AI 原生:TDengine 出席 2026 QCon 分享工业数据基础设施路径
大数据·数据库·人工智能·tdengine·工业