數據庫行存儲及列存儲詳解


 本文參見:https://blog.csdn.net/Xingxinxinxin/article/details/80939277

未完待修改.......................

 一.數據處理類型

  • 聯機事務處理 OLTP(on-line transaction processing)
  • 聯機分析處理 OLAP(On-Line Analytical Processing)

區別:

  • OLTP 是傳統關系型數據庫的主要應用,用來執行一些基本的、日常的事務處理,比如數據庫記錄的增、刪、改、查等等
  • OLAP 則是分布式數據庫的主要應用,它對實時性要求不高,但處理的數據量大,通常應用於復雜的動態報表系統上。

 

二.行式存儲和列式存儲

  • Row-based storage storesatable in a sequence of rows.
  • Column-based storage storesatable in a sequence of columns.

傳統的關系型數據庫,如 Oracle、DB2、MySQL、SQL SERVER 等采用行式存儲法(Row-based),在基於行式存儲的數據庫中, 數據是按照行數據為基礎邏輯存儲單元進行存儲的, 一行中的數據在存儲介質中以連續存儲形式存在。

列式存儲(Column-based)是相對於行式存儲來說的,新興的 Hbase、HP Vertica、EMC Greenplum 等分布式數據庫均采用列式存儲。在基於列式存儲的數據庫中, 數據是按照列為基礎的邏輯存儲單元進行存儲的,一列中的數據在存儲介質中以連續存儲形式存在。

從上圖可以很清楚地看到,行式存儲下一張表的數據都是放在一起的,但列式存儲下都被分開保存了。所以它們就有了如下這些優缺點對比:

1.在數據寫入上的對比

1)行存儲的寫入是一次完成。如果這種寫入建立在操作系統的文件系統上,可以保證寫入過程的成功或者失敗,數據的完整性因此可以確定

2)列存儲由於需要把一行記錄拆分成單列保存,寫入次數明顯比行存儲多(意味着磁頭調度次數多,而磁頭調度是需要時間的,一般在1ms~10ms),再加上磁頭需要在盤片上移動和定位花費的時間,實際時間消耗會更大。所以,行存儲在寫入上占有很大的優勢

3)還有數據修改,這實際也是一次寫入過程。不同的是,數據修改是對磁盤上的記錄做刪除標記。行存儲是在指定位置寫入一次,列存儲是將磁盤定位到多個列上分別寫入,這個過程仍是行存儲的列數倍。所以,數據修改也是以行存儲占優

2.在數據讀取上的對比

1)數據讀取時,行存儲通常將一行數據完全讀出,如果只需要其中幾列數據的情況,就會存在冗余列,出於縮短處理時間的考量,消除冗余列的過程通常是在內存中進行的。

2)列存儲每次讀取的數據是集合的一段或者全部,不存在冗余性問題。

3) 兩種存儲的數據分布。由於列存儲的每一列數據類型是同質的,不存在二義性問題。比如說某列數據類型為整型(int),那么它的數據集合一定是整型數據。這種情況使數據解析變得十分容易。相比之下,行存儲則要復雜得多,因為在一行記錄中保存了多種類型的數據,數據解析需要在多種數據類型之間頻繁轉換,這個操作很消耗CPU,增加了解析的時間。所以,列存儲的解析過程更有利於分析大數據。

4)從數據的壓縮以及更性能的讀取來對比

 

圖列分析:首先將Customes Name列及Material列做邏輯化索引標識,查詢時分別匹配Materia=Refrigerator及Customes Name=Miller的數據,然后做交叉匹配

3.優缺點

1)行存儲的寫入是一次性完成,消耗的時間比列存儲少,並且能夠保證數據的完整性,缺點是數據讀取過程中會產生冗余數據,如果只有少量數據,此影響可以忽略;數量大可能會影響到數據的處理效率。

2)列存儲在寫入效率、保證數據完整性上都不如行存儲,它的優勢是在讀取過程,不會產生冗余數據,這對數據完整性要求不高的大數據處理領域,比如互聯網,猶為重要。查詢過程中,可針對各列的運算並發執行(SMP),***在內存中聚合完整記錄集,***可能降低查詢響應時間;可在數據列中高效查找數據,無需維護索引(任何列都能作為索引),查詢過程中能夠盡量減少無關IO,避免全表掃描;因為各列獨立存儲,且數據類型已知,可以針對該列的數據類型、數據量大小等因素動態選擇壓縮算法,以提高物理存儲利用率;如果某一行的某一列沒有數據,那在列存儲時,就可以不存儲該列的值,這將比行式存儲更節省空間。

4.使用場景

  如果你大部分時間都是關注整張表的內容,而不是單獨某幾列,並且所關注的內容是不需要通過任何聚集運算的,那么推薦使用行式存儲。原因是重構每一行數據(即解壓縮過程)對於HANA來說,是一個不小的負擔。列式存儲的話,比如你比較關注的都是某幾列的內容,或者有頻繁聚集需要的,通過聚集之后進行數據分析的表。

行式存儲的適用場景:

  1、適合隨機的增刪改查操作;

  2、需要在行中選取所有屬性的查詢操作;

  3、需要頻繁插入或更新的操作,其操作與索引和行的大小更為相關。

列式存儲的適用場景:

  一般來說,一個OLAP類型的查詢可能需要訪問幾百萬甚至幾十億個數據行,且該查詢往往只關心少數幾個數據列。例如,查詢今年銷量最高的前20個商品,這個查詢只關心三個數據列:時間(date)、商品(item)以及銷售量(sales amount)。商品的其他數據列,例如商品URL、商品描述、商品所屬店鋪,等等,對這個查詢都是沒有意義的。而列式數據庫只需要讀取存儲着“時間、商品、銷量”的數據列,而行式數據庫需要讀取所有的數據列。因此,列式數據庫大大地提高了OLAP大數據量查詢的效率。

  很多列式數據庫還支持列族(column group,Bigtable系統中稱為locality group),即將多個經常一起訪問的數據列的各個值存放在一起。如果讀取的數據列屬於相同的列族,列式數據庫可以從相同的地方一次性讀取多個數據列的值,避免了多個數據列的合並。列族是一種行列混合存儲模式,這種模式能夠同時滿足OLTP和OLAP的查詢需求。

  實操中我們會發現,行式數據庫在讀取數據的時候,會存在一個固有的“缺陷”。比如,所選擇查詢的目標即使只涉及少數幾項屬性,但由於這些目標數據埋藏在各行數據單元中,而行單元往往又特別大,應用程序必須讀取每一條完整的行記錄,從而使得讀取效率大大降低,對此,行式數據庫給出的優化方案是加“索引”。

  在OLTP類型的應用中,通過索引機制或給表分區等手段,可以簡化查詢操作步驟,並提升查詢效率。但針對海量數據背景的OLAP應用(例如分布式數據庫、數據倉庫等等),行式存儲的數據庫就有些“力不從心”了,行式數據庫建立索引和物化視圖,需要花費大量時間和資源,因此還是得不償失,無法從根本上解決查詢性能和維護成本等問題,也不適用於數據倉庫等應用場景,所以后來出現了基於列式存儲的數據庫。對於數據倉庫和分布式數據庫來說,大部分情況下它會從各個數據源匯總數據,然后進行分析和反饋,其操作大多是圍繞同一列屬性的數據進行的,而當查詢某屬性的數據記錄時,列式數據庫只需返回與列屬性相關的值,在大數據量查詢場景中,列式數據庫可在內存中高效組裝各列的值,最終形成關系記錄集,因此可以顯著減少IO消耗,並降低查詢響應時間,非常適合數據倉庫和分布式的應用。

 

       

5.總結

1.傳統行式數據庫的特性如下:

  ①數據是按行存儲的。

  ②沒有索引的查詢使用大量I/O。比如一般的數據庫表都會建立索引,通過索引加快查詢效率。

  ③建立索引和物化視圖需要花費大量的時間和資源。

  ④面對查詢需求,數據庫必須被大量膨脹才能滿足需求。

2.列式數據庫的特性如下:

  ①數據按列存儲,即每一列單獨存放。

  ②數據即索引。

  ③只訪問查詢涉及的列,可以大量降低系統I/O。

  ④每一列由一個線程來處理,即查詢的並發處理性能高。

  ⑤數據類型一致,數據特征相似,可以高效壓縮。比如有增量壓縮、前綴壓縮算法都是基於列存儲的類型定制的,所以可以大幅度提高壓縮比,有利於存儲和網絡輸出數據帶寬的消耗。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM