簡體   English   中英

如何最好地處理緩慢變化維度(SCD2)中的歷史數據更改

[英]How to best handle historical data changes in a Slowly Changing Dimension (SCD2)

表格:

我工作的公司有一個緩慢變化的維度(員工數據),它已經使用Kimball方法進行了存儲。 包含此數據的維度表具有主鍵( int identity employee_key ,用作其他表中的代理),自然鍵( employee_id ),有效日期范圍( valid_dateinvalid_date )以及跟蹤的各種SCD1和SCD2數據元素時間。 這是一個簡化的例子:

employee_key | employee_id | valid_date | invalid_date | employee_name | employee_role
1            | 1001        | 1/1/2015   | 6/1/2015     | Bob           | DBA
2            | 1001        | 6/2/2015   | NULL         | Bob           | Developer
3            | 1002        | 1/1/2015   | NULL         | Jill          | DBA

在上面的示例中, employee_key是主鍵(代理), employee_id是自然鍵。 其他值應該是自我解釋的。 該表反映出:

  1. Bob是2015年1月1日開始並於2015年6月1日結束的DBA。
  2. Bob於2015年6月2日開始擔任開發人員,現任該職位。
  3. Jill從2015年1月1日開始擔任DBA,現任該職位。

現在,我們還有一系列參考這個維度的事實表。 一個這樣的事實表包含員工記錄的所有時間,並且精細到當天。 我們並不真正關心這些表的結構,只是它們使用代理鍵鏈接到我們的員工維度,它們通常包含很多行(介於10M-200M之間)。 以下是包含時間記錄的事實表的示例:

calendar_dt | employee_id | employee_key | time_code | hours
1/1/2015    | 1001        | 1            | 1234      | 2.25
1/1/2015    | 1001        | 1            | 21        | 3.50
1/2/2015    | 1001        | 1            | 21        | 8.00
...
6/1/2015    | 1001        | 1            | 21        | 4.00  

通過代理鍵employee_key鏈接到員工維度具有重要的業務目的 - 它可以使用BETWEEN運算符實現准確的歷史報告,而無需昂貴的連接。 例如,它讓我們說Bob在2015年6月1日記錄的時間可歸因於他的DBA角色,Bob於2015年6月2日記錄的時間可歸因於他的開發人員角色。

據我所知,這是一個有點標准的Kimball實現。

問題:

該實現不能很好地處理數據的校正。 讓我們說,在我們之前的示例中,人力資源部告訴我們,Bob轉移到分析師的角色,有效的日期范圍是2015年5月1日至2015年6月1日,他們未能將其輸入系統。 這給我們帶來了一個主要問題:我們需要將employee_key = 1的行拆分為兩行,其中有效/無效日期不同。 此外,我們需要找到現在錯誤地引用employee_key = 1並更新它們的所有地方。 以下是問題:

  1. 我們需要在許多巨大的表上運行昂貴的更新操作。 每次需要進行修正時,我們都無法承擔這一責任。
  2. 維度行拆分需要手動完成,使表存在數據輸入錯誤或有效/無效日期范圍重疊的風險。
  3. 拆分行違反了一條重要規則:主鍵是不可變的,一旦分配就不會改變。

解決方案:

我可以想出解決這個問題的方法,但沒有一個是優雅的:

  1. 忍受更新代理關鍵數據的噩夢。 可能會按正常計划強制更正,從而減少運行此更新所需的次數。
  2. 將員工維度表轉換為每個員工每行的表。 這樣做的好處是允許在employee_idcalendar_dt上進行自然鍵連接。 它還使此鍵不可變,並允許識別適當的代理鍵值而無需在維度表中查找它。 無論維度表如何更改,事實表總是引用正確的行。 這具有將100,000行維度表轉換為20M行表的主要缺點。

還有哪些其他解決方案? 我不能成為遇到這個問題的唯一一個......幫助我!

注意事項:

  • 我們假設數據永遠不需要時間元素(粒度將始終在日級別)。
  • 我們假設employee_id值永遠不會改變(是的,我知道這是一個危險的假設)。

您的DW有一個要求:“員工信息可以隨時進行追溯更改”,因此您的DW設計必須適應這一點。

可能有很多方法可以解決這個問題,但是想到的最簡單的方法(以及一個對我來說類似情況的方法)是引入一個新的2類集成表:master_employee_time。 此表將僅使用業務鍵維護原始時間記錄數據的版本化歷史記錄。

employee_time_key | employee_id | valid_date | invalid_date | time date | time code | hours
1                 | 1001        | 1/1/2015   | NULL         | 1/1/2015  | 1234      | 2.25
2                 | 1001        | 1/1/2015   | NULL         | 1/1/2015  | 21        | 3.5
3                 | 1001        | 1/2/2015   | NULL         | 1/2/2015  | 21        | 8

注意:此表可能需要特殊的更新條件,具體取決於您有權訪問的時間表數據,可能會在過去一年中將type2更改為time_dates,然后根據需要手動處理任何舊更新。

擁有此表后,您可以通過將master_employee和master_employee_time組合在一起來重新創建每個加載的當前事實表

insert into fact_employee_time
select
  t.calendar_dt, e.employee_id, e.employee_key, t.time_code, t.hours 
from
  master_employee_time t
  inner join master_employee e on t.employee_id = e.employee_id
where
  --limit to 'current' time recordings
  t.invalid_date is null  
  and
  --get the employee record active for the time recordings day
  e.valid_date <= t.time_date  
  and
  (e.invalid_date is null OR e.invalid_date >t.time_date)

[評論]這也為您提供了能夠更新時間記錄的獎勵,同時為那些不可避免的“為什么我的1月數字已經改變”要求來自那些要求“我必須能夠改變”的人們提供可審計的歷史記錄歷史數據'。 [/評論]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM