原创

维度建模之代理键

维度表中必须有一个能够唯一标识一行记录的列,通过该列维护维度表与事实表之间的关系,一般在维度表中业务主键符合条件可以当作维度主键。

没有建立代理键时可能存在的问题:

  1. 当整合多个数据源的维度时,不同数据源的业务主键重复怎么办?
  2. 涉及维度拉链表时,同一主体多条记录,业务键重复怎么办?

什么是代理键?

代理键是由数据仓库处理过程中产生的、与业务本身无关的、唯一标识维度表中一条记录并充当维度表主键的列,也是描述维度表与事实表关系的纽带,所以在设计有代理键的维度表中,事实表中的关联键是代理键而不是原有的业务主键,既业务关系是靠代理键维护,这样有效避免源系统变化对数仓数据对影响。

在实际业务中,代理键通常是数值型、自增的值,如下图:

如何实现?

  • 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),0as 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),0as max_id 
    from 
        dim_goods_d 
    where dt='20191203'
)ta
union all
select 
    *
from 
    dim_goods_d 
where dt='20191203'

使用UDFRowSequence实现代理键性能可能会优于row_number()函数实现的代理键。

正文到此结束
本文目录