次元モデリングのゆっくりと変化する次元
OLTPビジネスデータベースからDWデータウェアハウスにデータを抽出するプロセス、特に最初のインポート後のすべての増分抽出では、次のような問題が発生することがよくあります。ビジネスデータベースの一部のデータが変更されているかどうか、変更するかどうか。データウェアハウスにも反映されていますか?データウェアハウスで、どのデータを変更する必要があり、どのデータを変更できないのですか?これらの変更を考慮して、データウェアハウスのディメンションテーブルは、これらのニーズを満たすようにどのように設計する必要がありますか?
現在のデータの完全なスナップショットデータを毎日保存します。このソリューションは、少量のデータを含むディメンションに適しており、簡単な方法で履歴状態を保存します。
キー属性値の履歴フィールドをディメンションテーブルに追加し、以前のステータス値のみを保持します
ジッパーテーブル
遅い勾配寸法とは何ですか?
ディメンションデータは時間の経過とともに変化し、変化の速度は比較的遅いです。この種のディメンションデータは通常、ゆっくりと変化するディメンションと呼ばれます。データウェアハウスは履歴の変更、特に一部の重要なデータを追跡する必要があるため、履歴の状態も取得する必要があります。特定の対策。保存します。
たとえば、顧客の連絡先情報、携帯電話番号、およびその他の情報は、顧客の場所の変更に伴って変更される場合があります。たとえば、商品の価格は、さまざまな期間で増減します。その後、ビジネスデータベースで自然に変更され、すぐに実際のビジネスに反映されます。ただし、データウェアハウスでは、データの主な特徴は静的な履歴データ、変更が少なく削除がないこと、定期的に増加することであり、その機能は主にデータ分析に使用されます。
ジッパーテーブル
データが変更されると、古いデータは無効になり、変更されたデータは新しいレコードとしてディメンションテーブルに挿入され、有効になり始めます。これにより、特定の粒度でのデータの変更履歴を記録できます。
寸法ジッパーテーブル:
次のように:
その中で、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