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

news2024/11/24 12:27:17

一、关于效率和适用范围

尽管官方承诺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

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

聚合操作

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

SELECT
	b.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 
WHERE
	a.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.coloradmin.cn/o/1580846.html

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

相关文章

Python3 replace()函数使用详解:字符串的艺术转换

博主猫头虎的技术世界 🌟 欢迎来到猫头虎的博客 — 探索技术的无限可能! 专栏链接: 🔗 精选专栏: 《面试题大全》 — 面试准备的宝典!《IDEA开发秘籍》 — 提升你的IDEA技能!《100天精通鸿蒙》 …

7-13那就别担心了

题目 下图转自“英式没品笑话百科”的新浪微博 —— 所以无论有没有遇到难题,其实都不用担心。 博主将这种逻辑推演称为“逻辑自洽”,即从某个命题出发的所有推理路径都会将结论引导到同一个最终命题(开玩笑的,千万别以为这是真正…

C语言面试题之环路检测

环路检测 实例要求 1、给定一个链表,如果它是有环链表,实现一个算法返回环路的开头节点;2、若环不存在,请返回NULL;3、如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在…

【C语言】简单介绍进制和操作符

🌈个人主页:是店小二呀 🌈C语言笔记专栏:C语言笔记 🌈C笔记专栏: C笔记 🌈喜欢的诗句:无人扶我青云志 我自踏雪至山巅 本文简要介绍进制和操作符,愿能为您提供帮助!文章…

FD-350 水分含量传感器 485输出 墒情监测

产品概述 FD-350 水分含量传感器由电源模块、变送模块、漂零及温度补偿模块、数据处理模块等组成。采用FDR频域法,可以实时准确测定各种土壤不同剖面的水分含量。传感器内置信号采样及放大、零点漂移及温度补偿功能,用户接口简洁、方便。外型小巧轻便&a…

负荷预测 | Matlab基于TCN-GRU-Attention单输入单输出时间序列多步预测

目录 效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab基于TCN-GRU-Attention单输入单输出时间序列多步预测; 2.单变量时间序列数据集,采用前12个时刻预测未来96个时刻的数据; 3.excel数据方便替换,运行环境matlab20…

盛最多水的容器(双指针)

11. 盛最多水的容器 - 力扣(LeetCode) 题目描述 给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。 …

快速安装/升级/卸载Ascend配套软件包

一、参考资料 配套MindSpore 昇腾软件安装指引(23.0.RC3) 快速安装CANN 二、安装Ascend配套软件包 1. Ascend配套软件包简介 Ascend配套软件包,包括:固件、驱动和CANN(Compute Architecture for Neural Networks&…

uniapp 表单使用Uview校验 包括城市选择器

<view><!-- 注意&#xff0c;如果需要兼容微信小程序&#xff0c;最好通过setRules方法设置rules规则 --><u--form labelPosition"left" :model"model1" :rules"rules" ref"uForm" labelWidth"174"><u…

【鸿蒙开发】系统组件Row

Row组件 Row沿水平方向布局容器 接口&#xff1a; Row(value?:{space?: number | string }) 参数&#xff1a; 参数名 参数类型 必填 参数描述 space string | number 否 横向布局元素间距。 从API version 9开始&#xff0c;space为负数或者justifyContent设置为…

electron打包Vue前端

Electron-Forge 打包Vue项目 效果&#xff1a;electronforge可将前端静态页面打包成.exe、.deb和.rpm等&#xff0c;能适配各种平台 示例&#xff1a;Windows环境下将前端 Vue 项目打包成exe文件 打包后的 exe 文件 运行 exe 文件 一、项目准备 开源项目 RouYi 下载 本…

百度获评CCIA数据安全和个人信息保护社会责任评价“三星”示范单位

日前&#xff0c;由中国网络安全产业联盟&#xff08;CCIA&#xff09;数据安全工作委员会主办的“促进数据安全合规流通使用”专题研讨会&#xff08;CCIA数安委年度会议&#xff09;成功举办。与会介绍了数据安全和个人信息保护社会责任试点评价工作的开展情况&#xff0c;并…

极狐GitLab 如何在 helm 中恢复数据

本文作者&#xff1a;徐晓伟 GitLab 是一个全球知名的一体化 DevOps 平台&#xff0c;很多人都通过私有化部署 GitLab 来进行源代码托管。极狐GitLab 是 GitLab 在中国的发行版&#xff0c;专门为中国程序员服务。可以一键式部署极狐GitLab。 本文主要讲述了如何在极狐GitLab …

Ubuntu20.04安装和编译运行lidar_align来联合标定lidar与imu的外参

硬件&#xff1a;树霉派4b 1、下载并安装lidar_align mkdir -p lidar_align/src cd lidar_align/src git clone https://github.com/ethz-asl/lidar_align.git 将 lidar_align/src/lidar_align/NLOPTConfig.cmake 文件移动到 lidar_align/src/ 下(与lidar_align同级) NLOP…

关于Linux内核code段被改写的原因分析

本文基于Linux-4.19.125&#xff0c; ARM V7&#xff0c;dual core。 1 code 段 Linux的code段&#xff08;或者说text段&#xff09;自_stext开始&#xff0c;到_etext结束&#xff0c;这段内容一般情况下是只读的&#xff0c;在理论上来说&#xff0c;这段数据在设备上应该…

Java设计模式—组合模式(Composite Pattern)

组合模式&#xff08;Composite&#xff09;&#xff0c;将对象组合成树形结构以表示部分-整体的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。 public class CompositeTest {public static void main(String[] args){// 创建主菜单MenuComponent mainMen…

访问网站时你的电脑都做了什么

电脑在访问百度时 首先在本地hosts文件里面查看本地有无域名对应的IP地址&#xff0c;若有就直接返回。若无&#xff0c;则本地DNS服务器当DNS的客户&#xff0c;向其它根域服务器发送报文查询IP地址&#xff0c;简单来说就是帮助主机查找IP&#xff0c;所以递归查询就在客户端…

纯C语言手搓GPT-2,前OpenAI、特斯拉高管新项目火了

ChatGPT狂飙160天&#xff0c;世界已经不是之前的样子。 新建了免费的人工智能中文站https://ai.weoknow.com 新建了收费的人工智能中文站https://ai.hzytsoft.cn/ 更多资源欢迎关注 「Real men program in C.」 众所周知&#xff0c;大语言模型还在快速发展&#xff0c;应该有…

云岚到家项目

一.项目介绍 云岚到家项目是一个家政服务o2o平台&#xff0c;互联网家政是继打车、外卖后的又一个风口&#xff0c;创业者众多&#xff0c;比如&#xff1a;58到家&#xff0c;天鹅到家等&#xff0c;o2o&#xff08;Online To Offline&#xff09;是将线下商务的机会与互联网…

el-table实现表格内部横向拖拽效果

2024.4.2今天我学习了如何对el-table表格组件实现内部横向拖拽的效果&#xff0c;效果&#xff1a; 代码如下&#xff1a; 一、创建utils/底下文件 const crosswise_drag_table function (Vue){// 全局添加table左右拖动效果的指令Vue.directive(tableMove, {bind: function…