資料儲存--面向列的儲存設計

b10l07發表於2018-01-22

如果你的資料倉儲中的事實資料表擁有大量的資料(參見前文),儲存和查詢資料的難度會大大上升。
在大多數OLTP系統中,資料儲存都是以面向行(row-oriented)的方式組織的。這種方式把一行資料存放在一起。
在OLAP系統中,查詢語句一般是獲取大量行資料中的特定某幾列。這裡就需要引入面向列(column-oriented)儲存的概念:相比於面向行儲存把一行資料相鄰存放,面向列儲存把一列的資料存放在一起。

335803-eac996c00dfb7e5e.png
面向列儲存示例

面向列儲存還有一個好處:處於同一列的資料往往具有某些相似性,這種特性會方便資料的壓縮處理。


335803-76a91c8413849cbb.png
bitmap壓縮示例

需要注意的一點是,谷歌知名的BigTable有一個列族(column families)的概念(HBase和Cassandra也一併繼承了這個概念)。但是同一列族的資料仍然也行為單位存放在一起,所以BigTable本身更貼近於面向行的資料儲存。
雖然面向列的儲存把同一列的資料存放在一起,但是在常規查詢的時候,還是應該按某一列的值按行把所有列的資料排序。比如某一操作需要經常按時間維度獲取資料,正確的做法是按時間列升序或者降序來按行把所有資料排序,這樣執行時間的區間查詢時效率比較高。
如果排序列中只含有少數幾個值的話,不妨使用bitmap將列進行壓縮,來減少空間佔用。
既然資料本身就要做冗餘災備,而且各個查詢請求對排序列的要求也可能不同,不妨在不同的資料節點上按不同的排序列來儲存多份資料。針對不同的查詢請求,選擇最合適的資料節點響應查詢請求,發生了部分當機之後最多造成查詢條件下降。
前面說到,資料倉儲常用做資料分析,這就意味著使用max,min,count,sum,avg等方法比獲取原始資料更為普遍。所以資料倉儲常常對某些列的統計值進行快取來減少計算量,這種方法叫物化檢視(materialized view)。每當發生寫操作時,物化檢視都要被更新計算,所幸OLAP系統一般是週期性大批量寫入,經常大批量讀取。

相關文章