MongoDB的索引策略分析 /1

近期換了工做,新公司在數據持久化的方面的技術棧用到了MongoDB,遂有了這篇內容,旨在學習Mongo的同時,對Mongo的一些設計進行刨析分解。本篇主要側重於MongoDB的索引存儲策略與傳統關係型數據庫Mysql的對比與差別緣由。sql

索引存儲結構

​ 談及索引,對於目標檢索的過程次數以及I/O次數是存儲結構權衡優劣的關鍵。在Mysql(Innodb)中,咱們的聚簇索引、二級索引默認都是由B+樹進行索引的存儲管理。而在MongoDB中,則採用了B樹進行索引的構建。對於兩者的孰優孰劣暫不論定,咱們先得弄明白這兩種數據結構的優點和劣勢分別在哪。接下來內容可能會比較偏基礎,關於Mysql的部分我會配合着一些基礎結構進行分析(由於目前更熟悉一點的仍是Mysql)。數據庫

​ B-Tree、B+tree能夠說是爲磁盤或其它存儲工具而生,不一樣於基礎的二叉搜索樹,B-樹,B+樹都有着矮胖的特徵,而咱們都知道磁盤在讀取數據時是以塊爲基礎單位,矮胖的特徵意味着一個盤塊內能夠存放更多的內容,在查找數據的過程當中得以減小盤塊的讀取次數。網絡

B+樹

​ B+樹是Mysql(InnoDB)的默認索引結構,包括聚簇索引和二級索引。而其存儲的方式也很簡單明瞭,Mysql定義了不少種類型的頁面以存放各類數據譬如說Undo日誌頁(FIL_PAGE_UNDO_LOG)、系統頁(FIL_PAGE_TYPE_SYS)、段信息頁(FIL_PAGE_INODE),還有咱們最基本的存放數據的頁叫索引頁或者數據頁(FIL_PAGE_INDEX),而索引頁中的數據,在數據頭的數據結構有一個字段叫record_type用於標註數據類型,0表明非葉子節點記錄,1表明普通記錄。聽到這裏是否是比較熟悉,讓咱們來看看一個Mysql存放一張表的數據結構是怎樣的。數據結構

​ 基本的東西我已經在圖上標出來了,雖然已經略去了不少信息,可是大致結構你們能夠意會一下。能夠從圖上看到數據之間經過指針關聯,在葉子節點頁面間也經過指針關聯,主鍵有序排列,這就是咱們Mysql數據存儲數據所構建的一個聚簇索引,二級索引把主鍵替換爲索引列,數據替換爲數據主鍵就行了。從大致結構上看就是一個標準的B+樹,即非葉子節點只存放主鍵範圍,而葉子節點存放主鍵和數據,葉子節點間經過指針相互鏈接。經過以上結構咱們也能夠看出一些問題。工具

  • 非葉子節點因爲不存儲具體數據,因此能夠存放更多的主鍵範圍指向,即咱們每次IO能夠搜索更多數據。
  • 全部的數據所有存放在葉子節點,非葉子節點只負責索引的工做,因此每次查詢的時間複雜度都固定在了O(logn)
  • 在葉子節點部分還經過指針將葉子節點串聯起來,而葉子節點間的數據也是有序的,因此提升了區間範圍的搜索訪問性、

B樹

​ B+樹實際上是基於B樹的矮胖基礎形態下,添加了【非葉子節點不存儲具體數據內容,只存放索引】、【葉子節點存放所有數據並使用指針鏈接】兩種特性。換句話說,B樹的全部節點都存放數據,節點的左子樹小於當前節點值,右子樹大於當前節點值。學習

MongoDB是一種面向文檔的數據庫管理系統,與傳統關係型數據庫譬如Mysql不一樣的是Mysql的數據是扁平化的,構建結構化的數據每每須要經過連表查詢在業務中進行組合。而MongoDB是面向文檔的數據庫,數據在存儲階段就是結構化的,聚合的。優化

​ 咱們能夠看一下Mongo的數據存儲結構是怎樣的(按照理解畫的)。設計

​ Mongo在索引上也區分爲主鍵索引和非主鍵索引,這方面與Mysql的聚簇索引和二級索引相似,主鍵索引儲存主鍵以及數據內容,非主鍵索引儲存索引列數據以及主鍵。從數據存儲結構圖來進行分析,咱們大體能得出如下幾個結論:指針

  • 搜索從根節點開始,因爲B樹全部節點都會負責數據存儲的工做。因此搜索的時間複雜度和數據在結構中的位置強相關,最好的狀態是數據在根節點中就搜索到了,能夠直接返回,時間複雜度是O(1)。即從平均搜索速度來看MongoDB查詢速度會比Mysql更快
  • 單純從存儲結構上看,數據的存儲分佈在各個節點,所以若是須要對數據進行遍歷,則須要對整個樹進行數據的讀取。可是從總體的角度層面來看,MongoDB的數據是結構化存儲,全部的數據均可以以聚合的方式進行存儲,對於數據的遍歷需求並無關係型數據庫那麼高。在數據的存儲底層,Mongo使用的也是BSON(Binary Json)進行存儲,在類型支持和網絡傳輸效率上相較於Json也有了很大的提高。

小結

​ 本篇咱們從傳統的關係型數據庫和非關係型數據庫的視角作了對比,瞭解了Mongo在數據存儲方面使用的結構,以及與關係型數據庫在存儲方面的差別。數據結構同技術同樣沒有優劣之分,適合的纔是最好的。Mongo做爲非關係型數據庫,在效率的綜合考量上採用了b-tree和bson進行搭配使用,也在搜索速度上達到了一個不差的水平。日誌

​ 以上就是個人一個對於Mongo的初步概覽,後續對於Mongo的具體索引模式,以及一個索引優化的思路也會有些總結,對內容中有疑問、錯誤的部分也歡迎你們指正,交流。

尾巴

​ 最近換了工做,新公司從各方面來看都很好,我也須要花上一些時間精力去融入公司,融入項目。可能與年終總結中定下按期更新博客內容有些衝突,時間沒有那麼肯定。可是至少一月兩篇的原創內容仍是會盡可能去保證的。2020年對於我來講也是個新開始,總之,加油。

相關文章
相關標籤/搜索