日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長提供免費收錄網(wǎng)站服務(wù),提交前請做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

InnoDB如何存儲數(shù)據(jù)

MySQL支持多種存儲結(jié)構(gòu),我們常用的就是InnoDB,前面我們在 前面的 " MySQL 的 NULL 值是怎么存放的 " 一文中已經(jīng)知道記錄是按照行來存儲的,數(shù)據(jù)讀取并不是以行為單位進行讀取的,因為這樣效率非常低,InnoDB 是以數(shù)據(jù)頁為單位進行讀取的。

也就是說,當(dāng)用戶只需要讀取一條記錄的時候,并不是將這個記錄從磁盤中讀出,而是以頁為單位,將記錄所在的頁整體讀入內(nèi)存。

InnoDB 數(shù)據(jù)頁默認(rèn)大小是16KB。

數(shù)據(jù)頁結(jié)構(gòu)分為7個部分,如下圖:

 

數(shù)據(jù)頁7個部分作用說明

字段

說明

File header 文件頭部

頁的一些通用信息

page header 頁面頭部

頁的狀態(tài)信息

infimum + supremum 最大、最下記錄

兩個虛擬的偽記錄,頁中最大、最小記錄

User records 用戶記錄

用戶存儲行的記錄內(nèi)容

Free space 用戶空間

頁中還沒有被使用的空間

Page Directory 頁目錄

頁中某些記錄相對的位置(對記錄索引作用)

FileTrailer 文件尾部

校驗頁是否完整

File header

在 File Header 中有兩個指針,分別指向上一個數(shù)據(jù)頁和下一個數(shù)據(jù)頁,連接起來的頁相當(dāng)于一個雙向的鏈表,如下圖所示:

 

采用鏈表的結(jié)構(gòu)是讓數(shù)據(jù)頁之間不需要是物理上的連續(xù)的,而是邏輯上的連續(xù)。

記錄在頁中的存儲

數(shù)據(jù)頁的主要作用是存儲記錄,也就是數(shù)據(jù)庫的數(shù)據(jù),所以重點說一下數(shù)據(jù)頁中的 User Records 是怎么組織數(shù)據(jù)的。

用戶插入數(shù)據(jù)的時候,記錄會按照行格式存儲到 User records 部分,在一開始的時候,沒有這一部分,每當(dāng)插入一條記錄的時候,都會從Free space 部分劃分到 User records 。

當(dāng) Free space 這部分的空間完全 被 User records這部分替換之后,也就代表著這個數(shù)據(jù)頁用完了。

過程如下:

 

數(shù)據(jù)頁中的記錄按照 主鍵 順序組成單向鏈表,單向鏈表的特點就是插入、刪除非常方便,但是檢索效率不高,最差的情況下需要遍歷鏈表上的所有節(jié)點才能完成檢索。InnoDB是這樣的嗎? 答案:肯定不是啊!

page Directory(頁目錄)

我們平時在查找一本書中的某個內(nèi)容的時候,會怎么做呢?一般會先去看目錄,找到對應(yīng)的頁碼,然后就可以去對應(yīng)的頁碼頁看內(nèi)容了。InnoDB也實現(xiàn)了類似這樣一個目錄。

目錄創(chuàng)建過程如下

  1. 將所有正常的記錄(包括 Infimum Supremum 記錄,但不包括已經(jīng)移除到垃圾鏈表的記錄)劃分為幾個組.
  1. 每個組的最后一條記錄(也就是組內(nèi)最大的那條記錄)相當(dāng)于"帶頭大哥"組內(nèi)其余的記錄相當(dāng)于"小弟。帶頭大哥"記錄的頭信息中的 owned 屬性表示該組內(nèi)共有幾條記錄
  1. 將每個組中最后一條記錄在頁面中的地址偏移量(就是該記錄的真實數(shù)據(jù)與頁面中個字節(jié)之間的距離〉單獨提取出來,按順序存儲到靠近頁尾部的地方,這個地方就是 Page Directory 。頁目錄中的這些地址偏移量稱為槽 (Slot) ,每個槽占用 2 個字節(jié),頁目錄就是由多個槽組成的。

舉個例子

如下圖5 個槽的編號分別為 0,1,2,3,4,我想查找主鍵為 11 的用戶記錄:

  • 先二分得出槽中間位是 (0+4)/2=2 ,2號槽里最大的記錄為 8。因為 11 > 8,所以需要從 2 號槽后繼續(xù)搜索記錄;
  • 再使用二分搜索出 2 號和 4 槽的中間位是 (2+4)/2= 3,3 號槽里最大的記錄為 12。因為 11 < 12,所以主鍵為 11 的記錄在 3 號槽里;
  • 這里有個問題,「槽對應(yīng)的值都是這個組的主鍵最大的記錄,如何找到組里最小的記錄」?比如槽 3 對應(yīng)最大主鍵是 12 的記錄,那如何找到最小記錄 9。解決辦法是:通過槽 3 找到 槽 2 對應(yīng)的記錄,也就是主鍵為 8 的記錄。主鍵為 8 的記錄的下一條記錄就是槽 3 當(dāng)中主鍵最小的 9 記錄,然后開始向下搜索 2 次,定位到主鍵為 11 的記錄,取出該條記錄的信息即為我們想要查找的內(nèi)容。

看到第三步的時候,可能有的同學(xué)會疑問,如果某個槽內(nèi)的記錄很多,然后因為記錄都是單向鏈表串起來的,那這樣在槽內(nèi)查找某個記錄的時間復(fù)雜度不就是 O(n) 了嗎?

這點不用擔(dān)心,InnoDB 對每個分組中的記錄條數(shù)都是有規(guī)定的,槽內(nèi)的記錄就只有幾條:

  • 第一個分組中的記錄只能有 1 條記錄;
  • 最后一個分組中的記錄條數(shù)范圍只能在 1-8 條之間;
  • 剩下的分組中記錄條數(shù)范圍只能在 4-8 條之間。

 

從圖可以看到,頁目錄就是由多個槽組成的,槽相當(dāng)于分組記錄的索引。然后,因為記錄是按照「主鍵值」從小到大排序的,所以我們通過槽查找記錄時,可以使用二分法快速定位要查詢的記錄在哪個槽(哪個記錄分組),定位到槽后,再遍歷槽內(nèi)的所有記錄,找到對應(yīng)的記錄,無需從最小記錄開始遍歷整個頁中的記錄鏈表。

B+ 樹是如何進行查詢

上面都是在說一個數(shù)據(jù)頁中的記錄檢索,因為一個數(shù)據(jù)頁中的記錄是有限的,且主鍵值是有序的,所以通過對所有記錄進行分組,然后將組號(槽號)存儲到頁目錄,使其起到索引作用,通過二分查找的方法快速檢索到記錄在哪個分組,來降低檢索的時間復(fù)雜度。

當(dāng)我們需要存儲大量的記錄時,就需要多個數(shù)據(jù)頁,這時我們就需要考慮如何建立合適的索引,才能方便定位記錄所在的頁。

為了解決這個問題,InnoDB 采用了 B+ 樹作為索引磁盤的 I/O 操作次數(shù)對索引的使用效率至關(guān)重要,因此在構(gòu)造索引的時候,我們更傾向于采用“矮胖”的 B+ 樹數(shù)據(jù)結(jié)構(gòu),這樣所需要進行的磁盤 I/O 次數(shù)更少,而且 B+ 樹 更適合進行關(guān)鍵字的范圍查詢。

InnoDB 里的 B+ 樹中的每個節(jié)點都是一個數(shù)據(jù)頁,結(jié)構(gòu)示意圖如下:

 

通過上圖,我們看出 B+ 樹的特點:

  • 只有葉子節(jié)點(最底層的節(jié)點)才存放了數(shù)據(jù),非葉子節(jié)點(其他上層節(jié))僅用來存放目錄項作為索引。
  • 非葉子節(jié)點分為不同層次,通過分層來降低每一層的搜索量;
  • 所有節(jié)點按照索引鍵大小排序,構(gòu)成一個雙向鏈表,便于范圍查詢;

我們再看看 B+ 樹如何實現(xiàn)快速查找主鍵為 6 的記錄,以上圖為例子:

  • 從根節(jié)點開始,通過二分法快速定位到符合頁內(nèi)范圍包含查詢值的頁,因為查詢的主鍵值為 6,在[1, 7)范圍之間,所以到頁 30 中查找更詳細的目錄項;
  • 在非葉子節(jié)點(頁30)中,繼續(xù)通過二分法快速定位到符合頁內(nèi)范圍包含查詢值的頁,主鍵值大于 5,所以就到葉子節(jié)點(頁16)查找記錄;
  • 接著,在葉子節(jié)點(頁16)中,通過槽查找記錄時,使用二分法快速定位要查詢的記錄在哪個槽(哪個記錄分組),定位到槽后,再遍歷槽內(nèi)的所有記錄,找到主鍵為 6 的記錄。

可以看到,在定位記錄所在哪一個頁時,也是通過二分法快速定位到包含該記錄的頁。定位到該頁后,又會在該頁內(nèi)進行二分法快速定位記錄所在的分組(槽號),最后在分組內(nèi)進行遍歷查找。

總結(jié)

  • InnoDB 的數(shù)據(jù)是按「數(shù)據(jù)頁」為單位來讀寫的,默認(rèn)數(shù)據(jù)頁大小為 16 KB。每個數(shù)據(jù)頁之間通過雙向鏈表的形式組織起來,物理上不連續(xù),但是邏輯上連續(xù)。
  • 數(shù)據(jù)頁內(nèi)包含用戶記錄,每個記錄之間用單向鏈表的方式組織起來,為了加快在數(shù)據(jù)頁內(nèi)高效查詢記錄,設(shè)計了一個頁目錄,頁目錄存儲各個槽(分組),且主鍵值是有序的,于是可以通過二分查找法的方式進行檢索從而提高效率。
  • 為了高效查詢記錄所在的數(shù)據(jù)頁,InnoDB 采用 b+ 樹作為索引,每個節(jié)點都是一個數(shù)據(jù)頁。

分享到:
標(biāo)簽:Mysql
用戶無頭像

網(wǎng)友整理

注冊時間:

網(wǎng)站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨大挑戰(zhàn)2018-06-03

數(shù)獨一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學(xué)四六

運動步數(shù)有氧達人2018-06-03

記錄運動步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績評定2018-06-03

通用課目體育訓(xùn)練成績評定