最佳实践 · 如何高效索引MySQL JSON字段

news2024/11/13 9:15:46

概述

从MySQL 5.7.8版本开始,MySQL引入了对JSON字段的支持,这为处理半结构化数据提供了极大的灵活性。然而,MySQL原生并不支持直接对JSON对象中的字段进行索引。本文将介绍如何利用MySQL 5.7中的虚拟字段功能,对JSON字段中的数据进行高效索引,以提高查询性能。

请在此添加图片描述

假设我们有一个记录用户游戏数据的JSON对象,我们希望能够快速检索游戏玩家的相关信息。

{
    "user_id": 101,
    "username": "Alice",
    "games": {
        "Chess": {
            "rating": 1500,
            "wins": 30,
            "losses": 5
        },
        "Poker": {
            "games_played": 100,
            "win_percentage": 60
        },
        "Tetris": {
            "high_score": 85000
        }
    }
}

表的基本结构

首先,创建一个包含JSON字段的表:

CREATE TABLE `user_games` (
    `user_id` INT UNSIGNED NOT NULL,
    `user_data` JSON NOT NULL,
    PRIMARY KEY (`user_id`)
);

在上面的表结构中,我们无法直接对JSON字段中的键进行索引。接下来,我们将演示如何使用虚拟字段对JSON字段进行索引。

增加虚拟字段

虚拟列语法如下

<type> [ GENERATED ALWAYS ] AS ( <expression> ) [ VIRTUAL|STORED ]
[ UNIQUE [KEY] ] [ [PRIMARY] KEY ] [ NOT NULL ] [ COMMENT <text> ]

在MySQL 5.7中,支持两种类型的生成列(Generated Column):虚拟生成列(Virtual Generated Column)和存储生成列(Stored Generated Column)。Virtual Column是默认选项,它只在数据字典中保存字段定义,而不将字段数据持久化到磁盘上。对于大多数应用场景,Virtual Column已足够使用,因为它节省了磁盘空间并且查询性能也很高。

虚拟生成列(Virtual Generated Column)

  • 定义:虚拟生成列是一个只在数据字典中定义的列,它不会实际存储数据,而是在每次查询时动态计算。
  • 优点
    • 节省磁盘空间:由于数据不被存储在磁盘上,仅在查询时计算,因此不会增加表的大小。
    • 适用于不常用的计算字段:对于计算频率较低的字段,使用虚拟生成列可以减少对存储空间的需求。
  • 缺点
    • 查询性能:每次查询时都需要动态计算字段值,这可能会影响查询性能,尤其是在数据量大的情况下。
CREATE TABLE example (
    id INT PRIMARY KEY,
    data JSON,
    extracted_value VARCHAR(100) GENERATED ALWAYS AS (data->>'$.field') VIRTUAL
);

存储生成列(Stored Generated Column)

  • 定义:存储生成列不仅在数据字典中定义,还会将计算结果持久化到磁盘上。这意味着数据会被实际存储,并在插入或更新数据时计算。
  • 优点
    • 查询性能:由于数据已被计算并存储,因此查询时不需要再次计算,提高了查询效率。
    • 适用于经常查询的字段:对于需要频繁查询的计算字段,使用存储生成列可以显著提高查询性能。
  • 缺点
    • 增加磁盘空间使用:由于数据被存储在磁盘上,表的大小会增加。
    • 写入开销:每次插入或更新数据时,需要重新计算和存储字段值,可能会增加写入开销。
CREATE TABLE example (
    id INT PRIMARY KEY,
    data JSON,
    extracted_value VARCHAR(100) GENERATED ALWAYS AS (data->>'$.field') STORED
);
  • 虚拟生成列适合那些计算开销较小且不需要频繁查询的字段,因为它不会占用额外的磁盘空间。
  • 存储生成列适合需要高查询性能的场景,尤其是对查询性能要求较高的字段,因为计算结果被持久化到磁盘上。

以下是添加虚拟字段的建表语句:

CREATE TABLE `user_games` (
    `user_id` INT UNSIGNED NOT NULL,
    `user_data` JSON NOT NULL,
    `username_virtual` VARCHAR(50) GENERATED ALWAYS AS (`user_data` ->> '$.username') VIRTUAL NOT NULL,
    `chess_rating` INT GENERATED ALWAYS AS (`user_data` ->> '$.games.Chess.rating') VIRTUAL,
    PRIMARY KEY (`user_id`)
);

在这个例子中,我们定义了两个虚拟字段:username_virtualchess_ratingusername_virtual字段用于存储玩家的用户名,而chess_rating字段用于存储玩家在Chess游戏中的评分。

插入数据

INSERT INTO `user_games` (`user_id`, `user_data`) VALUES
(101, '{ "user_id": 101, "username": "Alice", "games": { "Chess": { "rating": 1500, "wins": 30, "losses": 5 }, "Poker": { "games_played": 100, "win_percentage": 60 }, "Tetris": { "high_score": 85000 } } }'),
(102, '{ "user_id": 102, "username": "Bob", "games": { "Chess": { "rating": 1600, "wins": 25, "losses": 10 }, "Poker": { "games_played": 80, "win_percentage": 55 }, "Tetris": { "high_score": 92000 } } }'),
(103, '{ "user_id": 103, "username": "Charlie", "games": { "Chess": { "rating": 1400, "wins": 20, "losses": 15 }, "Poker": { "games_played": 120, "win_percentage": 65 }, "Tetris": { "high_score": 80000 } } }');

请在此添加图片描述

查看数据

SELECT * FROM `user_games`;

查看表的字段

SHOW COLUMNS FROM `user_games`;

可以看到,虚拟字段username_virtualchess_rating已成功创建,它们都在数据字典中进行存储,并未实际存储数据。

请在此添加图片描述

在虚拟字段上添加索引

为了提高查询性能,我们可以在虚拟字段上添加索引。首先查看当前查询的执行计划:

EXPLAIN SELECT * FROM `user_games` WHERE `username_virtual` = 'Alice';

请在此添加图片描述

添加索引

CREATE INDEX `username_idx` ON `user_games`(`username_virtual`);
CREATE INDEX `chess_rating_idx` ON `user_games`(`chess_rating`);

请在此添加图片描述

重新执行查询,将得到优化后的执行计划:

EXPLAIN SELECT * FROM `user_games` WHERE `username_virtual` = 'Alice';

请在此添加图片描述

EXPLAIN SELECT * FROM `user_games` WHERE `chess_rating` = 1500;

请在此添加图片描述

总结

在本文中,我们探讨了如何在MySQL 5.7中利用生成列来高效索引JSON字段。通过虚拟生成列和存储生成列两种方式,我们可以根据实际需求选择最适合的解决方案,平衡磁盘空间使用和查询性能。虚拟生成列在不增加存储空间的前提下,通过动态计算提升了数据存储的灵活性,而存储生成列则通过持久化计算结果显著提升了查询效率。

通过虚拟字段和索引的结合,可以显著提高对JSON字段内容的检索速度,并优化查询性能。虚拟字段不仅提供了对JSON数据的索引支持,还避免了对磁盘空间的额外消耗,是处理半结构化数据的有效工具。开发者可以更好地管理和优化JSON数据结构的查询与索引,充分发挥MySQL 5.7在现代应用中的强大能力。

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

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

相关文章

数据结构-排序(冒泡,选择,插入,希尔,快排,归并,堆排)

文章目录 排序冒泡排序代码实现 选择排序动图演示代码实现 插入排序动图演示代码实现 希尔排序动图演示代码实现 快速排序动图演示代码实现(递归) 归并排序动图演示代码实现 堆排序动图演示代码实现 排序 概念&#xff1a;排序就是将一组杂乱无章的数据按照一定的规律&#xff…

web基础—dvwa靶场(九)Weak Session IDs

Weak Session IDs&#xff08;弱会话&#xff09; Weak Session IDs&#xff08;弱会话&#xff09;&#xff0c;用户访问服务器的时候&#xff0c;一般服务器都会分配一个身份证 session id 给用户&#xff0c;用于标识。用户拿到 session id 后就会保存到 cookies 上&#x…

数据可视化pyecharts——数据分析(柱状图、折线图、饼图)

安装 首先确保已经安装了pyecharts库&#xff0c;如果没有&#xff0c;可以通过pip install pyecharts进行安装。 柱状图 从pyecharts.charts导入Bar&#xff0c;从pyecharts导入options。准备数据&#xff08;如类别数据x_data和对应的数值数据y_data&#xff09;。创建Bar对…

C# 动态编译

一、简介 CSharpCodeProvider 是 .NET 提供的一个强大工具&#xff0c;它允许开发人员在应用程序运行时动态地生成和执行 C# 代码。这一特性为后端开发带来了前所未有的灵活性和动态性&#xff0c;特别是在处理那些需要高度定制化或难以在编译时确定逻辑的场景时&#xff0c;尤…

【项目实训1】手把手教你使用 Dehazeformer 模型去雾:服务器租用、环境配置、自定义数据集、模型的训练与测试(全网最全的操作指导)

前言 文章性质:实操笔记 📖 代码来源:GitHub - IDKiro/DehazeFormer: [IEEE TIP] Vision Transformers for Single Image Dehazing 主要内容:本文详细记录了如何借助 Tabby 图形界面工具在 AutoDL 远程服务器上配置 Dehazeformer 所需的项目环境,并且成功运行 Dehazeform…

HeterGCL-Graph Contrastive Learning Framework on Heterophilic Graph

推荐指数: #paper/⭐⭐ 发表于:IJCAI24 类型&#xff1a;个人觉得算是图结构学习&#xff0c;部分思想不错 问题背景&#xff1a; 传统的随机增强不适合异配图。随机增强主要保留的是同配信息。这就导致在异配图用随机增强会抑制高频信息&#xff0c;直接使用时不合理的(这个…

JDBC 编程

目录 JDBC 是什么 JDBC 的工作原理 JDBC 的使用 引入驱动 使用 常用接口和类 Connection Statement ResultSet 使用总结 JDBC 是什么 JDBC&#xff08;Java Database Connectivity&#xff09;&#xff1a;Java数据库连接&#xff0c;是一种用于执行 SQL 语句的Java…

【附激活码】2024最新PyCharm下载安装激活汉化教程!

一、PyCharm激活 激活码&#xff1a; KQ8KMJ77TY-eyJsaWNlbnNlSWQiOiJLUThLTUo3N1RZIiwibGljZW5zZWVOYW1lIjoiVW5pdmVyc2l0YXMgTmVnZXJpIE1hbGFuZyIsImxpY2Vuc2VlVHlwZSI6IkNMQVNTUk9PTSIsImFzc2lnbmVlTmFtZSI6IkpldOWFqOWutuahtiDorqTlh4blupflkI0iLCJhc3NpZ25lZUVtYWlsIjoi…

如何使用 Python Matplotlib 绘制 3D 曲面图

在数据可视化中&#xff0c;3D 图表是一个非常有用的工具&#xff0c;特别是当想要展示复杂的三维数据时&#xff0c;如期权的波动率曲面。Python 的 matplotlib 库提供了生成各种类型图表&#xff0c;包括 3D 图表。 本文将介绍如何使用 Python 中的 matplotlib 绘制 3D 曲面…

分公司=一部门——组合模式

文章目录 分公司一部门——组合模式分公司不就是一部门吗&#xff1f;组合模式透明方式与安全方式何时使用组合模式公司管理系统组合模式好处 分公司一部门——组合模式 分公司不就是一部门吗&#xff1f; 时间&#xff1a;5月10日19点  地点&#xff1a;小菜、大鸟住所的客…

开放的数据时代:Web3和个人隐私的未来

在数字化和信息化的时代&#xff0c;数据隐私成为了公众关注的焦点。随着Web3技术的兴起&#xff0c;个人隐私保护进入了一个新的阶段。Web3作为去中心化的互联网架构&#xff0c;提出了对数据控制和隐私保护的新方案。本文将探讨Web3如何影响个人隐私的未来&#xff0c;并分析…

[附源码]SpringBoot+VUE+Java实现人脸识别系统

今天带来一款优秀的项目&#xff1a;java人脸识别系统源码 。 系统采用的流行的前后端分离结构&#xff0c;内含功能包括 “人脸数数据录入”&#xff0c;“人脸管理”&#xff0c;“摄像头识别” 如果您有任何问题&#xff0c;也请联系小编&#xff0c;小编是经验丰富的程序员…

编写程序,在一行上显示1-5数字,每个相邻的数字要求用空格进行分开

目录 前言 一、一行输出&#xff08;使用一个System语句输出&#xff09; 二、多行输出&#xff08;使用多&#xff08;N&#xff09;个System语句输出&#xff09; 三、循环输出&#xff08;使用for语句循环在通过System语句输出&#xff09; 四、完整代码 前言 1.本文所…

只会Python编程,做量化交易策略用QMT怎么样?听说QMT是支持Python的!

QMT是专门为机构、活跃投资者、高净值客户等专业投资者研发的智能量化交易终端&#xff0c;拥有高速行情、极速交易、策略交易、多维度风控等专业功能&#xff0c;满足专业投资者的特殊交易需求。覆盖业务范围广:沪深A股、港股通、两融、期权、期货。 适合用QMT的投资者&#x…

使用 UWA Gears 定位游戏内存问题

UWA Gears 是UWA最新发布的无SDK性能分析工具。针对移动平台&#xff0c;提供了实时监测和截帧分析功能&#xff0c;帮助您精准定位性能热点&#xff0c;提升应用的整体表现。 内存不足、内存泄漏和过度使用等问题&#xff0c;常常导致游戏出现卡顿、崩溃&#xff0c;甚至影响…

偷偷告诉你,学会使用这几样测试用例管理工具就够啦!

在软件开发过程中&#xff0c;测试是必不可少的一环&#xff0c;而测试用例则是测试的重要依据。如何有效地管理测试用例&#xff0c;提高测试效率&#xff0c;是每一个测试人员都需要面对的问题。本文将为你介绍几款实用的测试用例管理工具&#xff0c;帮助你更好地进行测试工…

2024年双十一不容错过的好物分享,最值得买的五款单品

双十一购物狂欢节将至&#xff0c;这是一场属于“剁手党”的年度盛宴。每年的11月11日&#xff0c;各大电商平台纷纷推出海量优惠活动&#xff0c;吸引无数消费者积极参与。对于热衷于寻找好物的人来说&#xff0c;双十一无疑是一个不容错过的机会&#xff0c;双十一好物不间断…

基于JavaWeb开发的java+Springboot操作系统教学交流平台详细设计实现

基于JavaWeb开发的javaSpringboot操作系统教学交流平台详细设计实现 &#x1f345; 作者主页 网顺技术团队 &#x1f345; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; &#x1f345; 文末获取源码联系方式 &#x1f4dd; &#x1f345; 查看下方微信号获取联系方式 承接…

零基础制作一个ST-LINK V2 附PCB文件原理图 AD格式

资料下载地址&#xff1a;零基础制作一个ST-LINK V2 附PCB文件原理图 AD格式 ST-LINK/V2是一款可以在线仿真以及下载STM8以及STM32的开发工具。支持所有带SWIM接口的STM8系列单片机;支持所有带JTAG / SWD接口的STM32系列单片机。 基本属性 ST-LINK/V2是ST意法半导体为评估、开…

【我的 PWN 学习手札】劫持 tcache_perthread_struct

目录 前言 一、tcache perthread struct 二、劫持 tcache_perthread_struct 三、测试与模板 前言 tcache 是 glibc 2.26 (ubuntu 17.10) 之后引入的一种技术&#xff0c;目的是提升堆管理的性能&#xff0c;与 fast bin 类似。 tcache 引入了两个新的结构体&#xff0c; tc…