次元モデリングのゆっくりと変化する次元

次元モデリングのゆっくりと変化する次元

OLTPビジネスデータベースからDWデータウェアハウスにデータを抽出するプロセス、特に最初のインポート後のすべての増分抽出では、次のような問題が発生することがよくあります。ビジネスデータベースの一部のデータが変更されているかどうか、変更するかどうか。データウェアハウスにも反映されていますか?データウェアハウスで、どのデータを変更する必要があり、どのデータを変更できないのですか?これらの変更を考慮して、データウェアハウスのディメンションテーブルは、これらのニーズを満たすようにどのように設計する必要がありますか?

  1. 現在のデータの完全なスナップショットデータを毎日保存します。このソリューションは、少量のデータを含むディメンションに適しており、簡単な方法で履歴状態を保存します。

  2. キー属性値の履歴フィールドをディメンションテーブルに追加し、以前のステータス値のみを保持します

  3. ジッパーテーブル

遅い勾配寸法とは何ですか?

ディメンションデータは時間の経過とともに変化し、変化の速度は比較的遅いです。この種のディメンションデータは通常、ゆっくりと変化するディメンションと呼ばれます。データウェアハウスは履歴の変更、特に一部の重要なデータを追跡する必要があるため、履歴の状態も取得する必要があります。特定の対策。保存します。

たとえば、顧客の連絡先情報、携帯電話番号、およびその他の情報は、顧客の場所の変更に伴って変更される場合があります。たとえば、商品の価格は、さまざまな期間で増減します。その後、ビジネスデータベースで自然に変更され、すぐに実際のビジネスに反映されます。ただし、データウェアハウスでは、データの主な特徴は静的な履歴データ、変更が少なく削除がないこと、定期的に増加することであり、その機能は主にデータ分析に使用されます。

ジッパーテーブル

データが変更されると、古いデータは無効になり、変更されたデータは新しいレコードとしてディメンションテーブルに挿入され、有効になり始めます。これにより、特定の粒度でのデータの変更履歴を記録できます。

寸法ジッパーテーブル:

次のように:

ここに画像の説明を挿入
その中で、start_dateは有効時間であり、end_dateは有効期限です。次のように有効なデータをクエリします

Select * from user where start_date<= 2018-05-22 and end_date>= 2018-05-22

ディメンションテーブルはジッパー式であるため、同じディメンションエンティティに複数のレコードが存在する必要があります。現時点では、ディメンションテーブルのアトミック主キーは存在しません。代理キー追加する方法を使用して、ディメンションテーブルとファクトテーブル。

ファクトテーブルの読み込み代理キー(遅いグラデーションディメンションを含む)

順序ファクトテーブルとユーザーディメンションテーブル(代理キーを含む)は次のとおりです。ファクトテーブルの
ここに画像の説明を挿入
履歴ユーザー​​ディメンションIDは変更されないため、ファクトテーブルの代理キーの読み込みは新しく追加されたデータでのみ発生します。

-- 事实表装载代理键
select 
    ta.*,
    tb.uid
from 
    fact_order as ta
join (
    select 
        *
    from
        dim_user as tb
    where '${bizDate}' >= start_date and '${bizDate}' <= end_date
) as tb 
on ta.id = tb.id

注意:
${bizDate}为时间限定,每天增量表可取到当天。如20191204...

代理键是维度建模中极力推荐的方式,它的应用能有效的隔离源端变化带来的数仓结构不稳定问题,同时也能够提高数据检索性能但是如所见,代理键维护代价非常高,尤其是数据装载过程中,对事实表带来了较大的影响,在基于hive的数据仓库建设影响更加严重,比如代理键的生成、事实表中关联键的装载、不支持非等值关联等问题,带来ETL过程更加复杂故,在大数据体系下,谨慎使用代理键,同时对于缓慢渐变维场景,可以考虑用空间换取时间,每天保留维表全量快照;但这样会带来存储成本,根据实际情况衡量

事実ジッパーテーブル:

ファクトテーブルのデータ量が多いが、データがゆっくりと変化している場合は、履歴状態を追跡する必要があります。遅い勾配ディメンションと同様に、ファクトジッパーテーブルを使用する必要があります。

たとえば、クレジットカードのシナリオでは、ユーザーの与信限度額と使用限度額の変更が遅いため、変更の記録を追跡し、関連するファクトテーブルを設計する必要があります。

ソースデータには(credit_amount)が含まれます:ユーザーID、カードID、クォータ、使用済みクォータ、残りのクォータ、作成時間、更新時間

  • インクリメンタルファクトジッパーテーブル

    -- 伪代码仅供参考
    -- 1.增量采集数据
    insert into s_credit_amount
    select 
        *
    from  credit_amount
        where updated_time>='2019-12-01 00:00:00'
    -- 2.dwd层拉链表设计 d_credit_amount_l(l表示拉链表)
    drop table if exists tmp_credit_amount;
    create table tmp_credit_amount as 
    select 
        *
    from (
        select
            ta.card_id, -- 卡ID
            ta.user_id, -- 用户ID
            ta.amount, -- 额度
            ta.used_amount, -- 已用额度
            ta.created_time, -- 创建时间
            ta.updated_time, -- 更新时间
            ta.start_date, -- 拉链表(开始时间)
            (
             case 
                when tb.card_id is not null and ta.end_date>'2018-06-01' then '2018-05-31' 
                else ta.end_date 
             end
            ) as end_date, -- 拉链表(失效时间)
            load_time -- 方便排查问题
        from
            d_credit_amount_l as ta
        left join
        		s_credit_amount as tb
        on ta.card_id=tb.card_id
    
        union all -- union 发生变化的数据
    
        select 
            ta.card_id, -- 卡ID
            ta.user_id, -- 用户ID
            ta.amount, -- 额度
            ta.used_amount, -- 已用额度
            ta.created_time, -- 创建时间
            ta.updated_time, -- 更新时间
            '2019-10-04' as start_date, -- 拉链表(开始时间)
            '9999-12-31' as end_date, -- 拉链表(失效时间)
            unix_timestamp() as load_time  -- 数据生成时间
        from
            s_credit_amount as ta
    )tmp
    
    insert overwrite into d_credit_amount_l
    select * from tmp_credit_amount;
    
    备注:
    	首先查询增量数据中变化的数据更改end_date置为失效状态,再union关联新增数据。
    	
    
  • フルファクトジッパーテーブル

    -- 伪代码仅供参考
    select
        ta.*
    from(
        select
            ta.card_id,
            ta.user_id,
            ta.amount,
            ta.used_amount,
            ta.created_time,-- 捕获数据变化
            md5(concat(card_id,user_id,amount,used_amount,created_time)) as md5_flag
        from 
            d_credit_amount_d as ta 
        where dt='2019-12-05'
        )ta
    left join(
        select
            ta.card_id,
            ta.user_id,
            ta.amount,
            ta.used_amount,
            ta.created_time,
            md5_flag
        from 
            d_credit_amount_d as ta 
        where dt='2019-12-04'
        )tb
    on ta.card_id=tb.card_id
    where ta.md5!=tb.md5 or tb.card_id is null
    
    备注:
    	可以根据重要属性,进行md5加密确认唯一一条数据(可根据MD5判断改变数据)

    公式アカウントに注意を払い数据工匠记、ビッグデータ分野のオフラインおよびリアルタイムのテクニカル乾物に焦点を当てて定期的に共有してください!個人のウェブサイトwww.lllpan.top
    ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/lp284558195/article/details/112267996