MySQL中查询和操作JSON类型的数据的方法及常见踩坑记录

 更新时间:2026年10月20日 16:57:15   投稿:mrr  
MySQL5.7 开始原生支持JSON 数据类型,8.0 进一步增强了函数和索引能力,这篇文章给大家介绍MySQL中查询和操作JSON类型的数据的方法及常见踩坑记录,感兴趣的朋友一起看看吧

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

一、测试表准备

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原始值
  • ->>:返回去掉双引号的字符串,日常查询优先用 ->>
-- 查询商品名称、颜色、价格
SELECT 
    name,
    attr->>'$.color' AS color,
    attr->>'$.price' AS price
FROM product;

读取嵌套对象:

SELECT name, attr->>'$.detail.weight' AS weight FROM product;

读取数组指定下标元素:

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

2. JSON_EXTRACT()

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

-- 等价 attr->>'$.color'
SELECT JSON_UNQUOTE(JSON_EXTRACT(attr, '$.color')) FROM product;

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

-- 查询颜色为黑色的商品
SELECT name FROM product WHERE attr->>'$.color' = '黑色';
-- 查询价格大于1000
SELECT name FROM product WHERE attr->>'$.price' > 1000;

4. JSON数组包含判断 JSON_SEARCH

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

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

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

5. JSON_KEYS 获取JSON对象所有key

SELECT JSON_KEYS(attr) FROM product;

三、JSON写入(插入)

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

-- 方式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:有则更新,无则新增(开发首选)

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

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

UPDATE product
SET attr = JSON_REPLACE(attr, '$.price', 3699)
WHERE id = 1;

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

UPDATE product
SET attr = JSON_INSERT(attr, '$.stock', 200)
WHERE id = 1;

JSON数组追加:JSON_ARRAY_APPEND

UPDATE product
SET attr = JSON_ARRAY_APPEND(attr, '$.tags', '快充')
WHERE id = 1;

JSON数组指定位置插入:JSON_ARRAY_INSERT

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

五、JSON删除操作 JSON_REMOVE

删除JSON对象key、数组元素

-- 删除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查询不走索引,大数据量查询会全表扫描。可以创建生成列并建立索引:

-- 创建生成列,提取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数组

到此这篇关于MySQL中查询和操作JSON类型的数据的方法及常见踩坑记录的文章就介绍到这了,更多相关mysql查询和操作json数据内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Mysql内连接与外连接的区别详解

    Mysql内连接与外连接的区别详解

    最近别人问我一个问题:数据库中的左连接和右连接有什么区别?所以这篇文章主要给大家介绍了关于Mysql内连接和外连接区别的相关资料,需要的朋友可以参考下
    2023-01-01
  • MYSQL 一个巧用字符函数做数据筛选的题

    MYSQL 一个巧用字符函数做数据筛选的题

    这篇文章主要介绍了MYSQL 一个巧用字符函数做数据筛选的题,需要的朋友可以参考下
    2017-05-05
  • MySQL 最基本的SQL语法/语句

    MySQL 最基本的SQL语法/语句

    MySQL 最基本的SQL语法/语句,使用mysql的朋友可以参考下。
    2011-09-09
  • MySQL更新某个字段拼接固定字符串的实现

    MySQL更新某个字段拼接固定字符串的实现

    在MySQL中,我们经常需要对数据库中的某个字段进行更新操作,本文就来介绍一下MySQL更新某个字段拼接固定字符串的实现,感兴趣的可以了解一下
    2025-04-04
  • MySQL架构体系知识点总结

    MySQL架构体系知识点总结

    在本篇内容里我们给大家整理了关于MySQL架构体系的相关知识点内容以及相关实例,需要的朋友们学习下。
    2019-02-02
  • MySQL8.0 Root用户远程登录配置完整步骤记录

    MySQL8.0 Root用户远程登录配置完整步骤记录

    作为服务器,我们经常需要远程登录数据库,可以设置允许远程登录的用户和访问地,这篇文章主要介绍了MySQL8.0 Root用户远程登录配置完整步骤的相关资料,需要的朋友可以参考下
    2026-08-08
  • MySQL实现乐观锁的方式详解

    MySQL实现乐观锁的方式详解

    在 MySQL 中,可以通过使用乐观锁来实现并发控制,以避免数据冲突和并发更新问题,乐观锁是一种乐观的思想,它假设并发操作不会导致冲突,只有在提交更新时才会检查是否发生冲突,本文给大家介绍了Mysql如何实现乐观锁,需要的朋友可以参考下
    2023-09-09
  • MySQL如何使用使用Xtrabackup进行备份和恢复

    MySQL如何使用使用Xtrabackup进行备份和恢复

    Xtrabackup是由Percona开发的一个开源软件,可实现对InnoDB的数据备份,支持在线热备份(备份时不影响数据读写)。本文讲解如何使用该工具进行备份和恢复
    2021-06-06
  • MySQL中建表时可空(NULL)和非空(NOT NULL)的用法详解

    MySQL中建表时可空(NULL)和非空(NOT NULL)的用法详解

    这篇文章主要介绍了MySQL中建表时可空(NULL)和非空(NOT NULL)的用法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • MySQL数据库表约束讲解

    MySQL数据库表约束讲解

    这篇文章主要介绍了MySQL数据库表约束讲解,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-06-06

最新评论