利用JSON数据类型优化关系型数据库设计

news2025/1/30 11:56:38

利用JSON数据类型优化关系型数据库设计

前言

在关系型数据库中,传统的结构化存储方式要求预先定义好所有的列及其数据类型。

然而,随着业务的发展,这种设计可能会显得不够灵活,尤其是在需要扩展单个列的描述功能时。

JSON数据类型的引入,为关系型数据库提供了存储非结构化数据的能力,打破了关系型与非关系型数据库之间的界限。

本文将深入探讨JSON数据类型的优势,并通过实际案例展示如何在业务中有效使用JSON类型。

一、JSON数据类型的优势

1. 灵活的数据结构

JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,支持复杂的数据结构,包括对象和数组。

与传统的固定列结构不同,JSON类型允许字段的无限扩展,无需预先定义所有列。

这种灵活性非常适合存储动态或非结构化的数据。

2. 支持多种数据类型

JSON不仅支持字符串、整型、浮点数等基本数据类型,还支持嵌套的JSON对象和数组。

例如,可以存储图片的元数据、用户的登录信息或用户画像标签等复杂数据。

3. 高效的查询与索引

从MySQL 5.7版本开始,JSON类型支持函数索引和多值索引(Multi-Valued Indexes),这使得在JSON字段上进行高效查询成为可能。

通过虚拟列和索引,可以显著提升查询性能。

4. 简化表结构设计

使用JSON类型可以减少表的列数,避免频繁执行 ALTER TABLE操作来添加新列。

这对于需要频繁扩展字段的业务场景非常有用。

二、JSON类型的基本用法

1. JSON对象与数组

JSON对象是由键值对组成的无序集合,而JSON数组是由有序的值组成的列表。例如:

  • JSON对象:存储图片的元数据

    {
      "Image": {
        "Width": 800,
        "Height": 600,
        "Title": "View from 15th Floor",
        "Thumbnail": {
          "Url": "http://www.example.com/image/481989943",
          "Height": 125,
          "Width": 100
        },
        "IDs": [116, 943, 234, 38793]
      }
    }
    
  • JSON数组:存储多个地理位置信息

    [
      {
        "precision": "zip",
        "Latitude": 37.7668,
        "Longitude": -122.3959,
        "City": "SAN FRANCISCO",
        "State": "CA"
      },
      {
        "precision": "zip",
        "Latitude": 37.371991,
        "Longitude": -122.026020,
        "City": "SUNNYVALE",
        "State": "CA"
      }
    ]
    

2. JSON类型的存储与查询

在MySQL中,JSON类型的数据可以通过 JSON_EXTRACT->>等操作符进行查询。例如:

SELECT userId, loginInfo->>"$.cellphone" AS cellphone
FROM UserLogin;

三、实战案例:用户登录信息存储

1. 表结构设计

假设一个用户可以通过手机、微信、QQ等多种方式登录,我们可以使用JSON类型存储登录信息:

CREATE TABLE UserLogin (
    userId BIGINT NOT NULL,
    loginInfo JSON,
    PRIMARY KEY(userId)
);

2. 插入数据

插入用户登录信息:

INSERT INTO UserLogin VALUES 
(1, '{"cellphone": "13918888888", "wxchat": "破产码农", "QQ": "82946772"}'),
(2, '{"cellphone": "15026888888"}');

3. 查询数据

通过 ->>操作符提取JSON字段:

SELECT userId, loginInfo->>"$.cellphone" AS cellphone
FROM UserLogin;

4. 创建虚拟列与索引

为了优化查询性能,可以创建虚拟列并为其添加索引:

ALTER TABLE UserLogin 
ADD COLUMN cellphone VARCHAR(255) AS (loginInfo->>"$.cellphone");

ALTER TABLE UserLogin 
ADD UNIQUE INDEX idx_cellphone(cellphone);

四、实战案例:用户画像标签存储

1. 表结构设计

在用户画像场景中,可以使用JSON数组存储用户的标签:

CREATE TABLE UserTag (
    userId BIGINT NOT NULL,
    userTags JSON,
    PRIMARY KEY(userId)
);

2. 插入数据

插入用户标签数据:

INSERT INTO UserTag VALUES 
(1, '[2, 6, 8, 10]'),  -- 80后、高学历、小资、有房、常看电影
(2, '[3, 10, 12]');   -- 90后、常看电影、爱外卖

3. 多值索引与查询

从MySQL 8.0.17开始,支持在JSON数组上创建多值索引:

ALTER TABLE UserTag
ADD INDEX idx_user_tags ((CAST(userTags->"$" AS UNSIGNED ARRAY)));

通过 MEMBER OFJSON_CONTAINS等函数进行高效查询:

-- 查询常看电影的用户
SELECT * FROM UserTag 
WHERE 10 MEMBER OF(userTags->"$");

-- 查询80后且常看电影的用户
SELECT * FROM UserTag 
WHERE JSON_CONTAINS(userTags->"$", '[2, 10]');

五、总结

JSON数据类型为关系型数据库提供了存储和处理非结构化数据的能力,极大地增强了数据库的灵活性。

通过合理使用JSON类型,可以有效解决业务中的动态字段扩展、复杂数据存储等问题。

然而,使用JSON类型时也需要注意以下几点:

  1. 避免滥用:JSON类型适合存储动态或非结构化数据,但对于固定结构的字段,仍建议使用传统的列存储。
  2. 索引优化:通过虚拟列和多值索引,可以显著提升JSON字段的查询性能。
  3. 版本兼容性:JSON类型从MySQL 5.7开始支持,建议在生产环境中使用MySQL 8.0及以上版本,以获得更好的性能和功能支持。

– 欢迎点赞、关注、转发、收藏【我码玄黄】,各大平台同名。

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

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

相关文章

极简壁纸js逆向

首先抓包,翻页可以看到数据储存在该包 可以看到随着页面变化,只有current在变化 而且载荷都没有加密,看来不用js逆向了 爬取代码 import os import asyncio import aiohttp import jsonheaders {"accept": "application/j…

JAVA 接口、抽象类的关系和用处 详细解析

接口 - Java教程 - 廖雪峰的官方网站 一个 抽象类 如果实现了一个接口,可以只选择实现接口中的 部分方法(所有的方法都要有,可以一部分已经写具体,另一部分继续保留抽象),原因在于: 抽象类本身…

使用PC版本剪映制作照片MV

目录 制作MV模板时长调整拖动边缘缩短法分割删除法变速法整体调整法 制作MV 导入音乐 导入歌词 点击歌词 和片头可以修改字体: 还可以给字幕添加动画效果: 导入照片,自动创建照片轨: 修改片头字幕:增加两条字幕轨&…

.NET Core缓存

目录 缓存的概念 客户端响应缓存 cache-control 服务器端响应缓存 内存缓存(In-memory cache) 用法 GetOrCreateAsync 缓存过期时间策略 缓存的过期时间 解决方法: 两种过期时间策略: 绝对过期时间 滑动过期时间 两…

【微服务与分布式实践】探索 Dubbo

核心组件 服务注册与发现原理 服务提供者启动时,会将其服务信息(如服务名、版本、所在节点的网络地址等)注册到注册中心。服务消费者则可以从注册中心发现可用的服务提供者列表,并与之通信。注册中心会存储服务的信息&#xff0c…

Java 大视界 -- Java 大数据在生物信息学中的应用与挑战(67)

💖亲爱的朋友们,热烈欢迎来到 青云交的博客!能与诸位在此相逢,我倍感荣幸。在这飞速更迭的时代,我们都渴望一方心灵净土,而 我的博客 正是这样温暖的所在。这里为你呈上趣味与实用兼具的知识,也…

NeuIPS 2024 | CoT推理的新突破:推理边界框架(RBF)

近年来,大型语言模型(LLMs)在推理任务上的能力不断提升,尤其是 思维链(Chain-of-Thought, CoT) 技术,使得模型可以逐步推演逻辑,提高预测准确率。然而,当前的CoT推理仍然…

linux——进程树的概念和示例

一些程序进程运行后,会调用其他进程,这样就组成了一个进程树。 比如,在Windows XP的“运行”对话框中输入“cmd”启动命令行控制台,然后在命令行中输入“notepad”启动记事本,那么命令行控制台进程“cmd.exe”和记事本进程“note…

CSAPP学习:前言

前言 本书简称CS:APP。 背景知识 一些基础的C语言知识 如何阅读 Do-做系统 在真正的系统上解决具体的问题,或是编写和运行程序。 章节 2025-1-27 个人认为如下章节将会对学习408中的操作系统与计算机组成原理提供帮助,于是先凭借记忆将其简单…

【番外篇】鸿蒙扫雷天纪:运混沌灵智勘破雷劫天局

大家好啊,我是小象٩(๑ω๑)۶ 我的博客:Xiao Xiangζั͡ޓއއ 很高兴见到大家,希望能够和大家一起交流学习,共同进步。 这一节课我们不学习新的知识,我们来做一个扫雷小游戏 目录 扫雷小游戏概述一、扫雷游戏分析…

【反悔堆】力扣1642. 可以到达的最远建筑

给你一个整数数组 heights ,表示建筑物的高度。另有一些砖块 bricks 和梯子 ladders 。 你从建筑物 0 开始旅程,不断向后面的建筑物移动,期间可能会用到砖块或梯子。 当从建筑物 i 移动到建筑物 i1(下标 从 0 开始 )…

电力晶体管(GTR)全控性器件

电力晶体管(Giant Transistor,GTR)是一种全控性器件,以下是关于它的详细介绍:(模电普通晶体管三极管进行对比学习) 基本概念 GTR是一种耐高电压、大电流的双极结型晶体管(BJT&am…

Cursor 帮你写一个小程序

Cursor注册地址 首先下载客户端 点击链接下载 1 打开微信开发者工具创建一个小程序项目 选择TS-基础模版 官方 2 然后使用Cursor打开小程序创建的项目 3 在CHAT聊天框输入自己的需求 比如 小程序功能描述:吃什么助手 项目名称: 吃什么小程序 功能目标…

【shell工具】编写一个批量扫描IP地址的shell脚本

批量扫描某个网段中的主机(并发) 创建目录编写脚本文件 mkdir /root/ip_scan_shell/ touch /root/ip_scan_shell/online_server.txt touch /root/ip_scan_shell/offline_server.txt touch /root/ip_scan_shell/ip_scan.sh写入下面shell到脚本文件中…

vim如何设置制表符表示的空格数量

:set tabstop4 设置制表符表示的空格数量 制表符就是tab键,一般默认是四个空格的数量 示例: (vim如何使设置制表符表示的空格数量永久生效:vim如何使相关设置永久生效-CSDN博客)

LangChain:使用表达式语言优化提示词链

在 LangChain 里,LCEL 即 LangChain Expression Language(LangChain 表达式语言),本文为你详细介绍它的定义、作用、优势并举例说明,从简单示例到复杂组合示例,让你快速掌握LCEL表达式语言使用技巧。 定义 …

多线程编程杂谈( 下)

问题 是否存在其它中途线程退出的方法? 通过调用Linux系统函数 pthread_cancel(...) 可中途退出线程 Linux 提供了线程取消函数 取消状态 接受取消状态: PTHREAD_CANCEL_ENABLE拒绝取消状态: PTHREAD_CANCEL_DISABLE 取消请求 延迟取消: PTHREAD_CANCEL_DEFERR…

电脑无法开机,重装系统后没有驱动且驱动安装失败

电脑无法开机,重装系统后没有驱动且驱动安装失败 前几天电脑突然坏了,电脑卡住后,强制关机,再开机后开机马上就关机。尝试无数次开机后失败,进入BIOS界面,发现已经没有Windows系统了。重新安装系统后&…

【Java数据结构】了解排序相关算法

基数排序 基数排序是桶排序的扩展,本质是将整数按位切割成不同的数字,然后按每个位数分别比较最后比一位较下来的顺序就是所有数的大小顺序。 先对数组中每个数的个位比大小排序然后按照队列先进先出的顺序分别拿出数据再将拿出的数据分别对十位百位千位…

机器学习-线性回归(对于f(x;w)=w^Tx+b理解)

一、𝑓(𝒙;𝒘) 𝒘T𝒙的推导 学习线性回归,我们那先要对于线性回归的表达公示,有所认识。 我们先假设空间是一组参数化的线性函数: 其中权重向量𝒘 ∈ R𝐷 …