【MySQL】JSON 格式字段处理

news2024/12/24 20:43:04

MySQL 5.7 版本后已支持 JSON 格式,这虽是 MySQL 的一小步,但可以说是程序开发的一大步,再也不用将 JSON 内容塞到 VARCHAR 类型字段了,程序设计也会变得更加灵活。网上大多只针对JSONObject 对象类型,本文也将详解 JSONArray 数组类型。

目录

1 定义

JSONObject:对象

JSONArray:数组

建表 SQL

插入数据 SQL

2 原生查询

原生查询规则

条件查询

3 常用函数

① JSON_EXTRACT() 提取

② JSON_SET() 更新

③ JSON_INSERT() 插入

④ JSON_REPLACE() 替换

⑤ JSON_REMOVE()  移除

⑥ JSON_OBJECT()、JSON_ARRAY()

⑦ JSON_CONTAINS() 是否包含

⑧ JSON_TYPE()类型

⑨ JSON_KEYS() 键名

⑩ JSON_SEARCH()  深度查询

总结


1 定义

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,它以键值对的方式存储数据,并以大括号和方括号进行标记,MySQL JSON 格式字段可以存储 JSON 对象和数组。

JSONObject:对象

{
  "name": "yinyu",
  "age": "18"
}

JSONArray:数组

["yinyu", "tom", "jack"]

而且对象和数组都可以嵌套其他对象或数组,从而形成复杂的数据结构,比如 👇

[
  {
    "name": "yinyu",
    "age": [18, 28, 38]
  },
  "tom",
  "jack"
]

对于对象来说,它的键只能为字符串,值类型支持 null,string,boolean,number,object,array 等。

建表 SQL

在创建表时,可以指定字段类型为 JSON ,不过无需指定 JSON 类型的长度,因为默认值只能为 null 。此外,JSON 字段类型可以根据实际存储的数据自动推断是对象还是数组结构,因此无需显式指定。

create table `test_json_tb` (
  `id` bigint(20) not null auto_increment,
  `json_obj` json default null comment 'json 对象字段',
  `json_arr` json default null comment 'json 数组字段',
  primary key (`id`)
) engine=innodb default charset=utf8mb4;

插入数据 SQL

insert into test_json_tb(json_obj, json_arr) values
('{"name":"yinyu", "age":18, "tags":["rap", "dance"]}', '["yinyu", "yinyu1", "yinyu2"]'),
('{"name":"tom", "age":19, "tags":["rap"]}', '["tom"]'),
('{"name":"jack", "age":20, "tags":["dance"]}', '[{"name":"jack"}, {"age":"20"}]');

建表如图 👇,接下来将使用该数据表来教学 MYSQL JSON 常用函数。

2 原生查询

原生查询规则

针对 JSONObject 对象的规则:json对象字段名->’$.json属性名’

针对 JSONArray 数组的规则:json数组字段名->’$[数组索引]’  or  json对象字段名->’$数组的键名[数组索引]’

示例:

select
	json_obj->'$.name' name,
	json_obj->'$.tags[0]' tags0,
	json_arr->'$[0]' arr0
from test_json_tb;

可以看到查询到的字段字符串类型有个双引号,那么可以通过将 -> 替换成 ->> 去除,转义符同时也会去除。

条件查询

那么我们使用原生查询规则来试下条件查询,比如 👇

select *
from test_json_tb
where json_obj->'$.name' = 'yinyu';

由于 JSON 字段的模糊搜索仅支持 %str% 格式,因此它的模糊搜索时索引无效:

select * 
from test_json_tb 
where json_obj->'$.name' like '%yin%';

对于联表查询、多条件查询均是支持的~

3 常用函数

JSONObject 对象类型和 JSONArray 数组类型基本上都可以使用以下函数,而网上攻略大多只针对JSONObject 对象类型,因此我补充了 JSONArray 数组类型的相关规则和示例。

① JSON_EXTRACT() 提取

规则和原生查询类型~

针对 JSONObject 对象类型,规则:json_extract(对象字段名, '$.属性名')

针对 JSONArray 数组类型,规则:json_extract(数组字段名, '$[数组索引]') or json_extract(对象字段名, '$.数组的键名[数组索引]')

select id,
	json_extract(json_obj,'$.name') as name,
	json_extract(json_obj,'$.tags[1]') as tags1,
	json_extract(json_arr,'$[0]') as arr0
from test_json_tb;

若想去除双引号,可以使用 JSON_UNQUOTE(JSON_EXTRACT())。

② JSON_SET() 更新

将数据插入到 JSON 格式字段中,如果是 JSONObject 对象类型,则有 key 则替换,无 key 则新增;如果是 JSONArray 数组类型,则根据索引进行替换或新增,规则以 JSONObject 对象类型为例。

规则:JSON_SET(json数据, '$.属性名', '更新/插入的值/数组', '$.数组的键名[数组索引]', '更新/插入的值'......)

示例:比如修改第2条数据,将他的 age 修改为 20,并且 tags 增加一个 “dance”:

update test_json_tb t1
set json_obj = json_set(t1.json_obj,'$.age',20, '$.tags[1]', 'dance') 
where id=2;

更新后的记录 👇

③ JSON_INSERT() 插入

JSON_SET() 类似,但 JSON_INSERT() 只插入不更新(有 key 保持原样)。

规则:JSON_INSERT(json数据, '$.属性名', '更新/插入的值/数组', '$.数组的键名[数组索引]', '更新/插入的值'......)

示例:比如给第3条数据新增一个 age 属性和 from 属性,但是执行 sql 后会发现 age 属性插入是不生效的,这是因为 age 属性已存在,而 from 属性新增成功。

update test_json_tb t1
set json_obj = json_insert(t1.json_obj,'$.age', 21,'$.from', 'china') 
where id=3;

④ JSON_REPLACE() 替换

JSON_REPLACE() 的作用就是只替换/更新,不插入,针对JSONObject 对象类型,则有 key 则替换,无 key 则保持原样;如果是 JSONArray 数组类型,则根据索引进行替换,规则以 JSONObject 对象类型为例。

规则:JSON_REPLACE(json数据, '$.属性名', '替换的值/数组', '$.数组的键名[数组索引]', '替换的值'......)

示例:接着上边第3条记录,给 age 属性的值替换成 21,tags 数组的第一个值替换成 “rap”

update test_json_tb t1
set json_obj = json_replace(t1.json_obj,'$.age', 21,'$.tags[0]', 'rap') 
where id=3;

注意:如果该属性或数组索引不存在,那么是不会进行替换的,和 JSON_INSERT() 正好是反着来,而 JSON_SET() 集合了这两者。

⑤ JSON_REMOVE()  移除

顾名思义,该函数的作用是从删除 JSON 数据。

规则:JSON_REMOVE(json数据, '$.属性名', '$.数组的键名[数组索引]')

示例:之前不是给第3条记录增加了 from 属性么,我们来移除它,并且移除 json_arr 字段的第二个属性。

update test_json_tb t1
set json_obj = json_remove(t1.json_obj,'$.from'),
	json_arr = json_remove(t1.json_arr,'$[1]') 
where id=3;

⑥ JSON_OBJECT()、JSON_ARRAY()

这两个函数分别对应 JSON 对象和 JSON 数组,分别用来创建 JSON 对象和 JSON 数组,可以搭配 JSON_SET()、JSON_INSERT()、JSON_REPLACE() 等函数,也可用于查询等操作。

规则:JSON_OBJECT(键名, 值, 键名, 值......)、JSON_ARRAY(元素、元素、元素......)

接下来以插表 SQL 作为示例:

insert into test_json_tb(json_obj, json_arr) values
(json_object('age',22,'name','mike','tags',json_array('sing')), 
 json_array(11,22,33));

⑦ JSON_CONTAINS() 是否包含

校验 JSON 数据中是否包含特定值(可以是属性、对象、数组、数组索引等)。

规则:JSON_CONTAINS(target, candidate[, path]),详情看示例

示例1:查询出 json_obj 字段中包含 age = 18 的记录

select * from test_json_tb 
where json_contains(json_obj, json_object('age',18))

示例2:查询出 json_arr 字段中包含 11 的记录

select * from test_json_tb 
where json_contains(json_arr, json_array(11))

示例3:查询出 json_obj 字段中 tags 属性中同时包含 “rap” 和 “dance” 的记录


select * from test_json_tb 
where json_contains(json_obj, json_array('rap','dance'), '$.tags')

⑧ JSON_TYPE()类型

查询某个 JSON 字段属性类型。

规则:JSON_TYPE(原生查询或 JSON_EXTRACT())

示例:查看 json_obj 字段中 tags 属性的类型

select json_obj->'$.tags' ,json_type(json_obj->'$.tags') as type 
from test_json_tb 
-- or
select json_extract(json_obj,'$.tags') ,
	   json_type(json_extract(json_obj,'$.tags')) as type 
from test_json_tb 

⑨ JSON_KEYS() 键名

查询 JSON 数据中的所有键/key,返回列表,针对 JSON 对象,因为数组是没有键的。

规则:JSON_KEYS(json_value)

select json_keys(json_obj) 
from test_json_tb 

⑩ JSON_SEARCH()  深度查询

JSON_SEARCH() 函数,简单来说就是加强版查询,其实 JSON_EXTRACT() + limit SQL也能达到效果。

规则:JSON_SEARCH(json数据,one/all,json 查询规则)

one 是返回1条记录,all 是返回符合条件的所有记录

示例1:查询路径--以 json 对象为例

select json_search(json_obj,'all','yinyu', null)
from test_json_tb

他会返回符合条件的记录里的路径,若是路径编写有困难,那么可以试下这个深度查询!

null -- 若搜索内容不存在,则返回 NULL,第三个参数为值。

示例2:条件查询--针对 json 对象(第五个参数为路径,条件查询时搭配  is not null)

查询 json_obj 字段中 name 属性为 “yinyu” 的记录

select *
from test_json_tb
where json_search(json_obj,'all','yinyu', null,'$.name') is not null

示例3:条件查询--针对 json 数组

查询 json_arr 字段中第一个元素为 “yinyu” 的记录

select *
from test_json_tb
where json_search(json_arr,'all','yinyu', null,'$[0]') is not null

示例4:模糊查询

select *
from test_json_tb
where json_search(json_obj,'all','%t%', null,'$.name') is not null


总结

本文完善了 JSON 数组的相关操作,大家如果有疑问都可以评论提出,有不足之处请大家批评指正,希望能多结识这方面的朋友,共同学习、共同进步。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/902816.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux网络服务之iptables防火墙工具

I P T A B L E S 一、防火墙简介1.1 netfilter1.2 firewalld和iptables 二、iptables工具简述2.1 定义2.2 三种报文流向2.3 iptables的表、链结构(非常重要)2.3.1 "四表" ----- 规则表2.3.2 "五链" ----- 规则链 三、iptables配置3.…

适合低成本兼职的十个职业,做得好可能比上班挣得还多

这个年头干点什么兼职或者副业比较合适的,其实做兼职和副业就那么几条原则:最好是轻资产或者不投入资金,因为这个年代是现金流和储蓄为王,不能乱投资,一旦出了差错,更是雪上加霜。还有就是最好在网络上做兼…

对话音视频牛哥:开发RTSP|RTMP直播播放器难不难?难在哪?

我关注的播放器指标 好多开发者跟我交流音视频相关技术的时候,经常问我的问题是,多久可以开发个商业级别的RTMP或RTSP播放器?你们是怎样做到毫秒级延迟的?为什么一个播放器,会被你们做到那么复杂?带着这些…

一文详解4种聚类算法及可视化(Python)

在这篇文章中,基于20家公司的股票价格时间序列数据。根据股票价格之间的相关性,看一下对这些公司进行聚类的四种不同方式。 苹果(AAPL),亚马逊(AMZN),Facebook(META&…

裴蜀定理-拓展欧几里得算法--夏令营

题目 知识点 1.裴蜀定理: 欧几里得算法gcd辗转相除法 拓展欧几里得算法exgcd裴蜀定理 2.证明: 3.. 代码: int exgcd(int a, int b, int& x, int& y) {if (!b){x 1, y 0;return a;}int d exgcd(b, a % b, y, x);y - a / b * x;…

rabbitMq安装后无法启动可视化页面http://localhost:15672处理

本次安装环境信息: 系统:win10 64位专业版 erlang:otp_win64_23.0 rabbitMQ:rabbitmq-server-3.8.5 安装rabbitMQ需要依赖erlang语言环境,所以需要我们下载erlang的环境安装程序。 一、下载安装程序 rabbitMQ安装…

Lombok 同时使用 @Data 和 @Builder 的巨坑,千万别乱用!

1、Lombok 使用演示 Lombok 使⽤同时使⽤ Data 和 Builder ,构建无参构造器报错!编译不通过。如下图: Lombok 使⽤ Data 可以自动⽣成⽆参构造和类⾥⾯所有属性的 getter/setter ⽅法。可以简化我们代码的开发。(IDEA 需要安装 L…

Redis主从复制搭建

Redis主从复制搭建 Redis虽然拥有非常高的性能,但是在实际的生产环境中,使用单机模式还是会产生不少问题的,比如说容易出现 单机故障,容量瓶颈,以及QPS瓶颈等问题。通常环境下,主从复制、哨兵模式、Redis…

从关键新闻和最新技术看AI行业发展(2023.6.23-7.9第二期) |【WeThinkIn老实人报】

Rocky Ding 公众号:WeThinkIn 写在前面 【WeThinkIn老实人报】是WeThinkIn的全新栏目,旨在整理&挖掘AI行业的关键新闻和最新技术,同时Rocky会对这些关键信息进行解读,力求让读者们能从容跟随AI科技潮流。也欢迎大家提出宝贵的…

中国大学生服务外包创新创业大赛丨借 AI 之力,助“记账”难题

一、中国大学生服务外包创新创业大赛 赛事介绍 中国大学生服务外包创新创业大赛,是响应国家关于鼓励服务外包产业发展、加强服务外包人才培养的相关战略举措与号召,举办的每年一届的全国性竞赛。 大赛均由中华人民共和国教育部、中华人民共和国商务部…

08.SpringBoot请求相应

文章目录 1 请求1.1 Postman1.2 简单参数1.2.1 原始方式1.2.2 SpringBoot方式1.2.3 参数名不一致 1.3 实体参数1.3.1 简单实体对象1.3.2 复杂实体对象 1.4 数组集合参数1.4.1 数组1.4.2 集合 1.5 日期参数1.6 JSON参数1.7 路径参数 2 响应2.1 ResponseBody注解2.2 统一响应结果…

RHCE——二、时间服务器

时间服务器 一、时间服务器1、重要性2、Linux的系统时钟以及硬件时钟3、NTP网络时间协议4、Chrony介绍 二、chrony安装与配置1、安装2、Chrony配置文件分析3、实验3.1 实验13.2 实验2 三、chronyc命令1、查看时间服务器:2、chronyc sources输出分析3、其它命令4、常…

Docker网络的概念

一、说明 本文叙述Docker网络,介绍关于Docker网络、网桥网络、网桥网络、自定义网桥网络、主机网络、无网络 MACVLAN 和 IPVLAN 网络、叠加网络等网络模式。Docker 是一个用于开发、发布和运行应用程序的开放平台。 二、 什么是 Docker Networking? Doc…

如何在HTML里面使用session

原因在springboot项目里面不想使用jsp界面,怎么在HTML里面使用session呢? 借助sessionStorage方法,话不多说直接上代码 自定义一个js文件把这个代码放里面就可,根据具体业务来修改 // globalData 可以随便定义,调用的…

Facebook AI mBART:巴别塔的硅解

2018年,谷歌发布了BERT(来自transformers的双向编码器表示),这是一种预训练的语言模型,在一系列自然语言处理(NLP)任务中对SOTA结果进行评分,并彻底改变了研究领域。类似的基于变压器…

Shell脚本基础教程

Shell脚本基础教程 Shell参数定义 定义变量 想要定义变量,只需要使用如下命令即可。 variable_namevariable_valuevariable_name表示变量名,variable_value表示变量值。注意,等号与变量名和变量值之间不能有空格。 变量名的命名需要遵循…

速通蓝桥杯嵌入式省一教程:(六)PWM输出

定时器除了用于最基本的定时器计时中断以外,还可以用于输出PWM(Pulse Width Modulation)波,即脉冲宽度调制波形,也就是频率与占空比均可改变的矩形波。下面我们就使用PA1端口生成PWM波。 在Cube中,首先需要将PA1设置成定时器的通…

Android LiveData原理之-setValue和数据倒灌原理分析

一图胜万言,直接上图吧!有需要的同学们可以对着这张泳道图阅读源码,相信能够快速加深理解。

3:Ubuntu上配置QT交叉编译环境并编译QT程序到Jetson Orin Nano(ARM)

1.Ubuntu Qt 配置交叉编译环境 1.1 ubuntu 20.04安装Qt sudo apt-get install qtcreator 1.2 配置QT GCC配置同上 最后配置Kits 上面设置完成之后 ,设置Kits 中的Device(这是为了能够直接把项目部署到arm设备上) 点击NEXT之后会出现连接被拒绝,不用担…

IEC61499/ OPCUA pub/sub 测试

OpenDACS 是基于OPCUA 信息模型的IEC61499 分布式自动控制系统。本文介绍它如何采用Opcua Pub/Sub 实现分布式设备中功能块之间的通信。 4diac 构建IEC61499 系统和应用 系统结构 试验系统共有三台设备,为了实验方便,我们让它们在一台Linux PC 上运行…