当前位置:网站首页>Mysql存储json格式数据
Mysql存储json格式数据
2022-07-29 01:15:00 【xiaoweiwei99】
Mysql5.7版本以后新增的功能,Mysql提供了一个原生的Json类型,Json值将不再以字符串的形式存储,而是采用一种允许快速读取文本元素(document elements)的内部二进制(internal binary)格式。在Json列插入或者更新的时候将会自动验证Json文本,未通过验证的文本将产生一个错误信息
JSON 数据类型推荐使用在不经常更新的静态数据存储
创建表 t_user
CREATE TABLE `t_user_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;

登录方式字段使用json格式,分为phone,wechat,qq,email,zhifubao等等
插入数据:
insert into t_user values (1,'tom', 25, '{"email": "[email protected]", "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 数据类型推荐使用在不经常更新的静态数据存储。
边栏推荐
- 为什么 BI 软件都搞不定关联分析
- 【7.21-26】代码源 - 【好序列】【社交圈】【namonamo】
- Explanation of yocto project directory structure
- What is the function of data parsing?
- Js DOM2 和 DOM3
- 【流放之路-第二章】
- 给LaTeX公式添加优美的注解;日更『数据科学』面试题集锦;大学生『计算机』自学指南;个人防火墙;前沿资料/论文 | ShowMeAI资讯日报
- Promise解决异步
- As long as I run fast enough, it won't catch me. How does a high school student achieve a 70% salary increase under the epidemic?
- 数据平台数据接入实践
猜你喜欢
![[the road of Exile - Chapter 2]](/img/98/0a0558dc385141dbb4f97bc0e68b70.png)
[the road of Exile - Chapter 2]

【流放之路-第四章】

Nine days later, we are together to focus on the new development of audio and video and mystery technology

Sigma-DSP-OUTPUT
![[10:00 public class]: application exploration of Kwai gpu/fpga/asic heterogeneous platform](/img/e7/1d06eba0e50eeb91d2d5da7524f4af.png)
[10:00 public class]: application exploration of Kwai gpu/fpga/asic heterogeneous platform

【10点公开课】:快手GPU/FPGA/ASIC异构平台的应用探索

Stonedb invites you to participate in the open source community monthly meeting!

MPEG音频编码三十年

ASCII code table

Thirty years of MPEG audio coding
随机推荐
Use POI to export excel file, image URL to export file, image and excel file to export compressed package
leetcode/乘积小于K 的连续子数组的个数
正则过滤数据学习笔记(①)
Secret skill winter tide branding skill matching
数学建模——仓内拣货优化问题
The scientific research environment has a great impact on people
leetcode/和为k的连续子数组个数
Talk about possible problems when using transactions (@transactional)
StoneDB 为何敢称业界唯一开源的 MySQL 原生 HTAP 数据库?
Regular filtering data learning notes (①)
Force deduction brush question (1): sum of two numbers
leetcode/0和1个数相同的连续子数组
Day01 job
Overview of Qualcomm 5g intelligent platform
[7.21-26] code source - [sports festival] [Dan fishing war] [maximum weight division]
Comprehensive explanation of "search engine crawl"
Comprehensive analysis of news capture doorway
What is browser fingerprint recognition
Sword finger offer special assault edition day 13
How to protect WordPress website from network attack? It is essential to take safety measures