天天看點

資料庫的方向 - 行vs列資料庫的方向 - 行vs列

前言:

轉載的好文不多,但此篇的确是難得一見的好文,如若不信,請仔細閱讀。

此篇文章沒有波濤洶湧的起伏,沒有繁多的代碼,隻有悠然自得的文筆。

是以,分享此文給大家。

如果你是一位資料庫專家的話,這篇部落格可能幫不了你什麼。

如果你是一位IT人士,但對資料庫技術隻知其然的話,這篇部落格會很适合你。

如果你是非IT人士,又或者你是我的家人,謝謝你們的閱讀,但是顯然你應該去尋求更适合你的閱讀材料。

如此,可能會對此話題感興趣的朋友已經減少了。看來你應該是這樣一個人,你是非資料庫領域的IT專家,但是你深知資料庫的重要性,你可能非常想更多的了解一些目前IT界正在熱烈讨論的資料庫熱門話題。

我可以很坦率的告訴大家,雖然我在IBM i的很多個部門工作過,但是我并不是一個DB2的開發人員。是以我會定期的去DB2團隊尋求一些聰明的資料庫專家給我一些比較進階的資料庫指導。尤其,我非常想知道,為什麼近來如此多行業都在談論“列式存儲”資料庫的原因。是以,我找到了Mark Anderson。 衆所周知,Mark是一位傑出的工程師,現在是DB2 for i的首席架構師。下面,我将分享一下我學到的知識。

今天的主題也如同很多有關資料庫讨論一樣主要集中于性能方面。即,新興的列式資料庫和傳統的行式資料庫在性能方面的比較。

顧名思義,這兩種資料庫架構在存貯資料時的方式是大相徑庭的。在行式資料庫中,每一行中的每一塊資料都是緊挨着另一塊資料存放在硬碟中。一般情況下,你可以認為每一行存貯的内容就是硬碟中的一組連續的位元組。如果你記得DB 101(你已經學習了資料庫的介紹課程,對吧?)中介紹的資料庫中每一行都是用來記錄一些實體資訊的。為了友善我們的讨論,我們假設每一行都包含一個使用者的資訊,每個使用者的所有屬性都整塊兒存儲在硬碟上。如下圖所示,虛拟表(或者數組)中的列用來存儲每個屬性。

在硬碟上,大量的頁面用來存儲所有的資料。我們假設資料庫中的每一行的資訊都存儲在同一頁上。在這種情況下,每一頁都能儲存一個使用者的所有資訊。在上邊的例子中,Alice的所有資訊都存儲在一個頁面中。如果需要擷取或更新Alice的資訊,那麼某一時刻在記憶體中僅需存儲關于Alice的單一頁面。

雖然我還沒有提到,但是你可以想象,如果是基于列的資料庫,所有的資料都是以列的形式存儲的。回到之前的例子,假設每一列的存儲對應一個頁面。如下圖所示,所有的ZIP code将會存儲到一個頁面中,而所有的“2013 Total Order”則會存儲在另一個頁面中。

(嘿,所有資料庫專家可能會就此停留,繼而對使用者的表設計提出意見,但抱歉,我并不是資料庫架構師,這僅僅隻是一個教學用例。)

現在,我們言歸正傳。

所有的資料庫(實際上是所有的運算),當它所需要的資料駐留在記憶體中時其工作速度是最快的。當然正常情況下,資料不會在記憶體中,它們會被放到别的地方,當資料庫調用它們時,它們才會被放到記憶體中。是以,如果你使用的是行式資料庫,那麼你對一行資料進行操作時,資料庫的性能會是最好的。在上面的例子中,僅一個頁面被放到了記憶體中。(這隻是一個示例,事實上,作業系統會帶來不止一頁的資料,稍後詳細說明)

另一方面,如果你的資料庫是基于行的,但是你要想得到所有資料中,某一列上的資料來做一些操作,這就意味着你将花費時間去通路每一行,可你用到的資料僅是一行中的小部分資料。若此時你使用了列式的資料庫,那就可以友善快捷的擷取資料,因為每一列的資訊都是存儲在一起的。例如,所有的“2013 Total Order”資訊都是存儲在同一列中的。

可關鍵在于你使用列式資料庫時,當你想要得到Alice的所有資訊時,你又必須要讀取大量的列(頁面)來擷取所有的資料。

正因為此,才有了這些天有關列式資料庫的讨論。

如果你還是沒有很好了解的話,我們下面會有更加詳細的介紹。

到目前為止,幾乎所有的資料庫都是基于行的資料庫,此類資料庫對大多數的傳統業務都是非常有效的。資料庫專家們将大部分的資料庫工作負載稱為OLTP–線上事務處理。OLTP工作負載是資料庫現有業務的關鍵業務。一般而言,這些應用程式在使用行資料庫時會有更好的表現,因為其工作負載趨向于單一實體的多個屬性(存儲在很多的列中)。由于這些應用程式都是基于行工作的,是以在使用時,從硬碟中擷取的頁面數量是最小的。

如果能對列中的資料進行有效的處理,某些工作負載會運作得更高效。線上分析處理(OLAP)工作負載常常需要收集列中的資料。例如,如果你想要知道标記為“2013 Total Order”列中的所有值,當你使用基于列的資料庫時,你可以将這一列放到記憶體中并統計所有值。但當使用的是基于行的資料庫時,就必須去通路每一行而擷取對應的資料。

當然,事實并非如此。基于行的資料庫,例如DB2 for i,已經增加了一些方法,這些方法可以使得,諸如“sum a column”這樣簡單的操作,或者更複雜一些的OLAP分析也可以很高效的得到處理。例如,DB2 for i有兩種結構,分别是編碼向量索引(EVIs)和物化查詢表(MQTs),對于這樣的操作都有很好的效果。并且DB2 for i給使用者的資料是成批的(一次讀取很多行),而不是一次一個。除此之外,使用者自定義的方法也可以用來提高性能。IBM的存儲管理元件也是非常智能的,值得一提的是,它實作了單級存儲。正因為它如此的智能,是以在使用者提出請求前,已經将資料讀取到記憶體中。正因為在很多的OLTP工作負載中都要求順序地通過行,而DB2 for i在需要資料之前,已将行資料批量的讀取到記憶體中,可見這個功能是非常重要的。

另一方面,單純給列式存儲的表加索引,也不能使OLTP很高效。Mark曾經說過“這就像把很多的矮胖子放在一起”。行資訊分散在很多存儲頁中。即使整個資料庫都存放在記憶體裡,也需要消耗大量的CPU資源,來将一行中的所有列拼接起來。

下面總結這一課的關鍵内容。在選擇使用哪種資料庫時,問自己這樣一個問題,哪種工作負載是你的資料庫需要支援的最關鍵的工作負載。盡管可能你兩種操作都需要,但是當核心業務是OLTP時,一個行式的資料庫,再加上數十年積累的優化操作,可能是最好的選擇。如果你的企業并不需要快速處理OLTP業務,但需要可以快速處理OLAP時,那麼一個列式的資料庫将會成為你的不二選擇。

如果你需要同時處理兩種業務,且要求它們都能高效處理時,可以去了解兩種種架構相關的混合技術。你可以選擇一種,又或者是使用兩種架構的結合來滿足你的需求。無論你選擇了何種類别,都要確定證這一解決方案是穩定的,這可是要用來切實為企業資料服務的。

到此,尊敬的讀者們, DB 102就結束了.現在,當你再讀到有關列式數庫的文章時,就可以了解其引起讨論的原因了。

在下次的讨論中,我們将進一步學習。

原文作者:Steve Will

翻譯:周松文