分区存储
如果将用户标签开发成一张大的宽表,在这张宽表下放几十种类型标签,那么每天该用户画像宽表的ETL作业将会花费很长时间,而且不便于向这张宽表中新增标签类型。 要解决这种ETL花费时间较长的问题,可以从以下几个方面着手:
·将数据分区存储,分别执行作业;
·标签脚本性能调优;
·基于一些标签共同的数据来源开发中间表。
下面介绍一种用户标签分表、分区存储的解决方案。
根据标签指标体系的人口属性、行为属性、用户消费、风险控制、社交属性等维度分别建立对应的标签表进行分表存储对应的标签数据。如图3-3所示。
·人口属性表:dw.userprofifile_attritube_all;
·行为属性表:dw.userprofifile_action_all;
·用户消费表:dw.userprofifile_consume_all;
·风险控制表:dw.userprofifile_riskmanage_all;
·社交属性表:dw.userprofifile_social_all
图3-3 用户标签数据ETL逻辑示意图
例如创建用户的人口属性宽表:
同样的,用户其他id维度(如cookieid、deviceid、registerid 等)的标签数据存储,也可以使用上面案例中的表结构。
在上面的创建中通过设立人口属性维度的宽表开发相关的用户标签,为了提高数据的插入和查询效率,在Hive中可以使用分区表的方式,将数据存储在不同的目录中。在Hive使用select查询时一般会扫描整个表中所有数据,将会花费很多时间扫描不是当前要查询的数据,为了扫描表中关心的一部分数据,在建表时引入了partition的概念。在查询时,可以通过Hive的分区机制来控制一次遍历的数据量。
标签汇聚
在上面的案例中,用户的每个标签都插入到相应的分区下面, 但是对一个用户来说,打在他身上的全部标签存储在不同的分区下面。为了方便分析和查询,需要将用户身上的标签做聚合处理。紧接上面的案例,下面讲解标签汇聚的开发案例(见图3-4)。
标签汇聚后将一个用户身上的每个全量标签汇聚到一个字段中, 表结构设计如下:
CREATE TABLE `dw.userprofile_userlabel_map_all`(
`userid` string COMMENT 'userid',
`userlabels` map<string,string> COMMENT 'tagsmap',)
COMMENT 'userid 用户标签汇聚'
PARTITIONED BY ( `data_date` string COMMENT '数据日期')
图3-4 标签汇聚数据
开发udf函数“cast_to_json”将用户身上的标签汇聚成json字符串,执行命令将按分区存储的标签进行汇聚:
insert overwrite table dw.userprofile_userlabel_map_all
partition(data_date= "data_date")
select userid,
cast_to_json(concat_ws(',',collect_set(concat(labelid,':',labelweight))))
as userlabels
from “用户各维度的标签表”
where data_date= " data_date "
group by userid
汇聚后用户标签的存储格式如图3-5所示
图3-5 标签汇聚数据
将用户身上的标签进行聚合便于查询和计算。例如,在画像产品中,输入用户id后通过直接查询该表,解析标签id和对应的标签权重后,即可在前端展示该用户的相关信息(如图3-6所示)。
图3-6 用户标签查询








暂无数据