關係型數據庫到HBase的數據儲存方式變遷

 

我是標題黨,其實本文與hbase關係不大,只是把它作爲列族數據庫的代表來講。從目前字眼上看,HBase比Bigtable無疑更具吸引力。題目改成:RDBMS到列族的數據儲存方式變遷 更恰當。

如今Bigtable型(列族)數據庫應用越來越廣,功能也很強大。但是很多人還是把它當做關係型數據庫在使用,用原來關係型數據庫的思維建表、存儲、查詢。本文以hbase舉例講述數據模式的變化。

傳統關係型數據庫(mysql,oracle)數據存儲方式主要如下:

圖一

上圖是個很典型的數據儲存方式,我把每條記錄分成3部分:主鍵、記錄屬性、索引字段。我們會對索引字段建立索引,達到二級索引的效果。

但是隨着業務的發展,查詢條件越來越複雜,需要更多的索引字段,且很多值都不存在,如下圖:圖二

上圖是6個索引字段,實際情況可能是上百個甚至更多,並且還需要根據多個索引字段刷選。查詢性能越來越低,甚至無法滿足查詢要求。關係型數據裏的侷限也開始顯現,於是很多人開始接觸NoSQL。

列族數據庫很強大,很多人就想把數據從mysql遷到hbase,存儲的方式還是跟圖一或者圖二一樣,主鍵爲rowkey。其他各個字段的數據,存儲一個列族下的不同列。但是想對索引字段查詢就沒有辦法,目前還沒有比較好的基於bigtable的二級索引方案,所以無法對索引字段做查詢。

這時候其實可以轉換下思維,可以把數據倒過來,如下圖:

圖三

把各個索引字段的值作爲rowkey,然後把記錄的主鍵和屬性值按照一定順序存在對應rowkey的value裏。上圖只有一個列族,是最簡單的方式。 Value裏的記錄可以設置成定長的byte[],多個記錄集合通過移位快速查詢到。

但是上面只適合單個索引字段的查詢。如果要同時對多個索引字段查詢,圖三的方式需要求取出所有value值,比如查詢“浙江”and“手機”,需要取出兩個value,再解析出各自的主鍵求交。如果每條記錄的屬性有上百個,對性能影響很大。

接下來的變化是解決多索引字段查詢的問題。我們將主鍵字段和屬性字段分開存儲,儲存在不同的列族下,多索引查詢只需要取出列族1下的數據求交,再去最小集合的列族2裏取得想要的值。儲存如圖四:

圖四

以上圖數據舉例:查詢“浙江”AND“手機”

1、取出“浙江”、“手機”列族1下的數據,即{1,2,5}、{2,6}

2、對數據求交後得到{2}滿足條件,{2}在”手機”(最小集合)下的index爲{1}

3、取出“手機”列族二的數據,根據步驟2的index,取出結果{108,2,22234,12}

爲什麼是不同列族,而不是一個列族下的兩個列?

列族數據庫數據文件是按照列族分的。在取數據時,都會把一個列族的所有列數據都取出來,事實上我們並不需要把記錄明細取出來,所以把這部分數據放到了另一個列族下。

接下來是對列族2擴展,列族2儲存更多的列,用來做各種刷選、計算處理。如下圖:圖五

後來我感覺這玩樣越來越像搜索了。。。

這是一個很典型的通過空間換時間的方案,通過大量數據冗餘來提高查詢性能。同時也帶來了問題,就是數據一致性的問題。所以這種方案的應用場景是對海量歷史數據做實時計算上。關於應用場景可以看我之前寫的一篇文章:實時計算應用場景

而處理實時更新的數據或者經常修改的數據還是難點問題,也歡迎討論或者加入我們團隊一起解決這些難題

http://www.yiihsia.com/2011/08/%E5%85%B3%E7%B3%BB%E5%9E%8B%E6%95%B0%E6%8D%AE%E5%BA%93%E5%88%B0hbase%E7%9A%84%E6%95%B0%E6%8D%AE%E5%82%A8%E5%AD%98%E6%96%B9%E5%BC%8F%E5%8F%98%E8%BF%81/

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章