在事實/維度星模式上建構緩慢變化的維度
我聽說過關於如何設計星型模式的教科書定義,關於事實表中的內容和維度表中的內容,例如:
事實表應包含有關對象的核心資訊,維度應包含有關事實的資訊
(轉述)
然而,實際上在業務中,我見過一個星型架構,其中事實表包含一個代理鍵、一個業務鍵和一個對象的所有單值欄位,每個維度儲存一個對象的所有多值欄位(因此單詞維度)。例如,一個人可能是事實表中表示的對象。一個人有一個名字,一個年齡等,這些都在事實表中構成了可行的事實。一個人可能擁有多輛汽車,每輛汽車都有自己的屬性,這些屬性代表一個人的汽車維度,儲存為一個維度表,其中包含多個列來描述每輛汽車的屬性。在這個例子中,這個維度表還包括一個外鍵,表示來自事實表的相應行的業務鍵。
因此,如果我們同意這可能是一個合適的設計,那麼我要解決的問題是如何在多值維度表上執行 SCD 類型 2(歷史)。對於我的充滿單一事實的事實表,這是顯而易見的。我包括兩個額外的列,一個有效日期和到期日期,並且我使用業務密鑰來連結最近記錄具有
NULL
到期日期的公共記錄,並且同一業務密鑰的所有其他歷史記錄都具有有效日期和到期日期指示它們在什麼時間點是最新記錄。如何在表示多值列表的維度上使用相同的概念?我基本上想要同樣的概念,我可以(1)辨識目前列表(在這個例子中,一個人擁有的汽車)和(2)辨識歷史上任何給定時刻的列表是什麼。我可以在每個維度值上設置一個有效和到期日期嗎?那麼我如何區分一段時間後添加的值呢?還是刪除值?
但是,如果我們不同意這種設計方法,請告訴我什麼是行業標準,這樣我才能正確地做到這一點。
通常,維度表包含所有欄位的單個有效時間(開始和結束日期),並且 SCD2 將應用於完整記錄。最好提前使用非空結束值來標記目前有效的記錄,因為這樣可以簡化查詢。過去的結束日期表示刪除或您定義的任何其他語義(如人離開國家或不再受僱)。還將代理鍵添加到維度表以唯一標識記錄。
事實表通常包含諸如銷售或成本之類的“度量”,或者表示諸如已撥電話或這些電話的持續時間之類的事件。人們通常會在報告中對這些列使用聚合。
星型模式是一種對人口稀少的“立方體”進行建模的方法,其中座標系的每個軸由一個維度表給出。使用此模型,報表中的“切片和切塊”操作和“向上鑽取/向下鑽取”操作可以很好地轉換為 SQL。
在您的汽車和人員範例中,我將使用兩個維度表,一個用於汽車,一個用於人,每個都具有歷史記錄(根據 SCD2),以及一個包含維度表外鍵的無事實事實表,引用各自的標識符(實體標識符) 和有效時間列 (SCD2)。在此設計中,如果其中一個維度表發生更改,您將不會根據 SCD2 規則在事實表中添加記錄。
通過這種方式,您可以對每個實體的變化進行建模,例如人的姓名變化、汽車的顏色變化以及汽車與人之間的關係,例如所有權。每個表將使用每個業務鍵的非重疊有效時間(開始和結束值),獨立記錄這些實體的歷史。該模型中的事實表基本上是 am:n 連結表,其中保留了單獨的有效時間歷史記錄。
您可以通過
x between start and end
在每個表上使用目前(或過去)查詢來辨識目前和過去的列表(回答您的 (1) 和 (2) - 忽略間隔是右開還是左開)。匯總統計數據,例如我們在某個具有完整歷史的城市(假設城市是人員維度表的一部分)擁有多少汽車,現在可以使用時間連接和“排序”查詢來回答,這些查詢有時也稱為“合併”查詢,見Snodgrass,第 6.3 章ff