Database-Design

我對事實表粒度的理解是否正確?

  • October 22, 2014

我和我們公司的另一位 DBA 的任務是審查供應商為我們開發的數據庫設計。供應商表示他們使用 Kimball 作為他們設計的基礎。(注意:我不是在尋找 Kimball 與 Inmon 等的論點。)他們設計了一個具有多個事實和維度的集市。

現在平心而論,我們公司從來沒有設計過一個市場。我們一直讓顧問來做這件事。而且我們從來沒有被派去上課或其他任何事情。所以我們對倉儲/集市/維度建模等方面的知識是基於我們所擁有的一些經驗,我們可以在網際網路上找到的,以及自學(我們有 Inmon 和 Kimball 的書,並且正在努力通過它們) .

現在舞台已經為我的知識水平做好了準備,我們來迎接設計挑戰。

有一個名為“索賠損失統計”的事實表(這是用於保險的)。他們正試圖獲取索賠的付款(累積到每月的水平),然後是準備金中的錢(有點像索賠的銀行賬戶)。他們希望看到每月的付款金額(沒什麼大不了的)。但他們希望看到準備金的賬戶目前餘額。

我舉個形象的例子。

假設我們為索賠設置了 1000 美元的準備金。這被擱置一旁(所以在某些方面它的功能有點像銀行賬戶)。

2014 年 10 月,我們還沒有支付任何費用。因此,企業希望在 10 月底看到付款和準備金餘額。

-----------------------------------------------
-  MONTH_YEAR  -  PAYMENTS -  RESERVE_BALANCE -
-----------------------------------------------
-      102014  -      0.00 -          1000.00 -
-----------------------------------------------

然後十一月來了。我們支付 $ 100, $ 150 美元和 75 美元。他們希望看到這些合計金額和余額中的準備金如下:

-----------------------------------------------
-  MONTH_YEAR  -  PAYMENTS -  RESERVE_BALANCE -
-----------------------------------------------
-      102014  -      0.00 -          1000.00 -
-----------------------------------------------
-      112014  -    325.00 -           675.00 -
-----------------------------------------------

然後說我們在 12 月的付款為零,然後在明年 1 月再增加 200 美元。

-----------------------------------------------
-  MONTH_YEAR  -  PAYMENTS -  RESERVE_BALANCE -
-----------------------------------------------
-      102014  -      0.00 -          1000.00 -
-----------------------------------------------
-      112014  -    325.00 -           675.00 -
-----------------------------------------------
-      122014  -      0.00 -           675.00 -
-----------------------------------------------
-       12015  -    200.00 -           475.00 -
-----------------------------------------------

這是我掙扎的地方。我的理解是付款部分是正確的。它們都在每個記錄中按月匯總。因此,如果您需要年度、季度等,您可以進一步匯總。

但儲備金額不同。這是一種平衡。企業希望查看每個月的餘額有多少。但是您不能在此欄位上進行聚合。如果你這樣做了,你會得到一些不穩定的結果。

不知何故,這讓我覺得是錯誤的。但我不能如實說我已經建模足夠多或知道足夠多。我只能說我知道的。據我所知,Fact 中的所有值都應該具有相同的粒度。

這兩個數字都處於“月份”的相同粒度,但它們不是從它們所代表的角度來看。一個是一個月內的總美元。另一個只是平衡。

它是否正確?我一直在反對這個設計。我這樣做有錯嗎?實際上可以這樣做嗎?或者我對糟糕設計的“程式碼氣味”感覺是否準確?

任何幫助,將不勝感激。注意:請不要只說“應該是 X 方式”,請解釋為什麼應該這樣,以便我可以從中學習。

編輯:嗯,我了解到我對事實的初步理解是錯誤的。粒度不是每月一次。粒度是事務級別。所以這意味著在 MONTH_YEAR(即實際上是財務報告期)內將有多個付款和恢復交易。這些將按日期或交易日期發布。但由於業務部門看到的先前報告,以及數據如何儲存在遺留系統中,他們希望同時放置交易數據(每行一行)和儲備月結餘額(每月一行)。

一旦我了解到這一點,我意識到問題不在於添加劑與非添加劑,甚至是半添加劑,因為它是穀物,這是我從一開始就懷疑的。我們的 DBA 團隊與項目團隊討論了這個問題,並報告說他們試圖將兩種不同的顆粒放在同一個事實中,這是不正確的。他們應該將交易提高到每月的水平,然後讓他們獲得付款、回收和每月儲備餘額(即半附加事實),因為一切都將按月進行。或者他們需要找到一種方法將儲備餘額分解為交易以保留交易級別的粒度。或者他們需要將事實分解為兩個事實。一個可以是準備金餘額的每月級別。另一個可以在支付和恢復的交易級別。(沒有理由他們也不能將付款和追償放在每月水平的事實中。這取決於業務需求。)

鑑於我所學到的,我會將托馬斯的答案標記為正確答案。但是,我覺得我從原始問題開始的討論仍然值得其他人學習,因此我將保留問題的原始部分。我還打算獎勵 nikadam 的回答,因為它教會了我很多關於加法、非加法和半加法事實的知識,並糾正了 我對維度建模的許多誤解。

你對程式碼氣味的直覺是很好的磨練。

您正在處理的reserves 是 Kimball 所說的“半加法事實”。它不能很好地匯總到季度或年度。

對此的典型解決方案是有兩個事實表,一個用於附加事實(payments在您的情況下),另一個用於非附加事實。非加法事實實際上並不需要在月級別上有顆粒,您可以將它們一直儲存到當天,事情仍然可以正常工作。

非加法事實 ,reserve的查詢方式與其他事實不同。您需要做出一項業務決策:reserve年度級別意味著什麼?是一年中的最後一個月,還是一年中月份的平均值?無論您做出何種選擇,您都可以在 Kimball 書籍中關於非加性事實的章節下找到對此建模的解決方案。

請注意,如果您使用像 Analysis Services 這樣的多維數據集產品,即使您將聚合全部儲存在一個表中,聚合也可能“正常工作”。但是,我更喜歡將事物分開,這樣關係查詢更容易編寫(而且事實也更容易載入)。

引用自:https://dba.stackexchange.com/questions/77402