来源:安瑞哥是码农
上上篇文章实测了 Clickhouse(下称CK) 的 variant 数据类型,上篇文章又升级了我的 Doris 集群到 2.1.2,那么这一篇,怎么着也该轮到测试 Doris 的 variant 了。
从官网介绍来看,虽然同为 variant,且都只出现在高版本身上,但 Doris 跟 CK 对它的场景期望,似乎并不太一样。
CK: 拿它存储除 json 之外的所有其他数据类型,比如字符串、数值、array、map 等等;
Doris:也可以用来存储各种数据库支持的类型,但有一点跟 CK 正好相反,它更建议你用它存储 json 数据。
那么这一次,咱就用 Doris 的 variant type 针对同一份需求数据,对比 CK 的 json type,看在功能的使用上,两者的差异如何。
0. 理论准备
从官网对 variant 的介绍来看,虽然这个数据类型的定义,跟 CK 是一样的,代表了多种不同数据库类型的合集,
但 Doris 主推用它来存储 json,我猜是为了一雪它之前 json type 拉胯的前耻。
1. 往 Doris 表灌数据
公平起见,这里往 Doris 的 variant 写入的数据,跟之前写 CK 的 json 保持一致(数据量略有差异)。
写入 Doris 的建表语句:
CREATE TABLE `domain_whois_variant` (
`domain` VARCHAR(100) ,
`detail_json` VARIANT,
`create_time` DATETIME
)UNIQUE KEY(`domain`)
DISTRIBUTED BY HASH(`domain`) BUCKETS 3
PROPERTIES (
"replication_allocation" = "tag.location.default: 1"
);
写入后的数据量:
2. Doris 跟 CK 对比
2.1 字段结构对比
数据写入之后,根据官网的介绍,variant 会自动把 json 中的 key 提取出来作为新字段。
Doris 表结构:
写入 json 后 Doris 的表字段结构
注意,这里想要看到被展开的字段,你必须得先把这个「显示扩展列」的开关打开,然后,你就可以看到从 json 里面拉出来的扩展列。
CK 的数据存储结构:
跟 Doris 不一样的是,对于 CK 来说,它的表字段结构不变,但提取出来的 json key(包括子key),是直接显示在数据里面的:
写入 json 后 CK 的 json 类型列数据
2.2 查询方式对比
Doris 的普通查询
从上面列扩展后的 Doris 表结构来看,对于 json 中 key 的查询方式应该非常明了才对.
比如扩展后的字段有 detail_json.code, 那么以正常的思维习惯,你应该可以用 select detail_json.code from... 才对。
但是人家似乎并不按常理出牌。
你得把 detail_json.code 改为 detail_json['code'] ,而且在这么用之前,你还得把下面这个开关打开:
再查:
才能查出对应的结果。
CK 的普通查询
相比 Doris,CK 对存储为 json 类型的查询方式就直接很多,同样的字段,它就可以这么来查:
接下来,再来看看相同的 json 内部的字段,聚合查询该怎么来玩?
Doris 的聚合查询
既然在数据写入的时候,已经把 json 中的 key 作为独立字段存储了,那么按照正常的思维理解,拿它进行聚合查询,应该跟普通字段的玩法一样才对。
但事实证明,它好像并不正常。
看到这个抛出来的异常,让一脸懵逼的我,一脸懵逼。
指望这个报错提示来解决问题是不太可能了,幸好,官网给了案例,得这么来查:
你必须要把这个 json 内部字段先 cast 成一个具体的类型,才可以,就问你,膈应不膈应?
CK 的聚合查询
同样的聚合请求,来到 CK 这边,看是什么样的(忽略查询结果的不一样,因为数据量不一样):
怎么样?跟 Doris 比,你更中意哪个?
2.3 其他区别
此外,在这次对比中,还发现了另外一个 Doris 跟 CK 的区别,那就是 Doris 的 variant 对复杂一点的 json 识别能力,暂时还不够。
来,为了清楚说明这个问题,先看一眼我这次测试用的 json 数据长什么样:
可以明显地看到,这个 json 中的 data 这个 key,它对应的 value,是一个 json array。
那么如果这个时候,我想对 data 对应的value, 里面的 registrant_address 这个 key 进行聚合查询,Doris 跟 CK 该分别用什么办法呢?
先看 CK
查询语句可以直接这么来写:
简单直接。
对于 Doris
从前面的 desc table_name 的显示结果可以看出来,根本就没有看到 data 对应 value 里面的任何 key,也就是说,对于这个 json 数的「key 中 key」内容,Doris 没有对它进行额外的存储。
所以,如果你强行这么来查询,虽然查询语句也不会报错
但是从结果来看,很明显不对。
说明什么?
是不是就说明 Doris 的 variant,对于 key 对应的 value 为 json array 的复杂 json 数据来说,其中嵌套的 json array 中的子 key 就识别不了了,而相比之下 CK 的 json type,就可以。
最后
从这次对 Doris 的 variant type 实测表现来看,依然没有达到我当前需求场景下,对 json 的查询要求,虽然它确实可以有效的处理 json 数据,但,也仅限于结构简单的 json。
相比之下,同样是用来解决 json 查询问题,CK 的 json type 虽然在之前测试时发现有 bug,但它表现出来的功能,在这次对比下,个人会觉得比 Doris 的 variant 更优(凡事就怕对比)。
那么对于这次 Doris 的 variant type 跟 CK json type 的表现,你怎么看?