MySQL中JSON数据类型详解

news2024/11/17 3:12:21

目录

概要及优点

JSON定义

JSON字段的增删改查操作

插入操作

查询操作

修改操作

删除操作

如何对JSON字段创建索引?

 加索引查询结果分析:

 不加索引查询结果分析:

使用JSON时的注意事项


概要及优点

        JSON数据类型是MySQL5.7.8开始支持的。在此之前,只能通过字符类型(CHAR、VARCHAR或TEXT)来保存JSON文档。

JSO数据类型具有的优势:

  1. 在插入时能自动校验文档是否满足JSON格式的要求。
  2. 优化了存储格式,无需读取整个文档就能快速访问某个元素的值。
  3. 节省网络带宽,结合索引还能降低磁盘IO消耗。

JSON定义

        JSON 是 JavaScript Object Notation(JavaScript 对象表示法)的缩写,是一个轻量级的,基于文本的,跨语言的数据交换格式。易于阅读和编写。

JSON的基本数据类型:

  • 数值:十进制数,不能前导0,可以为负数或小数,还可以为e或E表示的指数。
  • 字符串:字符串必须用双引号括起来。
  • 布尔值:true、false。
  • 数组:一个由零或多个值组成的有序序列。每个值可以为任意类型。数组使用方括号[ ] 括起来,元素之间用逗号 分隔。

        [1, "abc", null, true, "11:05:00.000000", {"id": 1}]

  • 对象:一个由零或者多个键值对组成的无序集合。其中键必须是字符串,值可以为任意类型。对象使用花括号 { } 括起来,键值对之间使用逗号,分隔,键与值之间用冒号:分隔。

        {"db": ["mysql", "oracle"], "id": 123, "info": {"age": 20}}

  • 空值:null。

JSON字段的增删改查操作

插入操作

1)直接插入JSON格式的字符串

# 创建测试表
create table mytest(id BIGINT ,other json);

# 插入表数据
insert into mytest values(1,'[1, "abc", null, true, "00:00:00.000000"]');

2)使用函数,常用的有JSON_ARRAY()和JSON_OBJECT()

  • JSON_ARRAY():用于构造JSON数组
# 使用json_array()函数插入
insert into mytest values(2,json_array(2,'abc',null,true,now()));

  • JSON_OBJECT():用于构造JSON对象
# 使用json_object()函数插入
insert into mytest values(3,json_object('name','abc','time',now()));

 注意:

        MySQL5.7.x版本,如果插入键重复则会使用第一个键对应的值。

                json_object('key1',10,'key2',20,'key1',30)    结果:{"key1": 10, "key2": 20} 

        MySQL8.0.x版本,如果插入键重复会使用最后出现的键对应的值。

                 json_object('key1',10,'key2',20,'key1',30)    结果:{"key1": 30, "key2": 20} 

查询操作

以此数据为查询元数据

 

 

1)JSON_EXTRACT(json_doc,path[,path] ...)

        json_doc是JSON文档,path是路径。该函数会从JSON文档提取指定路径(path)的元素。如果指定path不存在,会返回NULL。可指定多个path,匹配到的多个值会以数组形式返回。

数组的路径:

  • 通过下标来表示的。第一个元素的下标是0。
# 使用json_extract函数进行查询,通过下标来表示的。
select json_extract(other,'$[0]') as val from mytest;

  • 通过 [ M to N ] 获取数组的子集。
    • MySQL5.7.x版本不支持,本人亲测。
    • MySQL8.0.x版本可以试一试,本人没有测试。
# 使用json_extract函数进行查询,通过[M to N] 获取数组的子集。
select json_extract(other,'$[0 to 1]') as val from mytest;

# 使用$[last-1 to last],这里的 last 代表最后一个元素的下标
select json_extract(other,'$[last-1 to last]') as val from mytest;

  • 通过 $[*],获取数组中的所有元素.
# 使用$[*],获取数组中的所有元素
select json_extract(other,'$[*]') as val from mytest;

 对象的路径:

  • 通过KEY来表示的
# 如果 KEY 在路径表达式中不合法(譬如存在空格),则在引用这个 KEY 时,需用双引号括起来。

# 使用json_extract函数进行查询对象,通过 KEY 来获取属性值
select json_extract(other,'$.name') as val from mytest where id = 3;

select json_extract(other,'$."test a"') as val from mytest where id = 3;

select json_extract(other,'$.testArr[0]') as val from mytest where id = 3;

注意:以上两种语法,在MySQL5.7.x版本不支持,可以在MySQL8.0.x版本试一试。

  • 通过 .* 获取对象中的所有元素
select json_extract(other,'$.*') as val from mytest where id = 3;

# 网上其他示例:

# 这里的 $**.b 匹配 $.a.b 和 $.c.b
select json_extract('{"a": {"b": 1}, "c": {"b": 2}}', '$**.b');

# 结果:
[1, 2]

2)column->path

        column->path,包括后面讲到的 column->>path,都是语法糖,在实际使用的时候都会转化为 JSON_EXTRACT。

        column->path 等同于 JSON_EXTRACT(column, path) ,只能指定一个path。

注意:在MySQL5.7.x版本不支持,可以在MySQL8.0.x版本试一试。

select other->"$name" from mytest where id = 3;
  • column->>path

同 column->path 类似,只不过其返回的是字符串。以下三者是等价的。

  • JSON_UNQUOTE( JSON_EXTRACT(column, path) )
  • JSON_UNQUOTE(column -> path)
  • column->>path
select other->'$.name',json_extract(c2, "$.name"),json_unquote(c2->'$.name'),c2->>'$.name' from mytest;

注意:在MySQL5.7.x版本不支持,可以在MySQL8.0.x版本试一试。

修改操作

1)JSON_INSERT(json_doc, path, val[, path, val] ...)

        插入新值。

        仅当指定位置或指定 KEY 的值不存在时,才执行插入操作。另外,如果指定的 path 是数组下标,且 json_doc 不是数组,该函数首先会将 json_doc 转化为数组,然后再插入新值。

# 示例一:
select json_insert('1','$[0]',"10");

# 结果:
1

# 示例二:
select json_insert('1','$[1]',"10");

# 结果:
[1,"10"]

# 示例三:
select json_insert('["1","2"]','$[2]',"10");

# 结果:
["1", "2", "10"]

2)JSON_SET(json_doc, path, val[, path, val] ...)

        插入新值,并替换已经存在的值。

        如果指定位置或指定 KEY 的值不存在,会执行插入操作,如果存在,则执行更新操作。

set @j = '{ "a": 1, "b": [2, 3]}';

# 示例:
select json_set(@j, '$.a', 10, '$.c', '[true, false]');

#结果:
{"a": 10, "b": [2, 3], "c": "[true, false]"} 

3)JSON_REPLACE(json_doc, path, val[, path, val] ...)

        替换已经存在的值。

set @j = '{ "a": 1, "b": [2, 3]}';

# 示例:
select json_replace(@j, '$.a', 10, '$.c', '[true, false]');

# 结果:
{"a": 10, "b": [2, 3]}

删除操作

1)JSON_REMOVE(json_doc, path[, path] ...)

        删除 JSON 文档指定位置的元素。

# 数据格式:{"name":"123","time":"234"}
# 会删除other字段中的name属性及对应的值
select json_remove(other, '$.name') from mytest where  id = 3;


# 数据格式:other: ["a", ["b", "c"], "d", "e"]
# 会删除other字段中数组下标为1的值
select json_remove(other, '$.[1]') from mytest;

# 结果:
["a", "d", "e"]

# 会删除other字段中数组下标为1的值,再根据新的结果,删除下标为2的值
select json_remove(@j, '$[1]','$[2]') from mytest;

# 结果:
["a", "d"] 

# 会删除other字段中数组下标为1的值,再根据新的结果,删除下标为1的值
select json_remove(@j, '$[1]','$[1]') from mytest;

# 结果:
["a", "e"] 

如何对JSON字段创建索引?

同 TEXT,BLOB 字段一样,JSON 字段不允许直接创建索引。

对文档中的元素进行查询,就需要用到 MySQL 5.7 引入的虚拟列及函数索引。

# 创建表及索引
create table t ( c1 json, c2 varchar(10) as (JSON_UNQUOTE(c1 -> "$.name")), index (c2) );

# 插入数据
insert into t (c1) values  ('{"id": 1, "name": "a"}'), ('{"id": 2, "name": "b"}'), ('{"id": 3, "name": "c"}'), ('{"id": 4, "name": "d"}');

 

 

 加索引查询结果分析:

explain select * from t where c2 = 'a';

explain select json_extract(c1,'$.id') from t where c1->'$.name' = 'a';

 以上可见,虚拟列和json类型的列结果分析是一样的。

 不加索引查询结果分析:

explain select * from t where c2 = 'a';

explain select json_extract(c1,'$.id') from t where c1->'$.name' = 'a';

 注意:在创建虚拟列时需指定  JSON_UNQUOTE,将 c1 -> "$.name" 的返回值转换为字符串。

使用JSON时的注意事项

  1. 再MySQL8.0.13之前,不允许对BLOB、TEXT、GEOMETRY、JSON字段设置默认值。从MySQL8.0.13开始,取消了这个限制。
  2. 不允许直接创建索引,可创建函数索引。
  3. JSON列的最大大小和LONGBLOB(LONGTEXT)一样,都是4G.
  4. 插入时,单个文档的大小受到max_allowed_packet的限制,该参数最大是1G.

小知识:

        max_allowed_packet:指mysql服务器端和客户端再一次传送数据包的过程当中最大允许的数据包大小。

作者:筱白爱学习!!

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

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

相关文章

FlowChartX/Diagramming for ActiveX 4.9.8 Crack

构建完美的图表 如果您的应用程序以 ActiveX 平台为目标,并且您需要实现图表功能,那么您所需要的只是 FlowChartX。它提供了创建、自定义和呈现流程图的所有功能。 ActiveX 图表库:分类图表 图 Diagramming for ActiveX该组件为您提供了一组…

浅谈C++函数重载

C相较于C语言来说,重载是一重大特性,让我们一起简单的回顾一下重载那些事 传送门函数重载是什么为什么有函数重载函数重载是如何实现的总结函数重载是什么 函数重载:是函数的一种特殊情况,C允许在同一作用域中声明几个功能相似的同名函数 这些同名函数的形参列表(参数个数or类…

day19_抽象类丶接口

由来 当我们声明一个几何图形类:圆、矩形、三角形类等,发现这些类都有共同特征:求面积、求周长、获取图形详细信息。那么这些共同特征应该抽取到一个公共父类中。但是这些方法在父类中又无法给出具体的实现,而是应该交给子类各自…

当遇到国外客户的问题,你解决不了的时候怎么办

对我来说,今年的这个春节假期有点长,差不多休了一个月。复工之后,截止目前做到了60万RMB的业绩,但是相较于往年,整体状态还是差了些。往年的春节,我都是随时待命的状态,整个春节天天坐于电脑前&…

JSP 和 JSTL

文章目录🍓摘要🍓一、JSP🍉1.1 JSP的基础语法🍫1.1.1 简介🍫1.1.2 依赖🍫1.1.3 注释🍫1.1.4 Scriptlet 脚本🍉1.2 JSP的指令标签🍫1.2.1 include 静态包含🍫1…

2023年数学建模美赛A题(A drought stricken plant communities)分析与编程

2023年数学建模美赛A题(A drought stricken plant communities)分析与编程 2023年数学建模美赛D题(Prioritizing the UN Sustainability Goals)分析与编程 特别提示: 1 本文介绍2023年美赛题目,进行深入分析…

台式计算机加固态硬盘,台式机添加固态硬盘教程_台式主机固态硬盘怎么安装-win7之家...

固态硬盘是用固态电子存储芯片阵列制成的硬盘,也是电脑中比较常见的内存硬件,有些用户在使用电脑时候,由于内存不足导致系统运行较卡的情况,往往会选择添加固态硬盘来解决,那么台式主机固态硬盘怎么安装呢?…

Ansible中的角色使用(ansible roles)

文章目录一、ansible 角色简介二、roles目录结构三、role存放的路径:配置文件ansible.cfg中定义四、创建目录结构五、playbook中使用rolesplaybook变量会覆盖roles中的定义变量六、控制任务执行顺序七、ansible—galaxy命令工具八、安装选择的角色1.从网上下载&…

2023.2.17-博客记录

1.斐波那契数列的复杂度 参考于:斐波那契数列时间复杂度 运用到了递归思想 那么,推导:时间复杂度 f(n) f(n-1) f(n-2) 每一层都包含一个加法操作 例如n 8时,T(n) 2^0 2^1 2^2 2^3 2^4 2^5 2^6 2^7-1 O(n) 2^7-1 2…

四六级真题长难句分析与应用

一、基本结构的长难句 基本结构的长难句主要考点:断开和简化 什么是长难句? 其实就是多件事连在了一块,这时候句子就变长、变难了 分析步骤: 第一件事就是要把长难句给断开,把多件事断开成一件一件的事情&#xff0…

ElementUI`resetFields()`方法避坑

使用ElementUI中的resetFields()方法有哪些注意点 场景一 场景一:当编辑弹出框和新增弹出框共用时,编辑数据后关闭编辑弹出框时调用this.$refs.form.resetFields()无法清空弹出框 问题代码: // 点击新增按钮handleAdd() {this.dialogVi…

《Qt6开发及实例》6-3 双缓冲机制

目录 一、原理与设计 1.1 原理 1.2 设计 二、绘图区的实现 2.1 鼠标移动事件 2.2 重绘函数&调整大小函数&清除屏幕 三、主窗口的实现 3.1 代码 一、原理与设计 1.1 原理 双缓冲就是在绘制控件时,将内容绘制在一个图片中,再将图片一次性…

全局状态管理插件 Vuex 介绍及使用

文章目录Vuex 是什么简介Vuex 如何存储数据Vuex 核心概念单向数据流StateGetterMutationActionModuleVuex 使用实例总结Vuex 是什么 简介 官方解释:Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以…

Linux环境下(CentOS 7)安装Java(JDK8)

Linux环境下(CentOS 7)安装Java(JDK8) 一、安装教程 1.1 首先,进入oracle官网下载jdk8的安装包,下载地址如下,这里以 jdk-8u121-linux-x64.tar.gz安装包为例。 http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-21…

2023美赛(MCM/ICM)数据汇总

2023美赛已经开始了十二个小时了,对于本次比赛,赛题 难度都不大。主要就是收集数据的问题 ,为了更好地帮助大家选题,我们将 我们今天已经收集到的数据进行汇总,分享。其中,首先是A、E题目都提及的天气数据&…

C语言学习_DAY_4_判断语句if_else和分支语句switch_case【C语言学习笔记】

高质量博主,点个关注不迷路🌸🌸🌸! 目录 1.案例引入 2.if判断语句的语法与注意事项 3.switch多分支语句的语法与注意事项 前言: 书接上回,我们已经学习了所有的数据类型、运算符,并且可以书写…

基于matlab/simulink的风光柴储微电网仿真建模

模型是基于之前的风光储系统上增加一部分柴油发电机系统,后面文章我会单独介绍柴油机这一部分,主要应用在船舶电力系统,一般小型电网黑启动也会用到。 风光柴储微电网发电系统是一种小型发电系统,同时具备并网运行和孤岛运行的功能…

气敏电阻的原理,结构,分类及应用场景总结

🏡《总目录》 目录 1,概述2,结构3,工作原理4,分类4.1,加热方式分类4.2,材料分类4.3,氧化还原分类5,应用场景6,总结1,概述 气敏电阻是指电阻值随着环境中某种气体的浓度变化而变化的电阻,本文对其工作原理,结构,分类和应用场景进行总结。 2,结构 气敏电阻由防爆…

Leetcode(每日一题)——1237. 找出给定方程的正整数解

摘要 1237. 找出给定方程的正整数解 一、暴力求解 根据题目给出的x和y的取值范围,枚举所有的 x,y数对,保存满足f(x,y)z的数对,最后返回结果。 /*** description 使用的暴力法 直接遍历符合的就添加到结果中* param: customfunction* param…

能不能做好性能测试,要看你有没有性能测试思维

获取性能需求 01、用户数信息 1、调查系统当前和未来使用的用户数 系统用户数 本系统目前注册的用户数,注册用户数并不代表他会每天并且无时无刻的使用着。 在线用户数 同时在线对系统进行操作的用户数量(相当于混合场景) 并发用户数 …