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');
这样就可以使用拉链表,用开始日期和结束日期来展现用户这段信息持续的状态,
基数太大,而且变化并不太多,因此保存全部数据消耗的资源并没有显现出特别大的意义,感觉浪费资源了
这里注意一下,这里拉链表用状态的结束时间来分区,因为开始时间并不能表现状态的结束和真正的持续结束时间。
每天的拉链表
和最新的拉链表
因为最新状态的结束时间并不确定,为了避免一天一修改的麻烦,直接将最新状态的结束时间设定为一个不可到达的值,这里设置为9999-12-31.
也就是说,每天的拉链表和9999-12-31
因为是按结束时间进行分区,则每天保存的,就是当天结束的状态,或者说,
对于插入,直接将数据添加到9999,
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