上一篇:
Doris画像存储系列一(https://editor.csdn.net/md/?articleId=120416295)
六、画像宽表+bitmap倒排表
重复一下bitmap倒排表的优点和缺点
标签类型 | 标签值 | user_ids |
---|---|---|
性别 | 男 | 1,2 |
性别 | 发 | 3 |
优点:
- doris bitmap聚合表在对做用户画像群体计算时很友好,交集/并集/差集
- 因为数据是聚合存储,因此数据量少,性能也特别好
缺点:
- 当我希望分页查询用户画像/自定义画像字段排序时特别麻烦
- 当我希望做流式计算做实时标签时,无法按照单个用户进行标签的删改
因此目前又有了一个新的技术方案:
“画像宽表” + bitmap倒排表方案,在方案五
的时候使用的是"画像窄表"+bitmap倒排表方案,因为早期Doris只能支持整行更新,而无法实现某表某列的单独操作,现在呢已经可以实现了,具体方案如下:
通过doris聚合模型+REPLACE_IF_NOT_NULL 聚合函数实现
表创建结构如下
CREATE TABLE `tdm_user_tag` (`user_id` int(11) NULL COMMENT '用户ID',`sex` varchar(20) REPLACE_IF_NOT_NULL NULL COMMENT '性别',`age` varchar(20) REPLACE_IF_NOT_NULL NULL COMMENT '年龄段',`id_number` int(11) REPLACE_IF_NOT_NULL NULL COMMENT '身份证号'
) ENGINE = OLAP AGGREGATE KEY(`user_id`) COMMENT '用户标签表' DISTRIBUTED BY HASH(`month`) BUCKETS 8 PROPERTIES ("replication_allocation" = "tag.location.default: 3","in_memory" = "false","storage_format" = "V2","disable_auto_compaction" = "false"
);
标签数据操作如下:
insert into tdm_user_tag(user_id,sex)values("1","男")("2","女");
insert into tdm_user_tag(user_id,age)values("1","90后");
insert into tdm_user_tag(user_id,id_number)values("1","1111111");
insert into tdm_user_tag(user_id,likes)values("1","钓鱼,看戏");
数据结果如下:
id | sex | age | id_number | likes |
---|---|---|---|---|
1 | 男 | 90后 | 1111111 | 钓鱼,看戏 |
2 | 女 |
说明:
REPLACE_IF_NOT_NULL
聚合函数,能够实现插入时忽略空值,也就可以实现一次操作某一列数据,也因为每个画像值的计算逻辑是不同的,所以也就和上面的例子一样,一条SQL对应一个画像,一个画像对应一个计算逻辑,一次操作一列数据- 基于这样的宽表数据,实现排序,分页,自定义组合检索都是非常好的
- 同时也兼顾了类似于身份证号类别不适合定义为标签的字段
- 补充一点说明,有的画像是多值的,在上面的例子中使用逗号分隔多个标签值,Doris提供函数
find_in_set
函数,能够匹配出是否包含某个画像值,如:
-- 查看命中"看戏"爱好的人有哪些
select * from tdm_user_tag where find_in_set("看戏",likes) > 0
- 到目前为止,doris依然对单条插入不友好和推荐,上面只是例子表示可以实现某一例的操作,正常应该是批量操作的,如:
-- 通过用户表的信息生成画像信息
insert into tdm_user_tag(user_id,sex) select user_id,sex from user_info
- 一般数据量不大的情况下,只需要
"画像宽表"
就可以了,如果涉及大量的如画像群体的交并集查询等操作,此时再建立"bitmap倒排表"
不迟,定时将"画像宽表"
数据写入到"bitmap倒排表"
中