Mysql存储json格式数据

article/2025/9/28 8:02:49

Mysql5.7版本以后新增的功能,Mysql提供了一个原生的Json类型,Json值将不再以字符串的形式存储,而是采用一种允许快速读取文本元素(document elements)的内部二进制(internal binary)格式。在Json列插入或者更新的时候将会自动验证Json文本,未通过验证的文本将产生一个错误信息


JSON 数据类型推荐使用在不经常更新的静态数据存储

创建表 t_user

登录方式字段使用json格式,分为phone,wechat,qq,email,zhifubao等等

插入数据:

insert into t_user values (1,'tom', 25, '{"email": "1324@qq.com", "phone": "13200001111", "wechat": "147258369"}');
insert into t_user values (2,'jack', 30, '{"phone": "13500001111"}');
insert into t_user values (3,'lily', 18, '{"qq": "147258369", "phone": "13600001111"}');
insert into t_user values (4,'lily', 45, '{"wechat":"1884875663"}');

查询

用户名,手机号,微信号

select name,
(JSON_EXTRACT(login_info, '$.phone')) phone,
JSON_UNQUOTE(JSON_EXTRACT(login_info, '$.wechat')) wechat
from t_user;

 可以看出

JSON_UNQUOTE 函数作用是 去除json字符串的引号,将值转成string类型

JSON_EXTRACT 函数作用是 提取json值

简洁的写法作用等同于上面的

select name,
login_info ->> '$.phone' phone,
login_info ->> '$.wechat' wechat
from t_user;

 ->> 表达式 等同于 JSON_UNQUOTE(JSON_EXTRACT(login_info, '$.wechat'))

-- 使用json中的字段作为查询条件
select name,
login_info ->> '$.phone' phone,
login_info ->> '$.wechat' wechat
from t_user
where login_info ->> '$.phone' = '13200001111';

 

json数据 增加索引

 给login_info字段中的手机号增加索引

-- 给login_info这个json中的phone增加索引
alter table t_user add COLUMN phone varchar(11) as (login_info ->> '$.phone');
alter table t_user add UNIQUE INDEX idx_uq_phone(phone);

上述 SQL 首先创建了一个虚拟列 phone,这个列是由函数 login_info->>"$.phone" 计算得到的。然后在这个虚拟列上创建一个唯一索引 idx_uq_phone。这时再通过虚拟列 phone进行查询,就可以看到优化器会使用到新创建的 idx_uq_phone 索引

-- 查看索引
EXPLAIN
select *
from t_user
where phone = '13200001111';

 我们查看表结构,发现索引增加上去了

 使用场景

某些业务需要做用户画像(也就是对用户打标签),然后根据用户的标签,通过数据挖掘技术,进行相应的产品推荐。比如:

  • 在电商行业中,根据用户的穿搭喜好,推荐相应的商品;

  • 在音乐行业中,根据用户喜欢的音乐风格和常听的歌手,推荐相应的歌曲;

  • 在金融行业,根据用户的风险喜好和投资经验,推荐相应的理财产品。

在这,我强烈推荐你用 JSON 类型在数据库中存储用户画像信息,并结合 JSON 数组类型和多值索引的特点进行高效查询。

创建用户画像定义表:

CREATE TABLE `t_tag` (`id` int NOT NULL AUTO_INCREMENT,`tag_name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '标签名称',PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

insert into t_tag values (null, '70后');
insert into t_tag values (null, '80后');
insert into t_tag values (null, '90后');
insert into t_tag values (null, '00后');
insert into t_tag values (null, '10后');
insert into t_tag values (null, '爱运动');
insert into t_tag values (null, '爱听歌');
insert into t_tag values (null, '爱看电影');
insert into t_tag values (null, '高学历');
insert into t_tag values (null, '小资');
insert into t_tag values (null, '有车');
insert into t_tag values (null, '有小孩');
insert into t_tag values (null, '喜欢网购');
insert into t_tag values (null, '喜欢点外卖');
insert into t_tag values (null, '萝莉');

 创建用户标签中间表

CREATE TABLE `t_user_tag` (`user_id` int NOT NULL COMMENT '用户id',`tag_id` json NOT NULL COMMENT '用户标签id',PRIMARY KEY (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

 插入数据,使用数组的形式存储

insert into t_user_tag values (1,'[2,4,6]');
insert into t_user_tag values (2,'[1,3,7]');
insert into t_user_tag values (3,'[8,10,12]');

 

 MySQL 8.0.17 版本开始支持 Multi-Valued Indexes,用于在 JSON 数组上创建索引,并通过函数 member of、json_contains、json_overlaps 来快速检索索引数据。所以你可以在表 UserTag 上创建 Multi-Valued Indexes:

ALTER TABLE t_user_tag
ADD INDEX idx_user_tags ((cast((tag_id->"$") as unsigned array)));

 查询爱看电影的

select * from t_user_tag
where 8 MEMBER OF(tag_id -> '$');

 查询爱看电影,且有小孩的

select * from t_user_tag
where JSON_CONTAINS(tag_id -> '$', '[8,10]');

  • 使用 JSON 数据类型,推荐用 MySQL 8.0.17 以上的版本,性能更好,同时也支持 Multi-Valued Indexes;

  • JSON 数据类型的好处是无须预先定义列,数据本身就具有很好的描述性;

  • 不要将有明显关系型的数据用 JSON 存储,如用户余额、用户姓名、用户身份证等,这些都是每个用户必须包含的数据;

  • JSON 数据类型推荐使用在不经常更新的静态数据存储。


http://chatgpt.dhexx.cn/article/PMmwVmA6.shtml

相关文章

多路复用技术之时分复用

多路复用技术是通信技术领域的一个专业名词,从字面上的意思去理解就是将多路信号按照一定的规则共用同一条信道进行传输。 一、多路复用技术的分类 多路复用技术通常分为频分多路复用、时分多路复用、波分多路复用、码分多址和空分多址。 二、时分多路复用原理 …

“分集”与“复用”辨析

【注:本文中几乎所有文字与图片均来自网络,本人仅做了整理与归纳!】 文章目录 分集与复用1. 分集与复用的概念1.1 分集1.2 复用 2. 分集与复用的目的2.1 分集的目的2.2 分集阶数与分集增益2.3 复用的目的 3. 分集与复用的分类3.1 分集技术3.…

认识LTE(七):LTE中的两种无反馈模式:发射分集(TM2)和开环空分复用(TM3)

认识LTE(七):LTE中的两种无反馈模式:发射分集(TM2)和开环空分复用(TM3) 文章目录 认识LTE(七):LTE中的两种无反馈模式:发射分集(TM2)和开环空分复用&#xff…

认识LTE(八):LTE中的反馈:闭环空分复用(TM4)

认识LTE(八):LTE中的反馈:闭环空分复用(TM4) 文章目录 认识LTE(八):LTE中的反馈:闭环空分复用(TM4)零.代码地址一.TM4到底反馈了什么?二.CQI反馈二.PMI 三.RI四.总结 零.…

图解通信原理与案例分析-21:4G LTE多天线技术--天线端口、码流、分集Diveristy、波束赋形BF、空分复用MIMO、空分多址

目录 前言: 第1章 MIMO多天线技术概述 1.1 三大目的 1.2 六大分类 第2章 单天线SISO(单输入单输出) 2.1 概述 2.2 实现原理--多路“异频”《发送接收》对 第3章 接收分集MISO(多输入单输出):冗余接…

[4G5G专题-28]:架构-什么是多天线技术与5G大规模天线阵列、波束赋形、高阶空分复用?

目录 第1章 多天线技术概述 1.1 LTE的多天线技术回顾 1.2 5G大规模天线阵列、波束赋形以及其动机 第2章 什么是波束赋形 2.1 波束赋形与大规模天线阵列的关系 2.2 波束赋形的定义 2.3 波束赋形要回答和解决的两个问题 2.4 常见的波束赋形相关的专业术语 第3章 Active …

复用,多址的区分以及其涉及的相关数据速率

复用技术 为了让尽可能多的手机使用同一个频段,无线通信设计了多址复用技术: 时分多路复用(Time Division Multiplexing,TDM)要求各个子通道按时间片轮流地占用整个带宽。时间片的大小可以按一次传送一位、一个字节或一个固定大…

王道 —— 操作系统的四个特征

1、知识总览 操作系统有并发、共享、虚拟、异步四个基本特征,并发和共享是两个最基本的特征,二者互为存在条件; 2、操作系统的特征 —— 并发 并发:指两个或者多个时间在同一时间间隔内发生。这些事件宏观上是同时发生的&#x…

操作系统学习笔记——总体总结

看书太慢容易抓不住重点,所以在此按照操作系统的主要内容分别查网上博客资料进行学习。 一、引论 操作系统基本特性: 并发: 1.并行与并发:并行性是指两个或多个时间在同一时刻发送;并发性是指两个或多是事件在同一…

数据库脏读、不可重复读、幻读

1. 脏读 :脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。 2. 不可重复读 :是指在一个事务内&…

关于可重复读和幻读

最近看到MySQL隔离性的知识,发现网上很多人说可重复读所针对的操作是update,然后亲自试验了一把,见下文。 首先我们知道在读提交隔离级别下,同一事物A中以相同的查询语句可能得到的结果不一致的情况,即不可重复读。这是…

可重复读如何解决幻读

学习之前的疑问: 可重复读的概念 与 不可重复读的概念 行锁gap锁(间隙锁) 快照读 与 当前读区别 快照读中的MVCC 当前读中的gap锁 和 行锁 前几天面试时被问到了mysql可重复读如何解决幻读的问题,之前脑子中的概念只有增加了共享锁和排他锁进行避免&…

MySQL(四)—MVCC实现可重复读的原理

文章目录 一、MVCC概况二、MVCC实现原理1.两或三个隐藏字段。2.undo log3.一个数组4.ReadView 三、举例验证MVCC原理参考文献 一、MVCC概况 MVCC是什么?MVCC即多版本控制协议,InnoDB实现了MVCC作版本控制,防止不该被当前事务看到的数据看到。…

可重复读

《循序渐进DB2-系统管理、运行维护与应用案例》第10章锁和并发,本章首先介绍了通用的事务概念,并指出DB2在用户读取、写入数据时的加锁策略、锁模式、兼容性等。本章还介绍了在并发控制中常碰到的4种数据异常现象,同时讲述了DB2如何使用锁克服…

mysql不可重复读和重复读_脏读、幻读、不可重复读的区别是什么

脏读、幻读、不可重复读的区别:1、脏读就是指当一个事务正在访问数据,并且对数据进行了修改;2、不可重复读是指在一个事务内,多次读同一数据;3、幻读是指当事务不是独立执行时发生的一种现象。 【相关学习推荐&#xf…

Mysql如何实现可重复读

首先对于mysql来说相信也并不陌生,mysql默认的事务的隔离级别是3,即可以实现可重复读,那mysql又是怎样实现可重复读的呢? 下边进行简单的介绍 这里就要提到了mvcc,即多版本并发控制 首先先来看一个事务的执行图 此时…

MySQL 可重复读隔离级别,完全解决幻读了吗?

我在上一篇文章中提到,MySQL InnoDB 引擎的默认隔离级别虽然是「可重复读」,但是它很大程度上避免幻读现象(并不是完全解决了),解决的方案有两种: 针对快照读(普通 select 语句)&am…

MySQL可重复读-问题实践

MySQL可重复读之幻读问题 MySQL事务存储引擎InnoDB的默认隔离级别为可重复读,在该隔离级别下,可以很大程度上避免幻读的问题,完全避免脏读和不可重复读问题,接下来通过实际的测试看看这些场景是否真的能够被完全避免 模拟均基于…

可重复读下的幻读

在事务执行过程中,另一个事务将新记录添加到正在读取的事务中时,会发生幻读(事务隔离级别为可重复读REPEATABLE-READ)。当执行SELECT … WHERE语句时未对where范围锁定,则可能会发生幻读。幻读是不可重复读的一种特殊情…

MySQL可重复读应用场景_mysql-repeatable read 可重复读隔离级别-幻读实例场景

本文详解 repeatable read 可重复读 隔离级别产生的影响(幻读) -- SERIALIZABLE serializable 序列化 ;一个个事务排成序列的形式。事务一个挨一个执行,等待前一个事务执行完,后面的事务才可以顺序执行 -- REPEATEABLE READ repeatable read …