mysql id自动递增两个_浅析Mysql索引数据结构演变,让你一看就懂
前言
相信小伙伴應該都用到過mysql數據庫,在mysql數據庫中,為了提升查詢效率,都會使用到索引技術。今天老顧就來介紹一下mysql索引的數據結構的演變。
數據查詢
我們來看一下有個用戶表,存放這基本的用戶信息
需求要我們找出id為51的用戶信息
如果我們是mysql開發工程師的話,怎么設計數據庫的查詢,最簡單做法就是一個個比較id,是否等于51,然后在返回給用戶。這種方式會存在很大的問題:
1、運氣好的話 比較1次直接返回2、運氣差的話 比較7次才能返回
這個方案就是全部遍歷的方式,從第一條記錄開始遍歷,一直遍歷下去。我們這么才7條記錄,如果幾百萬條,那查詢性能太低了。
二叉樹
為了解決這個問題,我們引入索引技術,改變一些數據存儲結構。首先想到的結構,就是二叉樹。
二叉樹的特點:1、一個節點只能有兩個子節點,也就是一個節點度不能超過2
2、左子節點 小于 本節點;右子節點大于等于 本節點
我們看一下上面的數據,以id為索引,建立的二叉樹的結構是什么?
因為二叉數的特點,右邊比左邊大,這次我們查詢id=51,只需要比較3次,因為有一部分數據是不需要比較的,再索引建立的時候就已經排序好了。
這個二叉樹比之前的遍歷的方案,性能提高了很多。但他也有一個問題,如果id的值是持續遞增的話,會是什么樣的結構?我們發現如果id是持續遞增的話,我們的二叉樹結構出現了殘缺,如果這個時候查找id=5,也是從一直遍歷到最后,沒有像之前的數據那樣,排除掉一部分數據。那怎么解決?
紅黑樹
紅黑樹的出現就可以解決這個問題,紅黑樹的特點會自動平衡樹,其他特點(小伙伴們自行度娘)。我們看一下紅黑樹怎么平衡?
上面兩個圖,左圖在插入數值為3時,紅黑樹的算法發現有偏向,就會重新調整樹結構;調整到右邊的圖
那我們可以看看,之前的數據1~6持續遞增的樹,會變成什么樣
我們看到紅黑樹的結構,這樣我們再次查找數據為5,只需要比較3次,有部分數據被提前排序了。紅黑樹很好的平衡了樹的偏向問題,但紅黑樹問題也比較大。
1、每次都要檢查規則,再把樹進行重新平衡,這個是非常消耗時間的2、數據量大的話,紅黑樹的深度會比較深,樹一旦深就代表著我們讀取磁盤次數就會增加B樹
小伙伴們有沒有發現,影響數據查詢時間的是樹的高度,高度越高,我們需要比較的次數越多,那我們是不是可以想辦法把樹的高度弄低點?那我們的B樹數據結構就由此產生。
B樹的特點
假如當前有一顆m階的B樹(注意階的意思是指每個節點的孩子節點的個數),那么其符合
(1)每個節點最多有m個子節點(2)除了根節點和葉子節點之外,其他的每個節點最少有m/2(向上取整)個孩子節點
(3)根節點至少有兩個孩子節點,(除了第一次插入的時候,此時只有一個節點,根節點同時是葉子節點)
(4)所有的葉子節點都在同一層
(5)有k個子節點的父節點包含k-1個關鍵碼
(6)所有的葉節點都在同一層
(7)每個節點中的子節點都是從左到右排序的
小伙伴們是不是看到這個比較暈,這么多的特點(其實還有更多性質,老顧也記不住);其實我們不需要記住這么多的特點,只要記住幾個核心點,先看圖
我們的主要目標就是把樹的高度弄低,上圖中,我們可以看到之前的一個節點里面多了幾個子節點(即幾階樹)【核心點一】,這樣的設計就是把之前節點只存儲1個數值,現在可以存儲多個數值。
多個子節點數值都是從左到右排序【核心點二】,有便于快速查找。而且葉節點具有相同的深度,保證了每個數值查詢效率一致【核心點三】。圖中每個節點里面都包含具體信息data【核心點四】,再查詢的時候找到對應的索引后,直接取出這個節點中的信息。
B樹的核心思想就是把樹高度弄低,用了樹節點包含多個子節點的設計思想,上圖中一個樹節點包含3個子節點。小伙伴有沒有過這個想法,那我們可以把樹節點包含更多子節點,10個、100個、甚至1萬個,這樣就讓樹高度越來越小,甚至就只有一個樹根節點,這樣不是更好嗎?往下看
硬盤原理
這里就涉及到計算機原理的知識了,用通俗的圖表示一下
讀取數據流程主要交給磁頭和磁盤,我們的數據存放在每個扇區中,要讀取一個扇區數據,需要把磁頭移動到相應的磁道上面,然后磁盤快速旋轉,從而讀取到里面值。(詳細知識自行度娘)
整個過程磁頭尋道是比較慢的,我們與硬盤的交互盡量減少尋道這個動作上面小伙伴有個疑問,我們能否擴大樹節點中的子節點數,甚至只有一個根節點就行了。這個是不行的,因為小伙伴們不要忘了,內存也是有限的,所有數據存儲在一個根節點中,數據量一旦上億就吃不消了。其實本質還有一個基本知識就是【磁盤有預讀機制,每次讀的時候都是加載一個磁盤頁到內存里面】,這話的理解就是一次磁盤I/o讀取只能讀一個磁盤頁大小(4kb)的數據到內存中,也就是8kb的數據,要磁盤i/o的2次操作。
就是因為這個磁盤預讀機制,也就是不可能樹的節點隨便我們設置,應該樹節點的數據量正好是一個磁盤頁的大小,這樣效率最高,一次IO讀取一個樹節點。
B+樹
有了上面的知識鋪墊,終于到了這里。我們來看一下上面的B樹,一個樹節點我們應該盡可能的包含更多的子節點,但又不能超過一個磁盤頁(4kb)的大小。
我們小伙伴們是不是想到進一步的優化點,我們發現B樹的節點中還包含了一些關鍵字信息data,這個data也占據著一定的數據量,我們是不是可以把data去掉,這樣就又能多加幾個子節點了。這也就是B+樹的核心思想,看圖
圖中可以看出所有data信息都移動了子節點中,而且子節點和子節點之間會有個指針指向,這個也是B+樹的核心點,這樣可以大大提升范圍查詢效率,也方便遍歷整個樹。
這樣的設計又大大的減少了樹的高度,一般B+樹的階數(樹節點包含的子節點數)不會超過100,這樣一般保證樹的高度在3~5層而已,查詢速度大大的提升。總結
到了這里應該知道為什么Mysql的索引結構采用了B+樹了吧,算法和數據結構一直在演變中。老顧這里再留一個面試題,為什么InnoDB表必須有主鍵,并且推薦使用整型的自增主鍵,為什么不推薦用UUID?小伙伴結合上面知識想想,謝謝!
最后讀到這的朋友可以點贊關注下,以后還會更新更多精選文章分享給大家,歡迎大家在評論區留言討論!
總結
以上是生活随笔為你收集整理的mysql id自动递增两个_浅析Mysql索引数据结构演变,让你一看就懂的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 什么是军队安全?
- 下一篇: 23年部队文职什么时候出成绩