json数组怎么写_MYSQL8 处理JSON 我不再是豆包,我是干粮

33f9787ac2f265c651f7c650fbb0306f.png

最近来了一个项目,本身如果用MONGODB 有点大材小用,所以为了避免某些表继续使用text字段来处理JSON 数据的方式,让技术水平上一个档次,并且公司也不在上MYSQL 5.7 的新项目,全部是8.018这个版本。

继续上一篇文字,那就看看MYSQL 8的野心到底是如何展现的。顺便研究完,给开发一个靠谱的方案,解决人家的问题。(如果是MYSQL5.7 打死我也不会给推荐的)

首先我们的界定为什么要使用MYSQL 8 种的JSON 格式,而不是之前应付的text type。

1 在数据输入的时候,能进行数据的检测,是否符合JSON 的标准

2 数据在处理的时候,通过键值对的方式进行查询,不在需要将字段里面的数据读取后,在进行处理。

用一句话来讲,更规范,更快速,专业的处理JSON,MYSQL OK的

为什么一个传统数据库要开始专注于处理非结构,半结构化得数据,因为需求,需求决定着一切,现在不同系统中传输信息的格式是什么,XML, 明文,OMG, JSON JSON JSON 。如果所有传统数据库都不能处理JSON ,那很可能,由于某些原因,某些业务场景,就不在需要什么 MYSQL ,PG 这样的数据库,取代的就是 MONGODB 。好在 PG 天生就是 JSON 好手, MYSQL 8 的一部分野心也是 JSON, 所以 MONGODB加油呀。

下面是一张,接受其他公司的数据的一张表。

其实MYSQL 5.7 本身也支持JSON ,之前也写过一篇,不过那篇是恶评,太烂了。MYSQL 8 如果使用JSON 也要在 8.014版本以上,否则也会吃亏在数组方面。在MySQL 8.0中,优化器可以执行JSON列的局部就地更新,而不是删除旧文档并将整个新文档写入该列,当然这也是有条件的。

CREATE TABLE `t_clue_info` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`fk_applyid` int(11) NOT NULL COMMENT ''申请id'',

`context` json DEFAULT NULL COMMENT ''接口结果'',

`cdate` datetime NOT NULL COMMENT ''创建时间'',

PRIMARY KEY (`id`),

KEY `ix_fk_applyid` (`fk_applyid`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

insert into t_tmall_clue_info (fk_applyid,context,cdate) values (1982873,'{"apply_id":"cm-387237","info":"sim-093823","date":"2020-03-18 02:00:09"}',"2020-03-18 02-09-09");

3afbf62626f2b2bcb52f449b5b5e5d7b.png

小结:1 插入的JSON 的字段要必须是 JSON 的格式

2 在插入的时候使用单引号进行包含,里面是正确的JSON格式

我们继续提高点难度,让MYSQL中开始存储数组

insert into t_tmall_clue_info (fk_applyid,context,cdate) values (1982823,'{"apply_id":"cm-387234","info":"sim-093856","tag":[12,34,56],"date":"2020-03-11 09:00:09"}',"2020-03-18 02-09-19");

insert into t_tmall_clue_info (fk_applyid,context,cdate) values (1982823,'{"apply_id":"cm-387234","info":"sim-093856","tag":[12,34,56],"date":"2020-03-11 09:00:09"}',"2020-03-18 02-09-19");

insert into t_tmall_clue_info (fk_applyid,context,cdate) values (1982823,'{"apply_id":"cm-387234","info":"sim-093856","tag":[12,34,56],"date":"2020-03-11 09:00:09","contant":"the informatiton is from car100"}',"2020-03-18 02-09-19");

insert into t_tmall_clue_info (fk_applyid,context,cdate) values (1982823,'{"apply_id":"cm-387234","info":"sim-093856","tag":[12,34,56],"date":"2020-03-11 09:00:09","contant":"the informatiton is from car100","add-in":"re-092878"}',"2020-03-18 02-09-19");

c96da6ea1f673ce06e41f8487533852d.png

如果你细心的话,就会发现我上面的输入和下面的展示的地方,有点意思的地方,展示的时候和你的输入的字段顺序无太大关系,他会自动将一些类似的东西进行整齐的排列(尽量),我说不上这样做是好还是...... 但看上去,绝对要比使用 text 那样的方式要好的多,至少你一眼就可以看出JSON 里面缺哪个多哪个。

查询的方式也,越来越有点意思了

SELECT * FROM t_tmall_clue_info WHERE context->>'$.info' = 'sim-093856';

461655bc137ce1997df921a2b81e389b.png

MYSQL 8 中的 Multi-Valued Indexes,其实就是为MYSQL JSON 数组而生的。一个多值索引可以有多个索引记录。多值索引用于索引JSON数组。例

怎么在上面的表添加一个多值索。"tag":[12,34,56]

CREATE INDEX idx_tmall_tag ON t_tmall_clue_info ( (CAST(context->'$.tag' AS UNSIGNED ARRAY)) );

9638941c61aee3bfa58013221c32a4d2.png

SELECT * FROM t_tmall_clue_info WHERE JSON_CONTAINS(context->'$.tag',cast('[78]' AS JSON));

27a4fa96d73dfee401982d324fb808b9.png

SELECT * FROM t_tmall_clue_info WHERE JSON_OVERLAPS(context->'$.tag',cast('[78]' AS JSON));

5ece7f61f59350c7bec3207b648d7895.png

Json_contains 和 json_overlaps 之间的区别是,一个包含数组中的值某即可,另一个不行,必须是你查询的数组的值都包含才可以。

882327f43d6d83e80eea21488dc43f58.png

在添加完索引,查询数组里面的值,是可以走索引的。

SELECT * FROM t_tmall_clue_info WHERE 78 MEMBER OF(context->'$.tag');

1d2cb4de3bb01aa6565af812980b1e45.png

当然只查询数组中的一个值也是可以的。

这里需要注意的几个地方

1 如果多值键部分有一个空数组,则不会向索引中添加任何项,并且索引扫描无法访问数据记录。

2 多值索引是虚拟列上的虚拟索引,所以它们必须遵守与虚拟生成列上的二级索引相同的规则。

下面是一些其他方面的操作

如何只显示一些需要显示的东西,并且可以看到这里里面如果有没有值的情况,MySQL会显示 null

select context-> '$.tag',context-> '$.date' from t_tmall_clue_info;

f67ba8071f5fce66c68de40c0b53fb48.png
a0172e8ca4d75d64e8a471c6aa4b31bb.png

上面两个语句都可以显示相关的信息,但是符号的不同

->

->>

在展示阶段相当于将""去掉和不去掉的选择,这样的符号的名字叫inline path operator

其实目前我们遇到的情况,大部分的需求都是查询,元数据是不会被修改的,所以UDPATE的事情,就下回再说吧。

541dabf7b05cc7450fa800d71087fa9f.png

另外,即使是在MYSQL中使用非数组信息,要变成数组也是很简单的

SELECT JSON_ARRAY(date_add(now(), interval 1 day), date_add(now(), interval 2 day), date_add(now(), interval 3 day), date_add(now(), interval 4 day), date_add(now(), interval 5 day)) as array1;

99e2b549f50543bec26dfae8a2a3a85c.png

当然如果想把一堆值,变成 KEY VALUE 也很简单 json_object 也可以帮助你

fdd0452397e7426ce27217d3e4e49e48.png

由于目前这个项目不大,每天的数据流也还OK, 所以选择 MYSQL 8 JSON 的处理方式,但如果数据量大,并且有复杂的查询 聚合,等等,那就要“大芒果” 来解决问题了。

c00b1ac5f55da7e60d2ab5a0fc64f59b.png
7a39965c59e534a5e986b549095616ab.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值