点击上方"蓝字"

关注我们,享更多干货!

现在很多应用环境中都能看到JSON灵活的影子。各阶段数据层次的递归层次,能很好的分辨。一直对MySQL的JSON很期待的,最近才有时间研究一下。

JSON了解

JSON就是一串字符串,只不过元素会使用特定的符号标注。比如:

  • {} 双括号表示对象

  • [] 中括号表示数组

  • “” 双引号内是属性或值

  • : 冒号表示后者是前者的值

关系型数据库实现JSON难度在于,关系型数据库需要定义数据库和表结构。为了应对这一点,从MySQL 5.7开始,MySQL支持了JavaScript对象表示(JavaScriptObject Notation,JSON) 数据类型。之前,这类数据不是单独的数据类型,会被存储为字符串。新的JSON数据类型提供了自动验证的JSON文档以及优化的存储格式。

MySQL里JSON文档以二进制格式存储,它提供以下功能:

  • 自动验证存储在JSON列中的JSON文档。无效文档产生错误。

  • 优化的存储格式。存储在JSON列中的JSON文档被转换为允许快速读取访问文档元素的内部格式。二进制格式存储的JSON值。

  • 对文档元素的快速读取访问。当服务器再次读取JSON文档时,不需要重新解析文本获取该值。通过键或数组索引直接查找子对象或嵌套值,而不需要读取文档中的所有值。

  • 存储JSON文档所需的空间大致与LONGBLOB或LONGTEXT相同。

  • 存储在JSON列中的任何JSON文档的大小都仅限于max_allowed_packet系统变量的值。

  • MySQL 8.0.13之前,JSON列不能有非NULL的默认值。

JSON操作

数据保存到MySQL,操作方面都提供哪些支持?目前MySQL 8.0版本的的JSON总共支持32个普通函数和2个空间函数:

1. 索引:

  • JSON列,像其他二进制类型的列一样,不直接索引;相反,您可以在生成的列上创建索引,从JSON列中提取标量值。有关详细示例,请参见为生成的列建立索引以提供JSON列索引。

  • MySQL优化器还会在匹配JSON表达式的虚拟列上寻找兼容的索引。

  • 在MySQL 8.0.17及以后版本中,InnoDB存储引擎支持JSON数组上的多值索引。看到多值索引。

  • MySQL NDB Cluster 8.0支持JSON列和MySQL JSON函数,包括在从JSON列生成的列上创建索引,作为无法索引JSON列的解决方案。每个NDB表最多支持3个JSON列。

2.JSON值的比较和排序:

  • JSON值可以使用=、<、<=、>、>=、<>、!=和<=>操作符进行比较。

  • JSON值不支持以下比较操作符和函数:
    BETWEEN
    IN()
    GREATEST()
    LEAST()

  • 对于列出的比较操作符和函数,一种变通方法是将JSON值转换为本地MySQL数值或字符串数据类型,以便它们具有一致的非JSON标量类型。就是说转换成需要的MySQL字段继续换算,也算是一种折中方案。

  • JSON值的比较分为两个级别。第一级比较基于比较值的JSON类型。如果类型不同,则仅由哪个类型优先级更高来决定比较结果。如果两个值具有相同的JSON类型,则使用特定类型的规则进行第二级比较。
    BLOB > BIT > OPAQUE > DATETIME > TIME > DATE > BOOLEAN > ARRAY > OBJECT > STRING > INTEGER, DOUBLE > NULL。

3.JSON和非JSON值之间的转换:

MySQL在JSON值和其他类型值之间转换时遵循的规则:

CAST(other type AS JSON)

结果为JSON类型的NULL值。

mysql>SET @j5 = '{"id":123, "name":"kevin","age":20, "time":"2021-06-01 01:00:00"}';
Query OK, 0 rows affected (0.00 sec)mysql>SELECT CAST(JSON_EXTRACT(@j5, '$.age') AS UNSIGNED);+----------------------------------------------+
| CAST(JSON_EXTRACT(@j5, '$.age') AS UNSIGNED) |
+----------------------------------------------+
|                                           20 |
+----------------------------------------------+
1 row in set (0.00 sec)

4.JSON值聚合:

对于JSON值的聚合,NULL值和其他数据类型一样被忽略。除MIN()、MAX()和GROUP_CONCAT()外,非NULL值被转换为数字类型并聚合。对于数字标量的JSON值,(取决于值)可能会出现截断和精度损失。

JSON使用索引方式:

MySQL JSON列上无法创建索引,是通过从JSON列中提取标量值,创建索引。这样能更有效的结合MySQL优势。

  • MySQL优化器会在匹配JSON表达式的虚拟列上寻找兼容的索引。

  • 在MySQL 8.0.17及以后版本中,InnoDB存储引擎支持JSON数组上的多值索引

  • MySQL NDB Cluster 8.0支持JSON列和MySQL JSON函数,包括在从JSON列生成的列上创建索引,作为无法索引JSON列的解决方案。每个NDB表最多支持3个JSON列。

1.虚拟列索引:

col_name data_type [GENERATED ALWAYS] AS (expr)[VIRTUAL | STORED] [NOT NULL | NULL][UNIQUE [KEY]] [[PRIMARY] KEY][COMMENT 'string']

VIRTUAL或STORED关键字表示列值是如何存储的,这对列的使用影响非常大:

  • VIRTUAL:不存储列值,但在读取行时,在任何【BEFORE触发器】之后立即计算列值。虚拟列不占用存储空间,但暂居内存。目前官方里没有设置这个极限。

  • STORED:当插入或更新行时,将计算并存储列值。存储的列需要存储空间,并且可以建立索引。

  • 如果没有指定关键字,则默认为VIRTUAL。

mysql> DROP TABLE IF EXISTS `jemp`;mysql> CREATE TABLE  `jemp` (id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,c JSON,d JSON,        g INT GENERATED ALWAYS AS  (c->"$.id") STORED,INDEX i (g));
Query OK, 0 rows affected (0.02 sec)mysql> INSERT INTO jemp (c,d) VALUES
('{"id": "1", "name": "Fred"}' , '{"user":"Fred",   "user_id":1, "zipcode":"[14471,14531]"}'),
('{"id": "2", "name": "Wilma"}', '{"user":"Wilma",  "user_id":2, "zipcode":[24472,24532]}'  ),
('{"id": "3", "name": "Jack"}' , '{"user":"Jack", "user_id":3, "zipcode":[34473,34533]}'    ),
('{"id": "4", "name": "Betty"}', '{"user":"Betty",  "user_id":4, "zipcode":[44474,44534]}'  );Query OK, 4 rows affected (0.02 sec)
Records: 4  Duplicates: 0  Warnings: 0mysql> EXPLAIN SELECT c->>"$.name" AS name  FROM jemp WHERE g > 2\G;
*************************** 1. row ***************************id: 1select_type: SIMPLEtable: jemppartitions: NULLtype: range
possible_keys: ikey: ikey_len: 5ref: NULLrows: 2filtered: 100.00Extra: Using where
1 row in set, 1 warning (0.00 sec)
ERROR:
No query specifiedmysql> SHOW WARNINGS\G*************************** 1. row ***************************Level: NoteCode: 1003
Message: /* select#1 */ select json_unquote(json_extract(`db1`.`jemp`.`c`,'$.name')) AS `name` from `db1`.`jemp` where (`db1`.`jemp`.`g` > 2)
1 row in set (0.00 sec)

2.使用多值索引

直接接口:MEMBER OF(),JSON_CONTAINS(),JSON_OVERLAPS()

mysql> ALTER TABLE jemp ADD INDEX zips( (CAST(d->'$.zipcode' AS UNSIGNED ARRAY)) );#MEMBER  OF
mysql> EXPLAIN  SELECT * FROM jemp    WHERE  24472 MEMBER  OF(d->'$.zipcode')\G*************************** 1. row ***************************id: 1select_type: SIMPLEtable: jemppartitions: NULLtype: ref
possible_keys: zipskey: zipskey_len: 9          ref: constrows: 1filtered: 100.00        Extra: Using where
1 row in set, 1 warning (0.00 sec)
#JSON_CONTAINS
mysql> EXPLAIN SELECT * FROM jemp   WHERE JSON_CONTAINS(d->'$.zipcode', CAST('[14471,14531]' AS JSON))\G;
*************************** 1. row ***************************id: 1select_type: SIMPLEtable: jemppartitions: NULLtype: range
possible_keys: zipskey: zipskey_len: 9ref: NULLrows: 2filtered: 100.00Extra: Using where
1 row in set, 1 warning (0.00 sec)#JSON_OVERLAPS
mysql> EXPLAIN SELECT * FROM jemp   WHERE JSON_OVERLAPS(d->'$.zipcode', CAST('[44474,94582]' AS JSON))\G;
*************************** 1. row ***************************id: 1select_type: SIMPLEtable: jemppartitions: NULLtype: range
possible_keys: zipskey: zipskey_len: 9ref: NULLrows: 2filtered: 100.00Extra: Using where
1 row in set, 1 warning (0.00 sec)

从上面例子里,数据的查询还是基于MySQL B+tree上,JSON只是一种数据保存的机制。通过对虚拟列方式,提供快速的访问,非常好的解决了JSON支持问题。

总结

  • MySQL里JSON的结合非常实用,虚拟列索引解决了查询的性能问题。

  • JSON大小确实个硬性问题,谨慎使用(空间大致与LONGBLOB或LONGTEXT相同,文档的大小都仅限于max_allowed_packet系统变量的值)。

  • 实际场景中,只能选择适中的JSON长度,可以考虑配合大页使用。

关于作者

崔虎龙,云和恩墨MySQL技术顾问,长期服务于金融、游戏、物流等行业的数据中心,设计数据存储架构,并熟悉数据中心运营管理的流程及规范,自动化运维等。擅长MySQL、Redis、MongoDB数据库高可用设计和运维故障处理、备份恢复、升级迁移、性能优化。自学通过了MySQL OCP 5.6和MySQL OCP 5.7认证。2年多开发经验,10年数据库运维工作经验,其中专职做MySQL工作8年;曾经担任过项目经理、数据库经理、数据仓库架构师、MySQL技术专家、DBA等职务;涉及行业:金融(银行、理财)、物流、游戏、医疗、重工业等。

墨天轮原文链接:https://www.modb.pro/db/68425(复制到浏览器或者点击“阅读原文”立即查看)

END

推荐阅读:267页!2020年度数据库技术年刊

推荐下载:2020数据技术嘉年华PPT下载

2020数据技术嘉年华近50个PPT下载、视频回放已上传墨天轮平台,可在“数据和云”公众号回复关键词“2020DTC”获得!

由ACDU(中国DBA联盟)和墨天轮联合出品的全新视频节目「数据三分钟」已发布多期,快速了解数据行业动态,快关注我们的视频号看看吧!↓↓↓

点击下图查看更多 ↓

云和恩墨大讲堂 | 一个分享交流的地方

长按,识别二维码,加入万人交流社群

请备注:云和恩墨大讲堂

  点个“在看”

你的喜欢会被看到❤

MySQL 8.0中的JSON增强相关推荐

  1. 审计MySQL 8.0中的分类数据查询

    面临的挑战 通常,涉及到敏感信息时用户需要使用审计日志.不仅仅是在表上运行Select,还包括访问表中的特定单元格.通常,这类数据将包含一个分类级别作为行的一部分,定义如何处理.审计等策略. 诸如此类 ...

  2. 在.NET2.0中解析Json和Xml

    在.NET2.0中解析Json和Xml 在.NET解析json有很多方法,这里介绍最简单也用的最多的一种. 一.添加引用 解析Json,先下载开源控件 Newtonsoft.Json.dll 下载地址 ...

  3. 演讲实录:MySQL 8.0 中的复制技术

    在近期的第七届数据技术嘉年华上,甲骨文MySQL研发工程师宋利兵做了"MySQL-8.0中的复制技术"为主题的演讲,介绍了MySQL-8.0中异步复制和Group Replicat ...

  4. mysql 8.0空间索引_牛逼!MySQL 8.0 中的索引可以隐藏了…

    MySQL 8.0 虽然发布很久了,但可能大家都停留在 5.7.x,甚至更老,其实 MySQL 8.0 新增了许多重磅新特性,比如栈长今天要介绍的 "隐藏索引" 或者 " ...

  5. MySQL 8.0 可以操作 JSON 了,牛!

    作者 | 旺财不哭 来源 | https://www.jianshu.com/p/d4b012769a3b 经过漫长的测试,即将整体迁移至Mysql8.0; Mysql8.0 对于Json操作新增/优 ...

  6. MySQL里面json_MySQL中的JSON

    MySQL 5.7.7开始,支持了JSON类型.CREATE TABLE IF NOT EXISTS `spss`.`variable` ( `name` VARCHAR(512) NOT NULL, ...

  7. mysql8审计_审计对存储在MySQL 8.0中的分类数据的更改

    作者:Mike Frank  译:徐轶韬 面临的挑战 使用敏感信息时您需要拥有审计日志.通常,此类数据将包含一个分类级别作为行的一部分,定义如何处理.审计等策略.在之前的博客中,我讨论了如何审计分类数 ...

  8. MySQL 8.0 可以操作 JSON 了!!

    点击上方"逆锋起笔",选择"加为星标" 第一时间获取技术干货! 经过漫长的测试,即将整体迁移至Mysql8.0; Mysql8.0 对于Json操作新增/优化了 ...

  9. mysql workbench修改密码_在MySQL Workbench8.0中,忘记MySQL root密码的情况下修改密码...

    适用:如果你已经安装好MySQL,但因为忘记root密码且不想重新下载而无法建立连接,那么本文可能对你有用 前提:已经在环境变量中配置好mysql路径 步骤: Step1.准备配置文件 (1)查看根目 ...

最新文章

  1. Confluence5.1 最新版的安装破解汉化
  2. 【 MATLAB 】使用 residuez 函数求 z 反变换的几个案例分析
  3. Integer装箱和拆箱 以及扔玻璃球的题目
  4. [转载]项目风险管理七种武器-多情环
  5. r java_如何在R中使用JAVA写的程序包?
  6. bzoj5108 数据_成都day3t3
  7. MySQL 高级 —— 深入理解 InnoDB 与 MyISAM
  8. easypr4android,EasyPR的基本使用
  9. 深入了解DSP和ARM的关系(相同与区别)
  10. 【Firefox设置百度搜索引擎】
  11. 钉钉机器人告警快速实现
  12. 微软借云重振中国市场希望渺茫
  13. 局部边缘保留滤波器LEP算法原理及matlab代码实现
  14. 游戏界的“扛把子”,“3D 游戏之父”, 约翰•卡马克的传奇人生
  15. 低能耗配电开关 USB过流保护芯片USB限流保护SY6280
  16. Python编程基础与应用(陈波著)微实践
  17. --如何用PhotoShop制作真人头像表情包--
  18. MAC-关于VMware虚拟机键盘鼠标失灵解决
  19. [MySQL数据库]-基础多表练习题---员工工资
  20. 动画包bootanimation的制作及内置

热门文章

  1. eclipse theia_Eclipse的Theia发布,缺少KubeCon,还有更多行业趋势
  2. raspberry pi3_Raspberry Pi 3,Linux Mint安全漏洞,针对Zika病毒的Google数据处理等
  3. perl 序列化_对Perl的热爱团结了多元化的社区
  4. (43)前端工程化总结
  5. CSS 设置列表格式
  6. python center函数_数据类型和数据结构(三):字符串(4) 字符串内置函数(1)
  7. ROS笔记(28) Setup Assistant
  8. history 改成 模式_前端路由三种模式
  9. bapi sap 创建物料_DEMO: MIRO 根据物料创建贷项凭证BAPI_INCOMINGINVOICE_CREATE
  10. dw2019连接mysql数据库_Dreamweaver 8.0连接Mysql数据库全攻略