1.用户维度表的模型
DROP TABLE IF EXISTS dim_user_zip;
CREATE EXTERNAL TABLE dim_user_zip
(
`id` STRING COMMENT '用户ID',
`name` STRING COMMENT '用户姓名',
`phone_num` STRING COMMENT '手机号码',
`email` STRING COMMENT '邮箱',
`user_level` STRING COMMENT '用户等级',
`birthday` STRING COMMENT '生日',
`gender` STRING COMMENT '性别',
`create_time` STRING COMMENT '创建时间',
`operate_time` STRING COMMENT '操作时间',
`start_date` STRING COMMENT '开始日期',
`end_date` STRING COMMENT '结束日期'
) COMMENT '用户维度表'
PARTITIONED BY (`dt` STRING)
STORED AS ORC
LOCATION '/warehouse/gmall/dim/dim_user_zip/'
TBLPROPERTIES ('orc.compress' = 'snappy');
2.解析表存储
1. 用户表的选型及理由
1.用户表的特点:
- 基数大
- 变化少,注意,一般是不存在物理删除的,删除只是状态的修改,因此变化为insert 和update
2.选型
这样就可以使用拉链表,用开始日期和结束日期来展现用户这段信息持续的状态,
基数太大,而且变化并不太多,因此保存全部数据消耗的资源并没有显现出特别大的意义,感觉浪费资源了
3.拉链表如何变化的?
1.拉链表的存储
这里注意一下,这里拉链表用状态的结束时间来分区,因为开始时间并不能表现状态的结束和真正的持续结束时间。
2.拉链表都有哪些?
每天的拉链表
和最新的拉链表
因为最新状态的结束时间并不确定,为了避免一天一修改的麻烦,直接将最新状态的结束时间设定为一个不可到达的值,这里设置为9999-12-31.
也就是说,每天的拉链表和9999-12-31
因为是按结束时间进行分区,则每天保存的,就是当天结束的状态,或者说,
3.对插入(注册)的想法是什么?
对于插入,直接将数据添加到9999,
4.对更新的想法是什么?
- 一个用户一次更新:将原来的状态结束日期修改为前一天(其实当天也行,看怎么理解了),最新的结束日期修改为9999,也就是说,最新状态由今天开始
- 一个用户多次更新:通过ODS中的用户增量表的ts来区分更新顺序,只保留最新的,按一次修改进行。
select
`id` ,--STRING COMMENT '用户ID',
`name` ,--STRING COMMENT '用户姓名',
`phone_num` ,--STRING COMMENT '手机号码',
`email` ,--STRING COMMENT '邮箱',
`user_level` ,--STRING COMMENT '用户等级',
`birthday` ,--STRING COMMENT '生日',
`gender` ,--STRING COMMENT '性别',
`create_time` ,--STRING COMMENT '创建时间',
`operate_time` ,--STRING COMMENT '操作时间',
`start_date` ,--STRING COMMENT '开始日期',
`end_date` --STRING COMMENT '结束日期'
from dim_user_zip
where dt = '9999-12-31'
union
select
`id` ,--STRING COMMENT '用户ID',
`name` ,--STRING COMMENT '用户姓名',
`phone_num` ,--STRING COMMENT '手机号码',
`email` ,--STRING COMMENT '邮箱',
`user_level` ,--STRING COMMENT '用户等级',
`birthday` ,--STRING COMMENT '生日',
`gender` ,--STRING COMMENT '性别',
`create_time` ,--STRING COMMENT '创建时间',
`operate_time` ,--STRING COMMENT '操作时间',
'2022-06-09' start_date,
'9999-12-31' end_date
from (
select
data.`id` ,--STRING COMMENT '用户ID',
data.`name` ,--STRING COMMENT '用户姓名',
data.`phone_num` ,--STRING COMMENT '手机号码',
data.`email` ,--STRING COMMENT '邮箱',
data.`user_level` ,--STRING COMMENT '用户等级',
data.`birthday` ,--STRING COMMENT '生日',
data.`gender` ,--STRING COMMENT '性别',
data.`create_time` ,--STRING COMMENT '创建时间',
data.`operate_time` ,--STRING COMMENT '操作时间',
row_number() over ( partition by data.id order by ts desc ) r
from ods_user_info_inc
where dt = '2022-06-09'
and type = 'insert' or type = 'update' ) t0 where r = 1