Doris 的 variant 对比 CK 的 json,谁更优?

来源:安瑞哥是码农


上上篇文章实测了 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 的表现,你怎么看?


请使用浏览器的分享功能分享到微信等