行存储 VS 列存储[通俗易懂]
概述
目前大數(shù)據(jù)存儲有兩種方案可供選擇:行存儲(Row-Based)和列存儲(Column-Based)。業(yè)界對兩種存儲方案有很多爭持,集中焦點是:誰能夠更有效地處理海量數(shù)據(jù),且兼顧安全、可靠、完整性。從目前發(fā)展情況看,關系數(shù)據(jù)庫已經(jīng)不適應這種巨大的存儲量和計算要求,基本是淘汰出局。在已知的幾種大數(shù)據(jù)處理軟件中,Hadoop的HBase采用列存儲,MongoDB是文檔型的行存儲,Lexst是二進制型的行存儲。
什么是列存儲?
列式存儲(column-based)是相對于傳統(tǒng)關系型數(shù)據(jù)庫的行式存儲(Row-basedstorage)來說的。簡單來說兩者的區(qū)別就是如何組織表:
? Row-based storage storesatable in a sequence of rows.
? Column-based storage storesatable in a sequence of columns.
從上圖可以很清楚地看到,行式存儲下一張表的數(shù)據(jù)都是放在一起的,但列式存儲下都被分開保存了。所以它們就有了如下這些優(yōu)缺點對比:
在數(shù)據(jù)寫入上的對比
1)行存儲的寫入是一次完成。如果這種寫入建立在操作系統(tǒng)的文件系統(tǒng)上,可以保證寫入過程的成功或者失敗,數(shù)據(jù)的完整性因此可以確定。
2)列存儲由于需要把一行記錄拆分成單列保存,寫入次數(shù)明顯比行存儲多(意味著磁頭調度次數(shù)多,而磁頭調度是需要時間的,一般在1ms~10ms),再加上磁頭需要在盤片上移動和定位花費的時間,實際時間消耗會更大。所以,行存儲在寫入上占有很大的優(yōu)勢。
3)還有數(shù)據(jù)修改,這實際也是一次寫入過程。不同的是,數(shù)據(jù)修改是對磁盤上的記錄做刪除標記。行存儲是在指定位置寫入一次,列存儲是將磁盤定位到多個列上分別寫入,這個過程仍是行存儲的列數(shù)倍。所以,數(shù)據(jù)修改也是以行存儲占優(yōu)。
在數(shù)據(jù)讀取上的對比
1)數(shù)據(jù)讀取時,行存儲通常將一行數(shù)據(jù)完全讀出,如果只需要其中幾列數(shù)據(jù)的情況,就會存在冗余列,出于縮短處理時間的考量,消除冗余列的過程通常是在內存中進行的。
2)列存儲每次讀取的數(shù)據(jù)是集合的一段或者全部,不存在冗余性問題。
3) 兩種存儲的數(shù)據(jù)分布。由于列存儲的每一列數(shù)據(jù)類型是同質的,不存在二義性問題。比如說某列數(shù)據(jù)類型為整型(int),那么它的數(shù)據(jù)集合一定是整型數(shù)據(jù)。這種情況使數(shù)據(jù)解析變得十分容易。相比之下,行存儲則要復雜得多,因為在一行記錄中保存了多種類型的數(shù)據(jù),數(shù)據(jù)解析需要在多種數(shù)據(jù)類型之間頻繁轉換,這個操作很消耗CPU,增加了解析的時間。所以,列存儲的解析過程更有利于分析大數(shù)據(jù)。
4)從數(shù)據(jù)的壓縮以及更性能的讀取來對比
優(yōu)缺點
顯而易見,兩種存儲格式都有各自的優(yōu)缺點:
1)行存儲的寫入是一次性完成,消耗的時間比列存儲少,并且能夠保證數(shù)據(jù)的完整性,缺點是數(shù)據(jù)讀取過程中會產生冗余數(shù)據(jù),如果只有少量數(shù)據(jù),此影響可以忽略;數(shù)量大可能會影響到數(shù)據(jù)的處理效率。
2)列存儲在寫入效率、保證數(shù)據(jù)完整性上都不如行存儲,它的優(yōu)勢是在讀取過程,不會產生冗余數(shù)據(jù),這對數(shù)據(jù)完整性要求不高的大數(shù)據(jù)處理領域,比如互聯(lián)網(wǎng),猶為重要。
兩種存儲格式各自的特性都決定了它們的使用場景。
列存儲的適用場景
1)一般來說,一個OLAP類型的查詢可能需要訪問幾百萬甚至幾十億個數(shù)據(jù)行,且該查詢往往只關心少數(shù)幾個數(shù)據(jù)列。例如,查詢今年銷量最高的前20個商品,這個查詢只關心三個數(shù)據(jù)列:時間(date)、商品(item)以及銷售量(sales amount)。商品的其他數(shù)據(jù)列,例如商品URL、商品描述、商品所屬店鋪,等等,對這個查詢都是沒有意義的。
而列式數(shù)據(jù)庫只需要讀取存儲著“時間、商品、銷量”的數(shù)據(jù)列,而行式數(shù)據(jù)庫需要讀取所有的數(shù)據(jù)列。因此,列式數(shù)據(jù)庫大大地提高了OLAP大數(shù)據(jù)量查詢的效率
OLTP OnLine TransactionProcessor 在線聯(lián)機事務處理系統(tǒng)(比如Mysql,Oracle等產品)
OLAP OnLine AnalaysierProcessor 在線聯(lián)機分析處理系統(tǒng)(比如Hive Hbase等)
2)很多列式數(shù)據(jù)庫還支持列族(column group,Bigtable系統(tǒng)中稱為locality group),即將多個經(jīng)常一起訪問的數(shù)據(jù)列的各個值存放在一起。如果讀取的數(shù)據(jù)列屬于相同的列族,列式數(shù)據(jù)庫可以從相同的地方一次性讀取多個數(shù)據(jù)列的值,避免了多個數(shù)據(jù)列的合并。列族是一種行列混合存儲模式,這種模式能夠同時滿足OLTP和OLAP的查詢需求。
3)此外,由于同一個數(shù)據(jù)列的數(shù)據(jù)重復度很高,因此,列式數(shù)據(jù)庫壓縮時有很大的優(yōu)勢。
例如,Google Bigtable列式數(shù)據(jù)庫對網(wǎng)頁庫壓縮可以達到15倍以上的壓縮率。另外,可以針對列式存儲做專門的索引優(yōu)化。比如,性別列只有兩個值,“男”和“女”,可以對這一列建立位圖索引:
如下圖所示
“男”對應的位圖為100101,表示第1、4、6行值為“男”
“女”對應的位圖為011010,表示第2、3、5行值為“女”
如果需要查找男性或者女性的個數(shù),只需要統(tǒng)計相應的位圖中1出現(xiàn)的次數(shù)即可。另外,建立位圖索引后0和1的重復度高,可以采用專門的編碼方式對其進行壓縮。
當然,如果每次查詢涉及的數(shù)據(jù)量較小或者大部分查詢都需要整行的數(shù)據(jù),列式數(shù)據(jù)庫并不適用。
最后總結如下
傳統(tǒng)行式數(shù)據(jù)庫的特性如下:
①數(shù)據(jù)是按行存儲的。
②沒有索引的查詢使用大量I/O。比如一般的數(shù)據(jù)庫表都會建立索引,通過索引加快查詢效率。
③建立索引和物化視圖需要花費大量的時間和資源。
④面對查詢需求,數(shù)據(jù)庫必須被大量膨脹才能滿足需求。
列式數(shù)據(jù)庫的特性如下:
①數(shù)據(jù)按列存儲,即每一列單獨存放。
②數(shù)據(jù)即索引。
③只訪問查詢涉及的列,可以大量降低系統(tǒng)I/O。
④每一列由一個線程來處理,即查詢的并發(fā)處理性能高。
⑤數(shù)據(jù)類型一致,數(shù)據(jù)特征相似,可以高效壓縮。比如有增量壓縮、前綴壓縮算法都是基于列存儲的類型定制的,所以可以大幅度提高壓縮比,有利于存儲和網(wǎng)絡輸出數(shù)據(jù)帶寬的消耗。
總結
以上是生活随笔為你收集整理的行存储 VS 列存储[通俗易懂]的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网络通信常见加密剖析[通俗易懂](计算机
- 下一篇: research button cont