本次分享內容由三個部分組成:算法
目前數據庫主流數據組織技術分爲數據按行存儲和數據按列存儲,達夢數據庫表數據的存儲方式同時支持行存儲和列存儲。行存儲是以記錄爲單位進行存儲的,數據頁面中存儲的是完整的若干條記錄;列存儲是以列爲單位進行存儲的,每個列的全部行數據都存儲在一塊兒,一個段只存儲一個列的數據,並且一個指定的頁面中存儲的都是某一個列的連續數據。
列存表的存儲方式有如下幾個優勢:數據庫
同一個列的數據都是連續存儲的,能夠加快某一個列的數據查詢速度(相對行存減少沒必要要IO);函數
連續存儲的列數據,具備更大的壓縮單元和數據類似性,能夠得到遠優於行存儲的壓縮效率;性能
條件掃描藉助數據區的統計信息進行精確過濾,能夠進一步減小IO,提升掃描效率(智能索引)。測試
下面咱們主要介紹達夢數據庫的列存儲的技術特色及具體實現,並詳細介紹列存儲的數據組織方式、智能索引的實現、自適應壓縮算法設計。大數據
1ui
列存儲數據組織實現編碼
達夢的列存儲表又叫HUGE表,是創建在HTS表空間上的(全稱HUGE TABLESPACE)。這個表空間與普通的表空間不一樣。普通的表空間,數據是經過段、簇、頁來管理的,而且以固定大小(4K、8K、16K、32K)的頁面爲管理單位;而HTS至關於一個簡單的文件系統,建立一個HTS,其實就是建立一個空的目錄。在建立一個HFS表以後,數據庫會在指定的HTS表空間目錄下建立一系列的目錄及文件,文件系統結構以下圖所示:加密
從上圖能夠看出,在HTS目錄下成功建立HFS表,系統內部須要通過如下步驟: 首先,在HTS目錄下建立這個表對應的模式目錄。目錄名爲「SCH+長度爲9的ID號」組成的字符串。spa
其次,在模式目錄下建立對應的表目錄。表目錄也是一樣的道理,表目錄名爲「TAB+長度爲4的ID號」組成的字符串。表目錄中存放的是這個表中全部的文件。
再次,在新建立表時,每個列對應的一個以dta爲後綴的文件,文件大小能夠在建表時指定,默認爲64M,文件名爲「COL+長度爲4的列號+_+長度爲10的文件號」。例如,在上圖中,0000表示第1列,0001表示第2列……;0000000000表示第1個文件,0000000001表示第2個文件……最初一個列只有一個文件便可,當隨着數據量不斷增加,一個文件已放不下以後,系統會自動建立新的文件來存儲不斷增加的數據。
對於一個文件,其內部存儲是按照區來管理的,區是文件內部數據管理的最小單位,也是惟一的單位(相似於行存的頁)。一個區中,能夠存儲單列數據的行數是經過建立表時指定的,一經指定,在這個表的生命過程就不能再修改。
一個區內,存儲的僅僅是數據而已,對於ABLE屬性的列,存儲的還有相應的標誌。每個區的開始位置及長度在文件內都是4K對齊的。對於一個HFS表,相應的還配備一個輔助表來管理其數據。
由於在上面介紹的文件中只存儲了數據,輔助表用來管理以及輔助系統用戶操做這些數據,該輔助表是在建立HFS表時系統自動建立的。輔助表中每一條記錄對應文件中的一個數據區,輔助表包括下面15列:
「
」
前面7列是用來控制數據存取的,根據這些信息就能夠知道這個區的具體存儲位置、長度及基本信息。後面8列都是用來對這個區進行統計分析的。其中,COLID和SEC_ID的組合鍵爲輔助表的聚簇關鍵字。
實際上數據庫對列存數據的查找過程就是經過對輔助表信息的檢索,利用輔助信息操縱HTS目錄下文件的過程。
2
智能索引的實現
列存表作條件掃描能夠藉助數據區的統計信息進行精確過濾,能夠進一步減小IO,提升掃描效率。數據區的統計信息是數據庫系統自動維護的,在必定程度上能夠替代BTree索引,因此被一些廠商稱爲「智能索引」。
下圖爲區最大值、最小值信息起到過濾做用的示意圖:
除了最大值、最小值起到跳區掃描減小IO的做用,區和值、區內有效行數等其它信息在一些統計分析場景甚至能夠徹底避免數據區的掃描。如MAX,COUNT,AVG等一些函數能夠直接經過查詢輔助表得到。
3
自適應壓縮算法
連續存儲的列數據,具備更大的壓縮單元和數據類似性,能夠得到遠優於行存儲的壓縮效率。根據列存儲的特性,達夢提供一套自適應的壓縮算法,能夠根據數據特性以區爲單位自動選擇相應的算法最大化壓縮率和性能。
下面詳細介紹4種編碼策略:
(1)字典編碼
利用數據類型的一致性,將相同的值提取出來生成符號表,每一個列值則直接存儲該值映射成的符號表值id便可。
字典編碼的示例以下:
(2)常量編碼
當區內的數據大部分的數據相同,只有少數不一樣時,能夠採用常量編碼。該編碼將區內數據出現最多的一個值做爲常量值,其餘值做爲異常值。異常值使用<行號+值>的方式存儲。
(3)RLE編碼
當區內的數據存在大量的相同值,每一個不一樣值的個數比較均勻,且連續出現時,可使用RLE編碼。
(4)序列編碼
當區內的數據差值成等差數列,或者存在必定的代數關係,則可使用序列編碼。
(5)四種編碼使用策略
字典編碼、常量編碼和RLE編碼都是基於重複值較多的狀況下使用的,若是不一樣值中,某個值出現屢次,其餘的值都只出現一次,則可使用常量編碼;若是這些不一樣值都連續出現屢次,且出現的次數至關,則使用RLE編碼;若是這些不一樣值出現的次數至關,但都不連續,則使用字典編碼。從上可知,這三種編碼方式都是基於不一樣值的分佈特徵來肯定使用哪一種編碼,也就是說,只會使用三種中的一種編碼方式,不會嵌套使用。
序列編碼基於先後兩個數據的差值大部分都相同的一種編碼方式,當差值計算出來以後,能夠再分析其數據特徵肯定再使用前面三種編碼方式。
綜上所述,這四種編碼策略以下:
「
」
除了採用編碼進行壓縮外還能夠對區採用QUICKLZ或1-9級LZ算法進一步壓縮,二者能夠同時存在,也就是對編碼後的存儲結構進一步二進制壓縮。
經過以上壓縮算法,一般能夠將數據壓縮幾倍,若是運氣好(數據有序、重複值不少等)壓縮率可達數百倍。目前CPU性能發展很快,而存儲性能提高有限,特別是大數據處理領域不大可能大規模使用SSD。解壓引發的性能損失遠遠小於磁盤IO等待的開銷。
Q&A
Q1:智能索引針對的數據類型和長度有限制嗎?
A1:「智能索引」不能用於大字段類型如BLOB,CLOB,其它達夢支持的基本數據類型均可以利用「智能索引」。
Q2:字典壓縮算法的字典有大小限制嗎?會根據列中數據量變化嗎?字典創建在列上仍是區上呢?
A2:區是列的子集,若是數據庫採用字典編碼去壓縮一個區,則這個區維護一個字典,字典會根據數據量變化。好比這個區有1000個不一樣值,則字典就有1000個值。有1萬個不一樣值,則字典就有1萬個值。字典編碼有大小限制,若是系統判斷採用字典壓縮算法後,壓縮率達不到閥值會放棄採用該編碼壓縮。
Q3:首先,在HTS目錄下建立這個表對應的模式目錄。目錄名爲「SCH+長度爲9的ID號」組成的字符串。9位的ID號,是指表的tabid麼 ?
A3:SCH+9位ID,那個ID是模式的編碼號。
Q4:若是字段值爲20000000000000000xxxxxxxx,這種數據類型,智能索引是否還會生效?
A4:會生效,只有數據很亂的時候纔不生效。好比全部的區最大值最小值都很相近,好比都是1到10000000000,則沒法利用智能索引。
Q5:數據字段中如有大量的空值,請問這種壓縮策略能不能有很好的壓縮率?如何實現?
A5:在達夢數據庫裏也是一個特殊字符,在列存裏同其它數據處理。也是根據數據的實際狀況選擇編碼方式壓縮。通常大量同一個字符,壓縮率通常都很好。
Q6:請問下收費規則如何?支持數據倉庫嗎?對經典的多對多關係怎麼拆分?
A6:數據庫的收費規則得諮詢銷售,不過確定比Oracle便宜。數據倉庫能夠基於咱們構建,你說的多對多關係拆分能夠線下討論。
Q7:和Oracle兼容性如何?
A7:達夢在DML類語句上,100%兼容Oracle語法。PL/SQL大部分都兼容。若是DML語句發現有不兼容的地方告訴咱們,咱們立馬改了。PL/SQL不兼容的看狀況,對於經常使用的語法和Oracle是兼容的,很冷門的包若是沒有項目推進,通常不會主動去兼容。
Q8:達夢是基於開源數據庫改的麼?
A8:徹底自主開發、自主原創,源代碼都是咱們本身寫的。
做者介紹 李鵬
http://www.58maisui.com/2016/06/17/a-218/