mysql的innodb數據存儲結構


數據庫磁盤讀取與系統磁盤讀取

 

1,系統從磁盤中讀取數據到內存時是以磁盤塊(block)為基本單位,位於同一個磁盤塊中的數據會被一次性讀取出來。

 

2,innodb存儲引擎中有頁(Page)的概念,頁是數據庫管理磁盤的最小單位,innodb存儲引擎中默認每個頁的大小為16kb,每次讀取磁盤時都將頁載入內存中。

 

3,系統一個磁盤塊的大小空間往往沒有16kb這么大,因此innodb每次io操作時都會將若干個地址連續的磁盤塊的數據讀入內存,從而實現整頁讀入內存

 

問題:數據庫的數據結構時怎樣的?B樹和B+樹有什么區別,為什么選擇B+樹作為存儲數據的結構,而不是B樹?

 

B樹和B+樹

 

Btree

 

一個M階的B-tree有如下特點

1,每個節點最多有m個孩子(分叉),

2,除了根節點和葉子節點外,其他每個節點至少有ceil(m/2)個孩子

3,若根節點不是葉子節點,則至少有兩個孩子

4,所有葉子節點都再同一層,且不包含其他關鍵字信息

5,每個非終端節點包含n個關鍵字信息,關鍵字的個數n滿足ceil(m/2)-1<=n<= m-1 其中m為階數

6,ki(i=1,…n)為關鍵字,且關鍵字(主鍵primary key)升序排序。

7,. Pi(i=1,…n)為指向子樹根節點的指針。P(i-1)指向的子樹的所有節點關鍵字均小於ki,但都大於k(i-1);

 

 

 

B-tree每個節點都包含指針,key以及data,每個節點含有三個指向子節點的指針和兩個升序排序的關鍵字(key)

 

模擬查找關鍵字29的過程:

1. 根據根節點找到磁盤塊1,讀入內存。【磁盤I/O操作第1次】

2. 比較關鍵字29在區間(17,35),找到磁盤塊1的指針P2。

3. 根據P2指針找到磁盤塊3,讀入內存。【磁盤I/O操作第2次】

4. 比較關鍵字29在區間(26,30),找到磁盤塊3的指針P2。

5. 根據P2指針找到磁盤塊8,讀入內存。【磁盤I/O操作第3次】

6. 在磁盤塊8中的關鍵字列表中找到關鍵字29。

分析上面過程,發現需要3次磁盤I/O操作,和3次內存查找操作。由於內存中的關鍵字是一個有序表結構,可以利用二分法查找提高效率。而3次磁盤I/O操作是影響整個B-Tree查找效率的決定因素。

B樹上大部分的操作(插入、刪除、查詢)所需要的磁盤存取次數和B樹的高度是成正比的,並且B樹是盡量多的在節點上存儲信息,保證導數盡量少,在B樹中可以檢查多個子結點,由於在一棵樹中檢查任意一個結點都需要一次磁盤訪問,所以B樹避免了大量的磁盤訪問,減少了磁盤I/O。

 

 

B+tree

 

毫無疑問,減少樹的高度是有效減少IO次數提高效率的方式,b-tree結構每個節點不僅包含key值,還有data值,每一個頁的存儲(16kb)是有限的,每個節點可容納的指針和keydata是有,如果data數據含量大,那么一個頁保存的指針和key的數量就會減少,從而增頁節點的數量,這就增加btree的深度,增加讀取磁盤的次數,進而影響查詢效率

 

而在b+tree中,一個節點記錄的都是key值和指針(排除了data值),這樣就可以記錄更多的key值,其key值是升序排序,

 

 

 

B+tree和b-tree有如下不同點

1,非葉子節點只存儲鍵值信息(key信息)

2,所有葉子節點之間都有一個鏈指針,數據都存放再葉子節點中

 

推算

innodb存儲引擎一頁的大小為16kb,一般主鍵類型為int占4個字節,或bigint占8個字節,指針類型頁一般4個或8個字節,也就是說一個頁中大概存儲16*1024/16=1024個key,深度為3的B+tree索引(三頁)可以維護1024*1024*1024=10億條記錄,實際情況每個節點不可能填滿,B+tree的高度一般為2-4曾,mysql的innodb存儲引擎將根節點常駐內存,也就是查找某一鍵值的行記錄最多需要1-3次磁盤IO操作

 

 

頁的概念,

頁是innodb讀取磁盤的最小單位,整頁整頁的讀取

頁分為,數據頁(BTreeNode),Undo頁(undo Log page),系統頁(Systempage),事務數據頁(Transaction SystemPage)每個數數據頁的大小為16kb,每個page使用一個32位int值來表示,

 

一個page的基本結構

 

 

1,0-38:page頭部,id,類型信息等占38個字節,頭部保存兩個指針分別指向前一個page和后一個page,page是一個雙向列表

 

2,38-16376:不同的類型頁所含的數據不同,這部分空間包含系統記錄(SystemRecord)和用戶記錄(UserRecord),我們表中的一條條記錄就放在UserRecord部分,UserRecord存放的內容可以是以下內容

a,主鍵索引樹非葉子節點,B+tree索引,和指針

b,主鍵索引樹葉子節點,key和data(就是記錄本身)

c,輔助鍵索引樹非葉子節點,B+tree輔助索引

d,輔助鍵索引樹葉子節點,key和data(這里的data是主鍵)

頁可以裝很多種數據信息,有的頁是B+樹的所有主鍵索引,有的頁是B+樹的葉子節點也就是數據記錄本身,有的頁是我們創建的二級索引,

 

16376-16384:page尾部

 

頁和節點的關系

頁和節點沒有強相關關系

 

由頁組成的鏈表,頁之間是雙向列表,頁里面的數據是單向鏈表,這種結構組成了主鍵索引B+樹,組成了葉子節點數據。

 

定位一條記錄的過程,select  * from table where id = 29

 

系統經過解析sql語句,首先讀取裝有非葉子節點page頁,遍歷非葉子節點,這個過程隨着節點的遍歷會將一個或多個page頁加載到內存,直到定位到這條記錄的葉子節點,然后遍歷找出該條記錄。

 

如果使用了二級索引則先讀取二級索引page遍歷這個二級索引,找到裝有主鍵信息葉子節點page頁,遍歷找到該主鍵。然后再根據主鍵索引尋找到該條記錄

 

 

 

 https://mp.weixin.qq.com/s?__biz=MzI4NTEzMjc5Mw==&mid=2650554818&idx=1&sn=ff0bd7677c431d42ed2346f1aa4e2b7d&chksm=f3f83354c48fba4293a6d0f7bab8aa5744ffaa31a0c42f5419fee63fcbb7f0658413850f5399&token=1663379705&lang=zh_CN#rd

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM