您的当前位置:首页>全部文章>文章详情

【MySQL】MySQL中的json操作

CrazyPanda发表于:2024-07-26 16:41:36浏览:255次TAG:

引言

Mysql5.7版本以后提供了一个原生的Json类型,Json值将不再以字符串的形式存储,而是采用一种允许快速读取文本元素(document elements)的内部二进制(internal binary)格式。 在Json列插入或者更新的时候将会自动验证Json文本,未通过验证的文本将产生一个错误信息。 Json文本采用标准的创建方式,可以使用大多数的比较操作符进行比较操作,例如:=, <, <=, >, >=, <>, != 和 <=>。
mybatis中操作json

1.建表及添加数据

--先创建一个简单的含json格式的数据库表,其中json_value就为json格式的字段。CREATE TABLE `dept` (  `id` int(11) NOT NULL,  `dept` varchar(255) DEFAULT NULL,  `json_value` json DEFAULT NULL,  PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;--添加数据insert into dept VALUES(1,'部门1','{"deptName": "部门1", "deptId": "1", "deptLeaderId": "3"}');insert into dept VALUES(2,'部门2','{"deptName": "部门2", "deptId": "2", "deptLeaderId": "4"}');insert into dept VALUES(3,'部门3','{"deptName": "部门3", "deptId": "3", "deptLeaderId": "5"}');insert into dept VALUES(4,'部门4','{"deptName": "部门4", "deptId": "4", "deptLeaderId": "5"}');insert into dept VALUES(5,'部门5','{"deptName": "部门5", "deptId": "5", "deptLeaderId": "5"}');12345678910111213

2.基础查询

用法提示:
如果json字符串不是数组,则直接使用$.字段名
如果json字符串是数组[Array],则直接使用$[对应元素的索引id]

2.1 一般json查询

使用 json字段名->'$.json属性' 进行查询条件

--查询deptLeaderId=5的数据SELECT * from dept WHERE json_value->'$.deptLeaderId'='5';12

在这里插入图片描述

2.2 多个条件查询

--查dept为“部门3”和deptLeaderId=5的数据,sql如下:SELECT * from dept WHERE json_value->'$.deptLeaderId'='5' and dept='部门3';12

2.4 关联表查询

--再创建一张包含json格式的表CREATE TABLE `dept_leader` (  `id` int(11) NOT NULL,  `leaderName` varchar(255) DEFAULT NULL,  `json_value` json DEFAULT NULL,  PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;--插入一些测试数据insert into dept_leader VALUES(1,'leader1','{"name": "王一", "id": "1", "leaderId": "1"}');insert into dept_leader VALUES(2,'leader2','{"name": "王二", "id": "2", "leaderId": "3"}');insert into dept_leader VALUES(3,'leader3','{"name": "王三", "id": "3", "leaderId": "4"}');insert into dept_leader VALUES(4,'leader4','{"name": "王四", "id": "4", "leaderId": "5"}');insert into dept_leader VALUES(5,'leader5','{"name": "王五", "id": "5", "leaderId": "5"}');--连表查询在dept表中部门leader在dept_leader中的详情SELECT * from dept,dept_leader 
WHERE dept.json_value->'$.deptLeaderId'=dept_leader.json_value->'$.id' ;12345678910111213141516

3.JSON函数操作

上述查询的json都是整条json数据,这样看起来不是很方便,那么如果我们只想看json中的某个字段怎么办?

3.1 ->、->>区别

->会保持json文档格式中原来格式,但->>会把所有引号去掉。
特别注意:->当做where查询是要注意类型的,->>是不用注意类型的

select * from dept where json_value->'$.deptId'=11

在这里插入图片描述

select * from dept where json_value->'$.deptId'='1'1

在这里插入图片描述

3.2 JSON_EXTRACT 函数:从json中返回想要的字段

1.可以通过key查询value值(如果是json数组类型,可以通过下标获取对应位置的值),非常方便。

2.使用场景:JSON_EXTRACT性能验证 , 通过查看执行计划,验证全部都是全表扫描。数据量不大json字符串较大则可以采用,数据量较大不建议使用。

3.语法:JSON_EXTRACT(json_doc, path[, path] …)

4.栗子

select 
	json_extract('{"name":"zhangsan","tel_no":"136-6666-6666","hobbies":["basketball","run","sing"]}',"$.name") as name,
	json_extract('{"name":"zhangsan","tel_no":"136-6666-6666","hobbies":["basketball","run","sing"]}',"$.tel_no") as tel_no,
	json_extract('{"name":"zhangsan","tel_no":"136-6666-6666","hobbies":["basketball","run","sing"]}',"$.hobbies[0]") as hobby_1,
	json_extract('{"name":"zhangsan","tel_no":"136-6666-6666","hobbies":["basketball","run","sing"]}',"$.hobbies[1]") as hobby_2,
	json_extract('{"name":"zhangsan","tel_no":"136-6666-6666","hobbies":["basketball","run","sing"]}',"$.hobbies[2]") as hobby_3,
	json_extract('{"name":"zhangsan","tel_no":"136-6666-6666","hobbies":["basketball","run","sing"]}',"$.hobbies[3]") as hobby_4;1234567

结果:
在这里插入图片描述
举例查询:

-- 创建测试表CREATE TABLE `tab_json` (  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键id',  `data` json DEFAULT NULL COMMENT 'json字符串',  PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- 新增数据-- {"Tel": "132223232444", "name": "david", "address": "Beijing"}-- {"Tel": "13390989765", "name": "Mike", "address": "Guangzhou"}INSERT INTO `testdb`.`tab_json`(`id`, `data`) VALUES (1, '{\"Tel\": \"132223232444\", \"name\": \"david\", \"address\": \"Beijing\"}');INSERT INTO `testdb`.`tab_json`(`id`, `data`) VALUES (2, '{\"Tel\": \"13390989765\", \"name\": \"Mike\", \"address\": \"Guangzhou\"}');INSERT INTO `testdb`.`tab_json`(`id`, `data`) VALUES (3, '{"success": true,"code": "0","message": "","data": {"name": "jerry","age": "18","sex": "男"}}');INSERT INTO `testdb`.`tab_json`(`id`, `data`) VALUES (4, '{"success": true,"code": "1","message": "","data": {"name": "tome","age": "30","sex": "女"}}');-- 查询select * from tab_json;-- json_extractselect json_extract('{"name":"Zhaim","tel":"13240133388"}',"$.tel");select json_extract('{"name":"Zhaim","tel":"13240133388"}',"$.name");-- 对tab_json表使用json_extract函数select json_extract(data,'$.name') from tab_json;#如果查询没有的key,那么是可以查询,不过返回的是NULL.select json_extract(data,'$.name'),json_extract(data,'$.Tel') from tab_json;  select json_extract(data,'$.name'),json_extract(data,'$.tel') from tab_json;  select json_extract(data,'$.name'),json_extract(data,'$.address') from tab_json;-- 条件查询select json_extract(data,'$.name'),json_extract(data,'$.Tel') from tab_json where json_extract(data,'$.name') = 'Mike';  -- 嵌套json查询select * from tab_json where json_extract(data,'$.success') = true;  select json_extract(data,'$.data') from tab_json where json_extract(data,'$.success') = true;  -- 查询data对应json中key为name的值select json_extract( json_extract(data,'$.data'),'$.name') from tab_json where json_extract(data,'$.code') = "1";  select json_extract( json_extract(data,'$.data'),'$.name'),json_extract( json_extract(data,'$.data'),'$.age') from tab_json where json_extract(data,'$.code') = "0";  -- 性能验证 , 通过验证全部都是全表扫描,使用场景:数据量不大json字符串较大则可以采用,数据量较大不建议使用。explain select * from tab_json where json_extract(data,'$.success') = true;  explain select json_extract(data,'$.data') from tab_json where json_extract(data,'$.success') = true;  -- 查询data对应json中key为name的值explain select json_extract( json_extract(data,'$.data'),'$.name') from tab_json where json_extract(data,'$.code') = "1";  explain select json_extract( json_extract(data,'$.data'),'$.name'),json_extract( json_extract(data,'$.data'),'$.age') from tab_json where json_extract(data,'$.code') = "0";1234567891011121314151617181920212223242526272829303132333435363738394041424344454647

3.3 JSON_CONTAINS():JSON格式数据是否在字段中包含特定对象

用法: JSON_CONTAINS(target, candidate[, path])

--查询包含deptName=部门5的对象select * from dept WHERE JSON_CONTAINS(json_value, JSON_OBJECT("deptName","部门5"))12

3.4 JSON_OBJECT():将一个键值对列表转换成json对象

比如我们想查询某个对象里面的值等于多少
比如我们添加这么一组数据到dept表中:

insert into dept VALUES(6,'部门9','{"deptName": {"dept":"de","depp":"dd"}, "deptId": "5", "deptLeaderId": "5"}');1

我们可以看到deptName中还有一个对象,里面还有dept和depp两个属性字段,那么我们应该怎么查询depp=dd的员工呢。

用法:JSON_OBJECT([key, val[, key, val] …])
事例:

SELECT * from (SELECT *,json_value->'$.deptName' as deptName FROM dept) t WHERE JSON_CONTAINS(deptName,JSON_OBJECT("depp","dd"));123

3.5 JSON_ARRAY():创建JSON数组

比如我们添加这么一组数据到dept表中:

insert into dept VALUES(7,'部门9','{"deptName": ["1","2","3"], "deptId": "5", "deptLeaderId": "5"}');insert into dept VALUES(7,'部门9','{"deptName": ["5","6","7"], "deptId": "5", "deptLeaderId": "5"}');12

用法:JSON_ARRAY([val[, val] …])

事例:我们要查询deptName包含1的数据

SELECT * from dept WHERE JSON_CONTAINS(json_value->'$.deptName',JSON_ARRAY("1"))1

3.6 JSON_TYPE():查询某个json字段属性类型

用法:JSON_TYPE(json_val)
事例:比如我们想查询deptName的字段属性是什么

SELECT json_value->'$.deptName' ,JSON_TYPE(json_value->'$.deptName') as type from dept1

3.7 JSON_KEYS():JSON文档中的键数组

用法:JSON_KEYS(json_value)
事例:比如我们想查询json格式数据中的所有key

SELECT JSON_KEYS(json_value) FROM dept1

接下来的3种函数都是新增数据类型的:

JSON_SET(json_doc, path, val[, path, val] …)JSON_INSERT(json_doc, path, val[, path, val] …)JSON_REPLACE(json_doc, path, val[, path, val] …)123

3.8 JSON_SET():将数据插入JSON格式中,有key则替换,无key则新增

这也是我们开发过程中经常会用到的一个函数
用法:JSON_SET(json_doc, path, val[, path, val] …)
事例:比如我们想针对id=2的数据新增一组:newData:新增的数据,修改deptName为新增的部门1

update dept set json_value=JSON_SET('{"deptName": "部门2", "deptId": "2", "deptLeaderId": "4"}','$.deptName','新增的部门1','$.newData','新增的数据') WHERE id=2;1

注意:json_doc如果不带这个单元格之前的值,之前的值是会新值被覆盖的,比如我们如果更新的语句换成:

update dept set json_value=JSON_SET('{"a":"1","b":"2"}','$.deptName','新增的部门1','$.newData','新增的数据') WHERE id=21

我们可以看到这里json_doc是{“a”:“1”,“b”:“2”},这样的话会把之前的单元格值覆盖后再新增/覆盖这个单元格字段

3.9 JSON_INSERT():插入值(往json中插入新值,但不替换已经存在的旧值)

用法:JSON_INSERT(json_doc, path, val[, path, val] …)
事例:

UPDATE dept set json_value=JSON_INSERT('{"a": "1", "b": "2"}', '$.deptName', '新增的部门2','$.newData2','新增的数据2') WHERE id=212

我们可以看到由于json_doc变化将之前的值覆盖了,新增了deptName和newData2.
如果我们再执行以下刚才的那个sql,只是换了value,我们会看到里面的key值不会发生变化。
因为这个函数只负责往json中插入新值,但不替换已经存在的旧值。

3.10 JSON_REPLACE()

用法:JSON_REPLACE(json_doc, path, val[, path, val] …)
用例:
如果我们要更新id=2数据中newData2的值为:更新的数据2

UPDATE dept set json_value=JSON_REPLACE('{"a": "1", "b": "2", "deptName": "新增的部门2", "newData2": "新增的数据2"}', '$.newData2', '更新的数据2') WHERE id =2;1

3.11 JSON_REMOVE():从JSON文档中删除数据

用法:JSON_REMOVE(json_doc, path[, path] …)
举例:删除key为a的字段。

UPDATE dept set json_value=JSON_REMOVE('{"a": "1", "b": "2", "deptName": "新增的部门2", "newData2": "更新的数据2"}','$.a') WHERE id =2;1

猜你喜欢

【MySql】MySQL产生死锁的根本原因及解决方法
概念死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等的进程称为死锁进程一、 什么是死锁死锁是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等的进程称为死锁进程.二、 死锁产生的四个必要条件互斥条件:指进程对所分配到的资源进行排它性使用,即在一段时间内某资源只
发表于:2024-03-13 浏览:295 TAG:
【MySql】深入解析数据库索引
写在前面&nbsp;MySQL索引是数据库中一个关键的概念,它可以极大地提高查询性能,加快数据检索速度。但是,要充分发挥索引的作用,需要深入理解它们的工作原理和使用方式。在本文中,我们将深入解析MySQL索引,探讨它们的重要性、类型、创建、维护以及最佳实践。一、基础介绍&nbsp;1.1&nbsp;什么是索引?在数据库中,索引是一种数据结构,用于快速查找表中的数据。索引包含表中一列或多列的值,这些值按照一定的顺序进行排序,以便优化数据的检索速度。通过使用索引,数据库可以避免全表扫描,从而提高查询
发表于:2023-12-07 浏览:357 TAG:
【MySQL】索引有哪些优缺点
索引是数据库中用于提高查询性能的重要工具,但它也有一些有点和确定,一下是索引的主要优缺点:优点:&nbsp;&nbsp;&nbsp;&nbsp;1. 加速查询速度最显而易见的有嗲你是加速select查询速度。通过使用索引,数据库引擎能够更快的定位和检索数据,特别是在大型数据集中。&nbsp;&nbsp;&nbsp;&nbsp;2. 排序性能提升索引可以提高排序操作的性能,因为数据库引擎可以按照索引顺序而不是表中实际物理存储顺序来执行排序。&nbsp;&nbsp;&nbsp;&nbsp;3. 唯一
发表于:2024-06-16 浏览:276 TAG:
【MySql】索引怎么提高查询的速度?
文章目录索引:怎么提高查询的速度?如何创建组合索引?组合索引的原理如何创建单字段索引?单字段索引的作用如何选择索引字段?索引是什么?单字段索引组合索引总结索引索引相关面试题MySQL索引的底层实现索引创建原则索引优缺点索引失效场景索引:怎么提高查询的速度?在超市信息系统刚刚开始运营的时候,因为数据量很少,每一次的查询都能很快拿到结果。但是,系统运转时间长了以后,数据量不断地累积,变得越来越庞大,很多查询的速度就变得特别慢。这个时候,我们就采用了 MySQL 提供的高效访问数据的方法—— 索引,有
发表于:2023-12-07 浏览:383 TAG:
【MySQL】MySQL数据库CPU飙升到100%解决方案
1、定位cpu问题所在当cpu飙升到100%时,先用操作系统命令top命令观察是不是mysqld占用导致的,如果不是,找出占用高的进程,并进行相关处理。2、查看慢查询日志进入mysql命令行mysql&nbsp;-h主机地址&nbsp;-u用户名&nbsp;-p用户密码1查看慢查询SQL是否启用:ON是开启,OFF是关闭。 show variables like ‘log_slow_queries’;开启慢查询日志 set global log_slow_queries = on;3、使用sho
发表于:2024-07-17 浏览:256 TAG:
【MySql】json字段内数据求和
首先,我们需要使用JSON_EXTRACT函数来解析JSON数据。假设我们的数据表名为data_table,JSON数据字段名为json_data,需要查询的字段为field_name。```sql SELECT&nbsp;JSON_EXTRACT(json_data,&nbsp;&#39;$.field_name&#39;)&nbsp;AS&nbsp;extracted_field FROM&nbsp;data_table;###&nbsp;步骤2:使用JSON函数提取数组内字段 如果字段是一
发表于:2024-09-18 浏览:216 TAG: #mysql
【MySql】怎么利用聚合函数实现高效地分组统计?
文章目录聚合函数:怎么高效地进行分组统计?sum( )avg( ) &amp; max( ) &amp; min( )count( )聚合函数:怎么高效地进行分组统计?MySQL中有5种聚合函数较为常用,分别是求和函数sum(), 求平均函数avg(), 最大值函数max(), 最小值函数min()和计数函数count()。在超市项目中有一个需求是这样的:经营者提出,他们需要统计一个门店,每天、每个单品的销售情况,包括销售数量和销售金额等。这里涉及3个数据表,具体信息如下所示:销售明细表demo
发表于:2023-12-08 浏览:392 TAG:
【MySql】批量替换数据表中某字段的值
系统域名变更,需要把数据库存储的图片、文件等链接域名也替换掉,使用了文字替换的方法,在此记录一下:数据库:mysqlUPDATE&nbsp;user&nbsp;SET&nbsp;headimg&nbsp;=&nbsp;REPLACE(headimg,&nbsp;&#39;a.com&#39;,&nbsp;&#39;b.com&#39;);其中 user 是数据表,headimg是其中的字段,把headimg中&#39;a.com&#39;全部替换成&#39;b.com&#39;,headimg中
发表于:2024-04-02 浏览:337 TAG:
【MySQL】 复合查询 | 内外连接
文章目录1. 复合查询unionunion all单行子查询多行子查询多列子查询in关键字all关键字any关键字多表笛卡尔积自连接在where子句使用子查询在from子句中使用子查询合并查询2. 内连接3. 外连接左外连接右外连接1. 复合查询多表笛卡尔积显示雇员名、雇员工资以及所在部门的名字由于员工 信息属于 emp表 而所在部门名字属于 dept表 数据来自不同的表,所以需要进行多表查询表示从 emp (员工表) 和dept (部门表)
发表于:2023-11-30 浏览:872 TAG:
【MySQL】MySQL主从同步实现
要实现MySQL的主从同步,可以按照以下步骤来进行操作:1 配置主服务器确保主服务器的MySQL配置文件my.cnf或my.ini中启动了二进制日志中brinary.log,即设置了log-bin参数为ON。为主数据库创建一个用于复制的用户,并授予复制权限。例如使用以下明命令:Create USER &#39;repl&#39;@&#39;slave_ip_address&#39; INENTIFIED BY &#39;password&#39;;Grant REPLACEACTION SLAV
发表于:2024-06-27 浏览:244 TAG: