面試 | 面向行的數(shù)據(jù)庫VS面向列的數(shù)據(jù)庫
本文轉(zhuǎn)載自微信公眾號「大數(shù)據(jù)技術(shù)與數(shù)倉」,作者西貝。轉(zhuǎn)載本文請聯(lián)系大數(shù)據(jù)技術(shù)與數(shù)倉公眾號。
總覽
數(shù)據(jù)庫的數(shù)據(jù)存儲有兩種類型,一種是面向行的(row-oriented)數(shù)據(jù)庫,另一種是面向列的(column-oriented )數(shù)據(jù)庫。
面向行(事務(wù)型) 數(shù)據(jù)庫
該類數(shù)據(jù)庫是根據(jù)記錄(record)組織數(shù)據(jù)的,將所有與記錄相關(guān)聯(lián)的數(shù)據(jù)保存在內(nèi)存中。面向行的數(shù)據(jù)庫是組織數(shù)據(jù)的傳統(tǒng)方式,并且為快速存儲數(shù)據(jù)提供了一些關(guān)鍵優(yōu)勢。它們經(jīng)過優(yōu)化,可以高效地讀取和寫入行。
常見的面向行的數(shù)據(jù)庫:
- PostgreSQL
- MySQL
優(yōu)點
- 行存儲的寫入是一次性完成,消耗的時間比列存儲少,并且能夠保證數(shù)據(jù)的完整性;
- insert/update更容易
缺點
- 沒有索引的查詢會產(chǎn)生大量的I/O
- 建立索引需要花費大量時間和資源
- 面對查詢的需求,數(shù)據(jù)庫必須被大量膨脹才能滿足性能的需求
面向列(分析型) 數(shù)據(jù)庫:
該類數(shù)據(jù)庫是按字段組織數(shù)據(jù)的,在內(nèi)存中將所有與字段相關(guān)聯(lián)的數(shù)據(jù)保存在一起。該類數(shù)據(jù)庫在讀取和計算列有明顯的優(yōu)勢。
常用的面向列的數(shù)據(jù)庫
- AWS RedShift
- Google BigQuery
- HBase
優(yōu)點
- 只查詢涉及的列,會大量降低系統(tǒng)I/O,適合并發(fā)查詢
- 數(shù)據(jù)類型一致,數(shù)據(jù)特征相似,能對數(shù)據(jù)進行高效壓縮
- 非常適合做聚合操作
缺點
- 缺乏數(shù)據(jù)完整性保證,寫入效率低
- 不適合頻繁delete/update操作
面向行的數(shù)據(jù)庫
傳統(tǒng)的關(guān)系型數(shù)據(jù)庫管理系統(tǒng)(DBMS)都是面向行的。在行存儲或面向行的數(shù)據(jù)庫中,數(shù)據(jù)是逐行存儲的,這樣,行的第一列將挨著前一行的最后一列。
比如,有下面的一張表
這些數(shù)據(jù)將被存儲在一個面向行的數(shù)據(jù)庫中的一個磁盤上,按照下面這樣的順序一行一行的排列:
這允許數(shù)據(jù)庫快速寫入一行,因為要寫入數(shù)據(jù),只需在數(shù)據(jù)的末尾添加另一行即可。
面向行的數(shù)據(jù)庫仍然通常用于聯(lián)機事務(wù)處理(OLTP)的應(yīng)用程序,因為它們可以很好地管理對數(shù)據(jù)庫的寫操作。對于聯(lián)機分析處理(OLAP)的場景需要一個支持特定數(shù)據(jù)查詢的數(shù)據(jù)庫。這就是面向行的數(shù)據(jù)庫比面向列的數(shù)據(jù)庫慢的地方。
讀取面向行的數(shù)據(jù)庫
面向行的數(shù)據(jù)庫檢索行或一組行的速度很快,但在執(zhí)行聚合時,它將額外的數(shù)據(jù)(列)帶入內(nèi)存,這比只選擇要執(zhí)行聚合的列要慢。此外,面向行的數(shù)據(jù)庫可能需要訪問的磁盤數(shù)量通常更多。
因此,我們可以看到,雖然向面向行的數(shù)據(jù)庫添加數(shù)據(jù)是快速和簡單的,但從中獲取數(shù)據(jù)可能需要使用額外的內(nèi)存和訪問多個磁盤。
面向列的數(shù)據(jù)庫
數(shù)據(jù)倉庫的創(chuàng)建是為了支持數(shù)據(jù)分析。這些類型的數(shù)據(jù)庫通常對數(shù)據(jù)讀取做了優(yōu)化。
在面向列的數(shù)據(jù)庫中,數(shù)據(jù)的存儲形式為列中的每一行都挨著同一列中的其他行。
仍然以上面的表為例:
一個表一次存儲一列,按照一行一行的順序排列:
寫入面向列的數(shù)據(jù)庫
如果我們想要添加一個新記錄,必須先定位數(shù)據(jù)的位置(比如HBASE的三級尋址),將每一列插入到它應(yīng)該在的位置。
如果數(shù)據(jù)存儲在一個單獨的磁盤上,那么它將有與面向行的數(shù)據(jù)庫相同的額外內(nèi)存問題,因為它需要將所有內(nèi)容都放入內(nèi)存中。但是,當(dāng)存儲在單獨的磁盤上時,面向列的數(shù)據(jù)庫將有很大的好處。
從面向列的數(shù)據(jù)庫中讀取
只需要計算需要的列,減少磁盤掃描,減少不必要的內(nèi)存開銷,只需要訪問極少數(shù)量的磁盤。
附錄(SQL知識大圖)