數據倉庫是數據的倉庫,數據是從操作型數據庫系統中獲取,經過集成處理、按照合適的粒度進行聚合而成的數據的集合。 構建數據倉庫,要從數據模型、數據集成、粒度設計和分區設計這四個方面着手,迭代式開發。
一,數據模型
在設計數據倉庫之前,首先要了解操作型數據庫的數據模型,數據模型分為三個層次:
- ERD(實體關系圖)是最頂層的概念模型,是實體關系的高度抽象,主要用於確定各個實體(或主題)及其之間的關系;
- 中間層是數據集成(DIS),用於對主要數據分組,設置數據的鏈接,確定主鍵、屬性和關系;
- 底層是物理模型,用於設計SQL Server的關系表,在這一層上,確定數據的粒度、對數據進行分區、定義引用、創建索引等
1,實體關系圖(ERD)
實體關系圖是數據之間關系的高度抽象,直接定義了數據模型中的實體(主題)和實體之間的關系,用於理解數據模型中涵蓋的主題
2,數據集成(DIS)
對實體-關系模型中標識出的每一個主題或實體,都要建立一個DIS模型,
數據集成模型基本上由三部分構成:
- 主要數據分組:每個主題或實體有且只有一個主要數據分組,例如,客戶是一個主要數據分組,有客戶ID這個唯一標識。
- 二級數據分組:實體的額外屬性,例如,客戶的居住地址
- 連接器:數據之間的關系,用於把一個數據分組和其他數據分組聯系起來
當在ERD層標識一個實體-關系之后,在DIS層就用連接器和數據分組來表現:
數據分組包含關鍵字和其他屬性,用於對數據分組進行詳細的描述。
3,物理模型(關系表)
物理模型是從DIS模型創建而來的, 一般來說,數據集成模型中定義的數據分組,都對應一個關系表,數據分組中的關鍵字和屬性,用於定義關系表的主鍵和屬性列。但是,這些表不能直接用於設計數據庫中的關系表,但是,物理模型是設計關系的依據,還要考慮對關系表進行性能優化。
二,數據倉庫的性能優化設計
設計關系表的關鍵是集成數據,設計數據的粒度和分區,另外,為了優化性能,還需要設計緩存,設計冗余字段,去外鍵,增加層次結構。
1,數據集成
把原始數據集成到數據倉庫中,為了性能優化,通常會對數據列做如下處理:
- 增加代理主鍵:保留業務主鍵,但是,增加自增的正整數列(代理主鍵)作為關系表的主鍵,用於唯一標識實體。
- 增加時間列:記錄數據插入的時間(Inserted Time)和數據最新更新的時間(Last Updated Time),便於對數據做增量更新。
- 數據集成時,還需要對數據進行一致性處理,比如,對屬性列統一命名,統一編碼,統一度量單位等
另外,一般數據倉庫中,不會保留長文本數據,如果必須保留長文本數據,建議把該文本列分離出去。對於無效的數據,需要清理出去;對於空值得數據,需要設置默認值等。
2,粒度
在數據倉庫中,數據存在着不同的細節級:原始數據(最細節的數據)、當前細節數據、輕度聚合數據和高度聚合數據,數據的粒度升級,是在數據由操作層傳輸到導出層進行的,一旦數據過期,就由原始數據導出當前細節數據,進而導出聚合數據。我們把聚合之后的數據稱作緩存數據,這是為了定向提高某個主題或分析的查詢性能。
不同的細節級,實際是由數據粒度的不同導致的,而粒度的升級通常是由時間、類別等屬性聚合之后得到的。粒度會深刻地影響存儲到數據倉庫中的數據量的大小和數據倉庫支持的查詢類型。數據倉庫中數據量的大小和粒度成反比,粒度越低,支持的查詢范圍越廣泛,數據量越大。換句話說,低粒度可以回答任何問題,而高粒度會限制數據所能回答的問題。
由於高粒度會降低數據量,使得查詢速度更快;而低粒度能夠回答更多的問題,因此,在數據倉庫中,一般根據數據被查詢的頻次,設計多重粒度,這樣啊,既能使用高粒度快速響應高頻問題,也能使用低粒度回答低頻的問題。
3,分區
數據分區是把數據分散到可獨立進行IO處理的分離的硬盤中,從根本上來說,分區的好處有兩點:
- 利用分區,可以把IO分散到不同的物理硬盤上去,以並發方式訪問數據,提高數據查詢和更新的速度;
- 利用分區,可以把不常用的數據切換到廉價的大容量硬盤上去,而把常用的數據切換到性能優越的硬盤上去;
對數據分區,需要依據特定的數據列,通常以時間列作為分區列,把不同的時間區間的數據存放到不同的分區中去。
注意:把分區分布於不同的物理硬盤,才能充分利用硬件的IO能力,通常情況下,一塊物理硬盤會划分為多個邏輯硬盤,如果把不同的分區放到不同的邏輯硬盤上,而這些邏輯硬盤屬於同一個物理硬盤,那么IO實際上不會並發執行。
4,反向規范化
數據模型的輸出是一系列的關系表,每個表都包含關鍵字和屬性,典型的OLTP數據庫設計的規范是避免冗余,所有的屬性都必須依賴於主鍵,不允許傳遞依賴(即不允許間接依賴主鍵),這樣設計的結果使更新操作的cost最小化,但是,對於一個查詢請求,可能會join多張表,而SQL Server對於多表的Join操作的性能優化能力有限,這會導致查詢性能急劇降低。
由於數據倉庫很少對數據進行更新,通常是保存歷史數據不變;在設計數據倉庫時,可以違反第三范式(不允許間接依賴主鍵),把實體的相關字段合並到一個表中,使相關的數據在物理上是順序存儲的。這樣的表結構設計,既能減少了查詢語句中使用Join的次數,充分利用SQL Server引擎的優化能力,也能利用物理硬盤的IO特性(順序讀取一塊數據),提高數據查詢的性能。
另外一個提高查詢性能的表設計是根據訪問頻率來分裂表,當一個列是長文本字段,且訪問頻次相當低時,可以把該列分離出去,存放到另一個附表中,這樣設計表的結果是高頻訪問的列和窄列放到主表中,低頻的長文本列放到副表中,主表和附表通過代理主鍵關聯在一起。
5,緩存設計
由於數據倉庫中的數據更新的次數少,對於常用的數據聚合,可以預先把數據計算好,存儲到緩存表,也就是說,在數據倉庫中,創建不同粒度的關系表。而緩存表中的數據,可以把計算的時間安排在夜晚等非工作時間段,這樣,用戶在工作時不需要重復計算,只需要查詢就可以快速獲得結果,提高了工作效率。
6,外鍵關系
對於參照完整性,在數據倉庫中,一般不會創建外鍵關系,參照完整性是通過“人工”識別的。這樣,即使刪除了參考表中的數據,也不會影響引用表,只不過join不出結果而已。
把外鍵關系轉換為數據冗余,這也就是數據的反規范化設計,這樣做會增大數據倉庫使用的存儲容量,降低數據更新的性能,但是會加快數據查詢的速度,當數據是穩定的,補償更新時,采用數據冗余是性能優化的設計方案。
7,增加層次結構
層次結構是聚合數據的角度,例如,數據是以天為單位,那么可以設計時間維度,該維度表的層次結構分別是天、周、月、季和年,分析人員可以按照周、月、季和年來聚合數據,以不同的視角來分析數據。常用的層次結構是日期、行政區划,類別等。數據倉庫中,肯定是存儲在時間維度的,也必定存在日期維度。
8,數據壓縮
對於數據倉庫而言,IO資源比CPU資源更加稀缺,我們可以使用計算資源換IO資源。雖然壓縮和解壓縮會浪費CPU資源,但是數據壓縮使得數據可以存儲到較小的硬盤空間中,也就是說,同樣的硬盤空間存儲更多的數據,這使得一次IO能夠讀取更多的數據。
9,索引設計
盡量使用窄列創建索引時,索引不是越多越好,但也不能一個索引都不創建。
對於只插入數據,而極少查詢的數據表,可以創建一個自增列作為主鍵,並創建聚集索引從物理上順序存儲數據;
對於復合主鍵的情況下,可以創建非聚集索引,而使用自增列作為主鍵,並創建聚集索引從物理上順序存儲數據;
對於變長數據類型,如果數據經常更新或改變,可能會帶來非常嚴重的性能問題,在創建索引時,盡量不要把變化頻繁的變長列作為索引列,考慮作為包含列來處理。
三,多維結構
數據倉庫中經常提到的設計方法是多維結構,基於星型連接、事實表和維度表來設計關系表架構,多維方法只適用於數據集市,而不適合數據倉庫。數據集市中的表結構是根據部門的特殊需求而建立的,其結構一般是星型連接,包含事實表和維度表,通常由OLAP技術支持。
通常來說,多維結構的特征是:
- 星型連接是指維度表中數據允許冗余,
- 維度表主要存儲類別屬性和層次結構,
- 事實表存儲實體數據,實體的屬性通過外鍵和維度表關聯。
使用多維結構的結果是:事實表中基本不存儲文本數據,維度表中記錄的是實體的類別,時間等屬性,大多數是文本數據和層次結構數據。多維結構靈活性不足,通用性不足。
四,設計模型
數據倉庫的數據庫設計有兩種基本模型:關系模型和多維模型,關系模型更加靈活,所以更適合數據倉庫的設計,而多維模型更適合數據集市。
1,關系模型
關系模型是OLTP數據庫系統的設計模型,表設計符合數據庫設計的第一范式、第二范式和第三范式,關系模型提高了數據更新的性能,而犧牲了數據查詢的性能。由於OLTP是高更新的數據庫系統,因此,關系模型非常適合操作型數據庫系統。然而,數據倉庫中存儲的數據不常更新,更多的是對數據的查詢。
關系模型的最大優點是靈活,支持適度變化的需求,適合數據倉庫的設計。
2,多維模型
通常認為,多維模型是建立數據倉庫的設計方法,多維模型犧牲數據更新的性能,以提高數據查詢的性能。多維模型的兩種結構是星形連接和雪花形連接,雪花形連接是星形連接的擴展。多維模型存在數據冗余,這會使得,通過一次訪問就可以得到一個實體的所有數據,Join操作較少,數據查詢較快,可以直接用於OLAP技術。缺點是不夠靈活,一旦設計完成,要想改動就很難了。
(1)星形連接
從設計模型上來看,星形連接是以一顆事實表為中心,周圍圍繞着維度表。
星形連接的中心是一個事實表,事實表是包含大量數據值的一個表;事實表的周圍是維度表,用於描述事實表的類別,時間等屬性。事實表和維度表通過公共屬性(外鍵)相關聯。
(2)雪花形連接
通常,星形連接只包含一張事實表,當需要多張事實表相結合時,這就是雪花形結構:
在雪花形結構中,不同的事實表通過共享一個或多個公共維度表連接起來。
參考文檔: