1. 程式人生 > >資料倉庫--事實表和維度表

資料倉庫--事實表和維度表

本文主要參考如下幾篇文章:
http://www.cnblogs.com/47613593/archive/2009/02/20/1394581.html
http://jackwxh.blog.51cto.com/2850597/827968

1.資料倉庫與操作型資料庫的區別

資料倉庫的物理模型與常見的操作型資料庫的物理模型有很大不同。最明顯的區別是:操作型資料庫主要是用來支撐即時操作,對資料庫的效能和質量要求都比較高,為了防止“garbage in,garbage out”,通常設計操作型資料庫的都要遵循幾個正規化的約束,除非少數情況下為了效能進行妥協,才可能出現冗餘;而資料倉庫的資料是來源於即時操作產生的資料,而不是直接來源於即時操作,所以它的資料質量是由操作型系統來保證的,而不是由幾個正規化來保證的。而且為了更好的跟蹤歷史資訊,以及更快的產生報表,資料倉庫的物理模型中存在著大量冗餘欄位。

2.事實表與維度表的基本概念

簡單的說維度表就是你觀察該事物的角度(維度);事實表就是你要關注的內容。
比如要分析產品銷售情況, 你可以選擇按產品類別來進行分析,或按時間來分析,這樣的按..分析就構成一個維度。這樣就有兩個維度:產品類別和時間。
下面是兩個維度表結構:
產品維度表:Prod_id, Product_Name, Category, Color, Size, Price
時間維度表:TimeKey, Season, Year, Month, Date

而事實表是資料聚合後依據某個維度生成的結果表,例如:

銷售事實表:Prod_id(引用產品維度表), TimeKey(引用時間維度表), SalesAmount(銷售總量,以貨幣計), Unit(銷售量)

事實資料和維度資料的識別必須依據具體的主題問題而定。“事實表”,用來儲存事實的度量(measure)及指向各個維的外來鍵值。維表用來儲存該維的元資料,即維的描述資訊,包括維的層次及成員類別等

所產生的資料,事實資料表通常包含大量的行。事實資料表的主要特點是包含數字資料(事實),並且這些數字資訊可以彙總,以提供有關單位作為歷史的資料,每個事實資料表包含一個由多個部分組成的索引,該索引包含作為外來鍵的相關性緯度表的主鍵,而維度表包含事實記錄的特性。事實資料表不應該包含描述性的資訊,也不應該包含除數字度量欄位及使事實與緯度表中對應項的相關索引欄位之外的任何資料。 包含在事實資料表中的“度量值”有兩種:一種是可以累計的度量值,另一種是非累計的度量值。最有用的度量值是可累計的度量值,其累計起來的數字是非常有意義的。使用者可以通過累計度量值獲得彙總資訊,例如可以彙總具體時間段內一組商店的特定商品的銷售情況。非累計的度量值也可以用於事實資料表,單彙總結果一般是沒有意義的,例如,在一座大廈的不同位置測量溫度時,如果將大廈中所有不同位置的溫度累加是沒有意義的,但是求平均值是有意義的。 一般來說,一個事實資料表都要和一個或多個緯度表相關聯,使用者在利用事實資料表建立多維資料集時,可以使用一個或多個維度表。 維度表
可以看作是使用者來分析資料的視窗,緯度表中包含事實資料表中事實記錄的特性
,有些特性提供描述性資訊,有些特性指定如何彙總事實資料表資料,以便為分析者提供有用的資訊,維度表包含幫助彙總資料的特性的層次結構。例如,包含產品資訊的維度表通常包含將產品分為食品、飲料、非消費品等若干類的層次結構,這些產品中的每一類進一步多次細分,直到各產品達到最低級別。 在維度表中,每個表都包含獨立於其他維度表的事實特性,例如,客戶維度表包含有關客戶的資料。維度表中的列欄位可以將資訊分為不同層次的結構級。

3.事實表和維度表的設計原則

事實表是用來儲存主題的主幹內容的。以日常的工作量為例,工作量可能具有如下屬性:工作日期,人員,上班時長,加班時長,工作性質,是否外勤,工作內容,稽核人。那麼什麼才是主幹內容?很容易看出上班時長,加班時長是主幹,也就是工作量主題的基本內容,那麼工作日期,人員,工作性質,是否外勤,工作內容是否為主幹資訊呢?認真分析特徵會發現,日期,人員,性質,是否外勤都是可以被分類的,例如日期有年-月-日的層次,人員也有上下級關係,外勤和正常上班也是兩類上班考勤記錄,而上班時長和加班時長則不具有此類意義。所以一般把能夠分類的屬性單獨列出來,成為維度表,在事實表中維護事實與維度的引用關係。

總的來看,和其他建立主外來鍵關係的表也都一樣。但是維度表的建立是需要有層次的(雖然不是必須,但是也是典型特徵),而事實表的建立是針對已經發生的事實的,是歷史資料的存檔,也就是說是不應該修改的。以測試部測試軟體的Bug為例。每個Bug都是一個事實。這個Bug的狀態在資料字典裡可能設計成新建,轉派,修復,拒絕等等。那麼在事實表中Bug表中有一個欄位為Status。當測試員或者開發人員改變了這個狀態的值,事實表中該如何更新呢?是直接更新Status還是什麼其他的方式?顯然,為了能夠追蹤這個Bug的歷史資訊,應該是重新插入一條新的記錄。那麼這和以往的資料庫設計有什麼區別呢?可以看出對於原始記錄和新插入的記錄,其他欄位全部是相同的,也就是全部冗餘的。如果以BugID作為主鍵,這時候會發現主鍵都是冗餘的(當然,插入之前只能刪除主鍵)。所以可以看出,事實表一般是沒有主鍵的。資料的質量完全由業務系統來把握。

維度表一般是有主鍵的,代表該類物質的一個單一個體,其他的欄位一般都是有層次關係的。例如2009年2月19日是主鍵,那麼它會有年--月--日這樣的層次,為了方便統計,年月日不會在做聚合的時候才計算出來,而是在維護記錄時已經計算出來。那麼這些欄位的冗餘是否值得呢?可以這樣解釋:維度表的資料一般是比較少的,這個少是指相對事實表來講的。因為事實表是與日俱增,而維度表則增長緩慢,所以絕對數字也不會太大。假如要做一個group by Year(TimeKey),那麼在事實表和維度表做連線查詢的時候,會產生與事實表一樣大的資料量;如果沒有這些維度表的分層,那麼其一是會增加計算(需要根據時間欄位去取出年份),其二是由於引入了計算,索引會失效。這個代價比引入冗餘欄位要大的多。

維度表的主鍵一般都取整型值的標誌列型別,這樣也是為了節省事實表的儲存空間.