行式存儲和列式存儲優缺點和paruqet文件結構

參考文章:行式存儲和列式存儲優缺點和paruqet文件結構

一、列式存儲和行式存儲的比較

列式存儲和行式存儲是針對數據在存儲介質中的排序形式而言的,假設存在一張table,那麼:

  • 行式存儲:依次連續存儲第1、2、3...行的數據到存儲介質中;
  • 列式存儲:依次連續存儲第1、2、3...列的數據到存儲介質中。

圖1-1所示爲行式存儲和列式存儲的示意圖,一張table包含5個字段(列)即rowid、date/time、customer name以及quantity,共7行,圖中的紅色箭頭表示存儲順序。

標圖1-1. 行式存儲和列式存儲區別題

 

二、行式存儲和列式存儲的優缺點和適用場景

存儲形式的差異決定了適用場景的不同:

  • 行式存儲適合”針對行”的查詢
    比如(mysql)select * from table_name limit 1,因爲只會讀取圖1-1中的“row-based store 第1個綠色部分的數據”(只有指定的行“1 845 2 3 1”纔會被讀取),而select rowid from table_name則需要讀取row-based store所有綠色部分的數據(雖然目的僅是要查詢1個字段);此外還適用於insert/update操作比較多的場景,因爲只需要更改部分數據塊即可。
  • 列式存儲適合“針對列”的查詢
    比如select rowid from table_name,因爲只會讀取圖1-1中的“column-based store 第1個綠色部分的數據”(查詢時只有涉及到的字段會被讀取),而select * from table_name limit 1則需要讀取column-based stores所有綠色部分的數據(雖然目的就是要查詢第1行的數據);但是不適用於insert/update操作比較多的場景,比如當插入1個row時,由於列式存儲導致同一個row的數據被分散在多個數據塊中,因此需要去遍歷所有數據塊的數據此外由於同一個字段連續存儲(同一列的內容有很多值是重複的,可以壓縮),因此更加便於編碼壓縮。
存儲類別 適用於 不適用於
row-based 針對行的查詢,
insert/update操作
針對列的查詢
column-based 針對列的查詢,
編碼壓縮減小存儲空間佔用
針對行的查詢,
insert/update操作

綜合來看,列式存儲比較適合大數據量(壓縮比高)、分析型操作(針對少數幾列);不適合頻率較高的刪除(全列檢索)、更新(重新壓縮)操作。

列式存儲基於字典表的編碼壓縮

圖2-1所示爲列式存儲中將某張table基於字典表進行編碼壓縮的示例,圖中左邊爲源表,假設該table中的customers和material字段的取值均只有右上表所示的5種,那麼當源表的行數很大時,customers和material字段就會存在大量重複的取值,爲了節省存儲空間對這兩個字段進行編碼,即使用一個字典表(右上圖)記錄該兩個字段的distinct取值,又下表則用右上表字段取值對應的index(整數1、2、3、4、5)來代替原來的string,由於string佔用的存儲空間比這幾個index佔用的存儲空間大多了,因此可以較大程度上壓縮佔用的存儲空間。

圖2-1. 列式存儲基於字典表壓縮數據標題

三、parquet文件結構

基於列式存儲的兩個典型實現是:hbase和parquet,其中:

  • hbase可以看成是一個基於列式存儲的非關係型數據庫NoSQL;
  • parquet是基於列式存儲定義的一種文件格式。

parquet的文件結構如圖3-1所示:

 

圖3-1. parquet文件結構一覽圖標題

 

從圖中可以看出,1個parquet文件由header(1個)、block(可以多個)、footer(1個)組成,分別負責:

  • header:只包含一個4個byte的數字PAR1,用來識別整個Parquet文件格式。文件中所有的metadata都存在於footer中;
  • block:存儲數據;
  • footer:包含block中的metadata比如版本信息、schema信息等,footer中最後2個字段分別是1個4個byte長度的footer的metadata、同header中一樣的PAR1。

圖3-2所示爲parquet文件中,block、rowgroup、columnchunk以及page的關係:

標圖3-2. parquet中rowgroup、block、columnchunk以及page的關係題

 

簡而言之:

  • 1個block就是指1個rowgroup;
  • 1個columnchunk對應1個字段;
    1個columnchunk中可能存在多個page(page默認大小爲1M)。

因此如果將一個parquet文件類比成一張大excel 表,那麼:

  • header就相當於excel表的後綴名;
  • block就相當於excel表中的某些數據行(如果行數太多導致需要的byte數超過了block size那就需要多個block);
  • footer就相當於excel表的頁腳記錄了字段數、行數、各block佔用的存儲空間等元數據)。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章