10分钟上手:MySQL8的Json格式字段使用总结干货

一、关于效率和适用范围

尽管官方承诺Json格式字段采用了空间换时间的策略,比Text类型来存储Json有大幅度的效率提升。但是Json格式的处理过程仍然效率不及传统关系表,所以什么时候用Json格式字段尤为重要。
只有我们确定系统已经能精确定位到某一行,比如用主键、创建时间范围等,这时候我们的数据集合比较小,那么我们就可以放心大胆的用Json格式字段进行进一步数据处理,而且Json中所存储的信息一定不是检索时必要的筛选信息和统计时需要计算的关键数据,不要妄想在百万行Json字段里对某一个Json属性进行搜索、聚合,这属于纯粹找虐。
比如说我们读个字典,以往要拆成两个表,现在一个表就可以解决;或者说ERP系统里我们可以把万年不查的子表、孙表都放在一个Json字段里,这样用单表即可解决复杂结构化数据存储的问题。
举个每个人都知道具体场景的例子:CMS系统有内容页,传统方式解决扩展字段大多都用键值对表(也就是窄表)来解决问题,但事实上键值对表的查询非常慢,所有的数据都以TEXT的方式存储(因为要照顾到富文本自定义字段),因此非常难以查询,当用户已经点击进入内容页的时候我们已知具体是内容表的哪一行,此时直接将JSON数据返回给前端的效率要完全优于遍历键值对表,而且还能对Json的某个属性加索引,也可以对整个Json串加全文索引,这样对某个栏目下的有限内容的同一个字段就很容易进行统计。
再举一个经常遇到的例子:业务总是在变化,字段总要变,需要兼顾灵活性和效率,不得不用Json字段来处理数据。

二、实测前的准备工作

建表就不用说了,主流建表工具都支持建立Json列。
插入和更新数据也不用说了,就当是操作字符串即可,只有一个局部更新可能需要用到,后面会讲到。
我们这里主要讲查询。
假设我们有这么一个表my_table,后面的例子都用它来举例:

CREATE TABLE `my_table`  (`id` bigint NOT NULL AUTO_INCREMENT,`code` varchar(255) NULL,`name` varchar(255) NULL,`attrs` json NULL,`create_time` datetime NULL,`creator` bigint NULL,`last_modify` datetime NULL,`modifier` bigint NULL,`time_stamp` datetime NULL,`deleted` tinyint NULL,PRIMARY KEY (`id`)
);

然后我们准备好要测试的数据

INSERT INTO `my_table` (`id`, `code`, `name`, `attrs`, `create_time`, `creator`, `last_modify`, `modifier`, `time_stamp`, `deleted`) 
VALUES (1, 'menu', '菜单', '[{\"code\": \"menu1\", \"name\": \"菜单1\"}, {\"code\": \"menu2\", \"name\": \"菜单2\"}]', NULL, NULL, NULL, NULL, NULL, NULL);
INSERT INTO `my_table` (`id`, `code`, `name`, `attrs`, `create_time`, `creator`, `last_modify`, `modifier`, `time_stamp`, `deleted`) 
VALUES (2, 'sysConfig', '系统设置', '{\"sysName\": \"某综合管理系统\", \"wxAppId\": \"wx1234567\"}', NULL, NULL, NULL, NULL, NULL, NULL);
INSERT INTO `my_table` (`id`, `code`, `name`, `attrs`, `create_time`, `creator`, `last_modify`, `modifier`, `time_stamp`, `deleted`) 
VALUES (3, 'site', '站点设定', '[{\"code\": \"a.myweb.com\", \"extra\": {\"owner\": \"rantUser1\"}, \"visited\": 200}, {\"code\": \"b.myweb.com\", \"extra\": {\"owner\": \"rantUser1\"}, \"visited\": 300}, {\"code\": \"www.example.com\", \"extra\": {\"owner\": \"rantUser2\"}, \"visited\": 157}, {\"code\": \"b2c.example.com\", \"extra\": {\"owner\": \"rantUser2\"}, \"visited\": 775}]', NULL, NULL, NULL, NULL, NULL, NULL);

都导入之后,数据大概是这样子的:
在这里插入图片描述

各种查询方法

晦涩难懂的官方原版Manual就不给大家重复了,直接上干货:

Json转表

Json转表是第一个要解决的问题,只要变成我们熟悉的表,很多传统MySQL的关联表、集合查询之类的操作都能用上了。

SELECT b.* FROM my_table AS a
JOIN JSON_TABLE(	a.attrs, '$[*]' COLUMNS (`code` VARCHAR(20) PATH '$.code',`name` VARCHAR(20) PATH '$.name') ) AS b 
WHERE a.code = 'menu'

解析直接看图吧:
在这里插入图片描述
查询结果:
在这里插入图片描述

取属性

我们很多时候面向对象开发需要用到ORM框架,但每次都要当做String来用FastJson、Gson之类的框架来解析实在是太麻烦。例如我们有MyBatis这样的框架,直接在SQL语句里把Json的字段都附加上,上层所有的应用框架全都可以认,岂不是一劳永逸。

SELECT *,attrs->>'$.sysName' sys_name,attrs->>'$.wxAppId' wx_app_id
from my_table
where code='sysConfig'

在这里插入图片描述
查询结果如下:
在这里插入图片描述

维度抽取

这个是针对数组的,echarts之类的框架会需要用到,这里不做赘述

select attrs->>'$[*].code' code_list,attrs->>'$[*].name' name_list
from my_table where code='menu'

查询结果:
在这里插入图片描述
还可以针对多行一起获得维度抽取的结果,如果碰到JSON不是数组的,它也不会报错,只是返回一个null,非常人性化

select id,code,name,attrs->>'$[*].code' sub_code
from my_table

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

聚合操作

这次我们把已经设定的站点都取出来,根据所有者的不同,把他们网站的访问量都统计出来

SELECTb.owner,sum(b.visited) visited
FROM my_table AS a
JOIN JSON_TABLE(	a.attrs, '$[*]' COLUMNS (`owner` VARCHAR(20) PATH '$.extra.owner',`visited` BIGINT PATH '$.visited') ) AS b 
WHEREa.code = 'site'
GROUP BY owner

在这里插入图片描述

局部更新

有时候我们并不想把整个Json都更新了,只想更新其中一个值(比如多人同时更新一个Json时,各个内存中完整的Json副本都不一样,如果贸然全量更新,就会互相覆盖)

UPDATE my_table
SET attrs = JSON_SET(attrs, '$.sysName', '某网站管理系统')
WHERE code='sysConfig';

通过上面这个方式就可以局部更新sysName这个key对应的值,MySql内部做了优化,如果值是相同的,影响行数则返回0,它并不会无脑覆盖。

总结

至于其他的用法,对于应用层面开发来说没什么太大用途,主要原因是大批量的Json加工压力还是在前端和后台,所以数据库层面只需要关注读取方式、效率以及和ORM框架的兼容性即可。Json字段对于低代码开发、元数据、动态表单之类的应用是很有帮助的,特别是对有些动态数据结构的加工来说,省了很多精力。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【完全背包求方案数问题】AcWing1023.买书(赋练习题目)

【题目链接】活动 - AcWing 输入样例1&#xff1a; 20输出样例1&#xff1a; 2输入样例2&#xff1a; 15输出样例2&#xff1a; 0输入样例3&#xff1a; 0输出样例3&#xff1a; 1 【代码】 //1023.买书——完全背包问题#include<bits/stdc.h>using namespace st…

一起学习HarmonyOS应用开发——基础篇(4)

前言&#xff0c;上一篇说了应用工程的目录结构&#xff0c;今天不讲ArkTS语言&#xff08;HarmonyOS优先的主力应用开发语言&#xff09;的语法&#xff0c;先说一下组件的事情。比如基础组件、容器组件、媒体组件、绘制组件、画布组件。今天就简单的学习一下常用的组件怎么玩…

【SpringCloud】Nacos 配置管理

目 录 一.统一配置管理1. 在 nacos 中添加配置文件2. 从微服务拉取配置 二.配置热更新1. 方式一2. 方式二 三.配置共享1. 添加一个环境共享配置2. 在 user-service 中读取共享配置3. 运行两个 UserApplication&#xff0c;使用不同的 profile4. 配置共享的优先级5. 多服务共享配…

提高网站安全性,漏洞扫描能带来什么帮助

随着互联网的蓬勃发展&#xff0c;网站已经成为人们获取信息、交流思想、开展业务的重要平台。然而&#xff0c;与之伴随的是日益严重的网络安全问题&#xff0c;包括恶意攻击、数据泄露、隐私侵犯等。 为了保障网站的安全性&#xff0c;提前做好网站的安全检测非常有必要&…

C语言程序与设计——工程项目开发

之前我们已经了解了C语言的基础知识部分&#xff0c;掌握这些之后&#xff0c;基本就可以开发一些小程序了。在开发时&#xff0c;就会出现合作的情况&#xff0c;C语言是如何协作开发的呢&#xff0c;将在这一篇文章进行演示。 工程项目开发 在开发过程中&#xff0c;你接到…

K8s学习十(高级调度)

高级调度 CronJob计划任务 在 k8s 中周期性运行计划任务&#xff0c;与 linux 中的 crontab 相同注意点&#xff1a;CronJob 执行的时间是 controller-manager 的时间&#xff0c;所以一定要确保 controller-manager 时间是准确的cron表达式如下&#xff1a; 配置如下&#x…

为什么企业推广需要品牌故事?媒介盒子分享

从时代来看&#xff0c;我们正处“信息超载的商业时代”&#xff0c;品牌传播面临着“产品同质化”和“信息超载化”的困境。近日小米SU7的出圈除了汽车本身的话题度外&#xff0c;离不开小米的品牌故事、创始人雷军的话题等等。今天媒介盒子就来和大家聊聊&#xff1a;为什么企…

医院智慧手术麻醉系统管理源码 C# .net有演示

医院智慧手术麻醉系统管理源码 C# .net有演示 手术麻醉管理系统(DORIS)是应用于医院手术室、麻醉科室的计算机软件系统。该系统针对整个围术期&#xff0c;对病人进行全程跟踪与信息管理&#xff0c;自动集成病人HIS、LIS、RIS、PACS信息&#xff0c;采集监护等设备数据&#x…

LowCodeEngine基础教程

一、技术介绍 1、应用场景 LowCodeEngine支持一下四种通用场景&#xff1a;中后台页面、移动端页面、流程、可视化报表。 2、低代码的特点 3、低代码在阿里巴巴实践 4、开发痛点 中后台页面中&#xff0c;对于页面的视觉冲击、视觉炫酷要求并不是很敏感&#xff0c;更多的是…

Java | Leetcode Java题解之第13题罗马数字转整数

题目&#xff1a; 题解&#xff1a; class Solution {Map<Character, Integer> symbolValues new HashMap<Character, Integer>() {{put(I, 1);put(V, 5);put(X, 10);put(L, 50);put(C, 100);put(D, 500);put(M, 1000);}};public int romanToInt(String s) {int …

vue前端项目到后端执行逻辑——自己改的话要怎么改

文章目录 vue前端项目到后端流程——自己改的话要怎么改 vue前端项目到后端流程——自己改的话要怎么改

下一代分层存储方案:CXL SSD

近日&#xff0c;在Memcon 2024大会上&#xff0c;三星推出了一款名为CXL Memory Module-Hybrid for Tiered Memory&#xff08;CMM-H TM&#xff09;&#xff0c;这款扩展卡配备了高速DRAM和NAND闪存&#xff0c;允许CPU和加速器远程访问额外的RAM和闪存资源。 那么&#xff0…