维度建模之代理键
维度表中必须有一个能够唯一标识一行记录的列,通过该列维护维度表与事实表之间的关系,一般在维度表中业务主键符合条件可以当作维度主键。
没有建立代理键时可能存在的问题:
- 当整合多个数据源的维度时,不同数据源的业务主键重复怎么办?
- 涉及维度拉链表时,同一主体多条记录,业务键重复怎么办?
什么是代理键?
代理键是由数据仓库处理过程中产生的、与业务本身无关的、唯一标识维度表中一条记录并充当维度表主键的列,也是描述维度表与事实表关系的纽带,所以在设计有代理键的维度表中,事实表中的关联键是代理键而不是原有的业务主键,既业务关系是靠代理键维护,这样有效避免源系统变化对数仓数据对影响。
在实际业务中,代理键通常是数值型、自增的值,如下图:
如何实现?
-
UDFRowSequence
hive-contrib-xx.jar中包含一个生成记录序号的自定义函数udfrowsequence
add jar hdfs:///path/.../user/hive-contrib-2.0.0.jar;
create temporary function row_sequence as 'org.apache.hadoop.hive.contrib.udf.udfrowsequence';
insert overwrite into dim_goods_d partition(dt='20191204')
select
row_sequence() + ta.max_id,
tb.*
from
tmp_s_inc as tb
cross join (
select
coalesce(max(gid),0) as max_id
from
dim_goods_d
where dt='20191203'
) as ta;
-
row_number()函数
先查询维度表中已有记录最大的代理键值,如果维度表中还没有记录,利用coalesce函数返回0。然后使用cross join连接生成过渡表和最大代理键值的笛卡尔集,最后使用row_number()函数生成行号,并将行号与最大代理键值相加的值,作为新装载记录的代理键。
insert overwrite into dim_goods_d partition(dt='20191204')
select
tb.*,
row_number() over(order by id)+ta.max_id as gid
from
tmp_s_inc as tb
cross join(
select
coalesce(max(gid),0) as max_id
from
dim_goods_d
where dt='20191203'
)ta
union all
select
*
from
dim_goods_d
where dt='20191203'
使用UDFRowSequence实现代理键性能可能会优于row_number()函数实现的代理键。
正文到此结束