本文地址:http://www.cnblogs.com/qiaoyihang/p/6262806.html
傳統的行式數據庫將一個個完整的數據行存儲在數據頁中。這種方式在大數據量查詢的時候會出現以下問題
一般來說,OLTP(Online Transaction Processing,聯機事務處理)應用適合采用這種方式。
一個OLAP類型的查詢可能需要訪問幾百萬甚至幾十億個數據行,且該查詢往往只關心少數幾個數據列。例如,查詢今年銷量最高的前20個商品,這個查詢只關心三個數據列:時間(date)、商品(item)以及銷售量(sales amount)。商品的其他數據列,例如商品URL、商品描述、商品所屬店鋪,等等,對這個查詢都是沒有意義的。
如下圖,列式數據庫是將同一個數據列的各個值存放在一起。插入某個數據行時,該行的各個數據列的值也會存放到不同的地方。上例中列式數據庫只需要讀取存儲着“時間、商品、銷量”的數據列,而行式數據庫需要讀取所有的數據列。因此,列式數據庫大大地提高了OLAP大數據量查詢的效率。當然,列式數據庫不是萬能的,每次讀取某個數據行時,需要分別從不同的地方讀取各個數據列的值,然后合並在一起形成數據行。因此,如果每次查詢涉及的數據量較小或者大部分查詢都需要整行的數據,列式數據庫並不適用。
很多列式數據庫還支持列組(column group,Bigtable系統中稱為locality group),即將多個經常一起訪問的數據列的各個值存放在一起。如果讀取的數據列屬於相同的列組,列式數據庫可以從相同的地方一次性讀取多個數據列的值,避免了多個數據列的合並。列組是一種行列混合存儲模式,這種模式能夠同時滿足OLTP和OLAP的查詢需求。
由於同一個數據列的數據重復度很高,因此,列式數據庫壓縮時有很大的優勢。例如,Google Bigtable列式數據庫對網頁庫壓縮可以達到15倍以上的壓縮率。另外,可以針對列式存儲做專門的索引優化。比如,性別列只有兩個值,“男”和“女”,可以對這一列建立位圖索引:
如下圖所示,“男”對應的位圖為100101,表示第1、4、6行值為“男”;“女”對應的位圖為011010,表示第2、3、5行值為“女”。如果需要查找男性或者女性的個數,只需要統計相應的位圖中1出現的次數即可。另外,建立位圖索引后0和1的重復度高,可以采用專門的編碼方式對其進行壓縮。
得出如下結論:
列式存儲: 每一列單獨存放,數據即是索引。
一行數據包含一個列或者多個列,每個列一單獨一個cell來存儲數據。而行式存儲,則是把一行數據作為一個整體來存儲。
在HANA的世界中,並不是只存在列式存儲,行式存儲也是存在的。那么讀者不經要問
什么時候應該使用行式存儲?什么時候應該使用列式存儲呢?
如果你大部分時間都是關注整張表的內容,而不是單獨某幾列,並且所關注的內容是不需要通過任何聚集運算的,那么推薦使用行式存儲。原因是重構每一行數據(即解壓縮過程)對於HANA來說,是一個不小的負擔。
列式存儲的話,比如你比較關注的都是某幾列的內容,或者有頻繁聚集需要的,通過聚集之后進行數據分析的表。
詳細歸納為如下:
選擇HANA列式存儲
基於一列或比較少的列計算的時候 |
經常關注一張表某幾列而非整表數據的時候 |
數據表擁有非常多的列的時候 |
數據表有非常多行數據並且需要聚集運算的時候 |
數據表列里有非常多的重復數據,有利於高度壓縮 |
選擇HANA行式存儲
關注整張表內容,或者需要經常更新數據 |
需要經常讀取整行數據 |
不需要聚集運算,或者快速查詢需求 |
數據表本身數據行並不多 |
數據表的列本身有太多唯一性的數據 |

按列存儲
存儲方式
put 表名,rowkey,列族:列名 ,值
邏輯視圖:
數據模型:


