MySQL(一)InnoDB 記錄存儲(chǔ)結(jié)構(gòu)

InnoDB 記錄存儲(chǔ)結(jié)構(gòu)

  1. 頁(yè)是MySQL中磁盤和內(nèi)存交互的基本單位,也是MySQL是管理存儲(chǔ)空間的基本單位。

  2. 指定和修改行格式的語(yǔ)法如下:

    CREATE TABLE 表名 (列的信息) ROW_FORMAT=行格式名稱
    
    ALTER TABLE 表名 ROW_FORMAT=行格式名稱
    
  3. InnoDB目前定義了4種行格式

    • COMPACT行格式

      具體組成如圖:

      • 變長(zhǎng)字段長(zhǎng)度列表存放的是每個(gè)變長(zhǎng)字段存儲(chǔ)的字節(jié)數(shù),通過(guò)字符數(shù)*每個(gè)字符占用的字節(jié)來(lái)記錄
      • null值列表存的是該條記錄哪幾列為null(逆序),比如第三第四列為空,主鍵列NOT NULL,第二列標(biāo)記為NOTNULL,則這個(gè)標(biāo)志位為000001(c4)1(c3)0(0x06)
  • Redundant行格式

    具體組成如圖:

  • Dynamic和Compressed行格式

    這兩種行格式類似于COMPACT行格式,只不過(guò)在處理行溢出數(shù)據(jù)時(shí)有點(diǎn)兒分歧,它們不會(huì)在記錄的真實(shí)數(shù)據(jù)處存儲(chǔ)字符串的前768個(gè)字節(jié),而是把所有的字節(jié)都存儲(chǔ)到其他頁(yè)面中,只在記錄的真實(shí)數(shù)據(jù)處存儲(chǔ)其他頁(yè)面的地址。

    另外,Compressed行格式會(huì)采用壓縮算法對(duì)頁(yè)面進(jìn)行壓縮。

  • 一個(gè)頁(yè)一般是16KB,當(dāng)記錄中的數(shù)據(jù)太多,當(dāng)前頁(yè)放不下的時(shí)候,會(huì)把多余的數(shù)據(jù)存儲(chǔ)到其他頁(yè)中,這種現(xiàn)象稱為行溢出。如果某個(gè)字段長(zhǎng)度大于了16KB,該記錄在單個(gè)頁(yè)面中無(wú)法存儲(chǔ)時(shí),InnoDB會(huì)把一部分?jǐn)?shù)據(jù)存放到所謂的溢出頁(yè)中。記錄的真實(shí)數(shù)據(jù)處只會(huì)存儲(chǔ)該列的前768個(gè)字節(jié)的數(shù)據(jù)和一個(gè)指向其他頁(yè)的地址,然后把剩下的數(shù)據(jù)存放到其他頁(yè)中,這個(gè)過(guò)程也叫做行溢出,存儲(chǔ)超出768字節(jié)的那些頁(yè)面也被稱為溢出頁(yè)

每一條數(shù)據(jù)的結(jié)構(gòu):

這些二進(jìn)制位代表的詳細(xì)信息如下表:

名稱 大小(單位:bit) 描述
預(yù)留位1 1 沒(méi)有使用
預(yù)留位2 1 沒(méi)有使用
delete_mask 1 標(biāo)記該記錄是否被刪除
min_rec_mask 1 B+樹(shù)的每層非葉子節(jié)點(diǎn)中的最小記錄都會(huì)添加該標(biāo)記
n_owned 4 表示當(dāng)前記錄擁有的記錄數(shù)
heap_no 13 表示當(dāng)前記錄在記錄堆的位置信息
record_type 3 表示當(dāng)前記錄的類型,0表示普通記錄,1表示B+樹(shù)非葉子節(jié)點(diǎn)記錄(目錄項(xiàng)記錄),2表示最小記錄,3表示最大記錄
next_record 16 表示下一條記錄的相對(duì)位置

頁(yè)

一個(gè)InnoDB數(shù)據(jù)頁(yè)的存儲(chǔ)空間大致被劃分成了7個(gè)部分,有的部分占用的字節(jié)數(shù)是確定的,有的部分占用的字節(jié)數(shù)是不確定的。

名稱 中文名 占用空間大小 簡(jiǎn)單描述
File Header 文件頭部 38字節(jié) 頁(yè)的一些通用信息
Page Header 頁(yè)面頭部 56字節(jié) 數(shù)據(jù)頁(yè)專有的一些信息
Infimum + Supremum 最小記錄和最大記錄 26字節(jié) 兩個(gè)虛擬的行記錄
User Records 用戶記錄 不確定 實(shí)際存儲(chǔ)的行記錄內(nèi)容
Free Space 空閑空間 不確定 頁(yè)中尚未使用的空間
Page Directory 頁(yè)面目錄 不確定 頁(yè)中的某些記錄的相對(duì)位置
File Trailer 文件尾部 8字節(jié) 校驗(yàn)頁(yè)是否完整

記錄在頁(yè)中的存儲(chǔ)

在頁(yè)的7個(gè)組成部分中,我們自己存儲(chǔ)的記錄會(huì)按照我們指定的行格式存儲(chǔ)到User Records部分。但是在一開(kāi)始生成頁(yè)的時(shí)候,其實(shí)并沒(méi)有User Records這個(gè)部分,每當(dāng)我們插入一條記錄,都會(huì)從Free Space部分,也就是尚未使用的存儲(chǔ)空間中申請(qǐng)一個(gè)記錄大小的空間劃分到User Records部分,當(dāng)Free Space部分的空間全部被User Records部分替代掉之后,也就意味著這個(gè)頁(yè)使用完了,如果還有新的記錄插入的話,就需要去申請(qǐng)新的頁(yè)了,這個(gè)過(guò)程的圖示如下:

被刪除的記錄只是會(huì)標(biāo)記為被刪除,而并不會(huì)從磁盤中刪除調(diào),因?yàn)橹匦屡帕行枰阅芟?。而?huì)在新的記錄插入的時(shí)候(相同id)占用到被刪除的記錄的空間(可重用空間)

? 每個(gè)頁(yè)中的數(shù)據(jù)會(huì)被劃分成幾個(gè)組,每個(gè)組的最后一條記錄的頭信息中的n_owned屬性表示該記錄擁有多少條記錄也就是這個(gè)組有多少條記錄,且把他的地址偏移量單獨(dú)提取出來(lái)按順序存儲(chǔ)到靠近頁(yè)的尾部的地方(頁(yè)目錄,也就是每個(gè)組最后一條記錄的地址偏移量存到頁(yè)目錄的每個(gè)槽中),頁(yè)目錄中的這些偏移量被稱為槽。

? 最小記錄和最大記錄分別是頭尾節(jié)點(diǎn),并不是真實(shí)的數(shù)據(jù)記錄。在一個(gè)組中的記錄數(shù)等于8個(gè)后再插入一條記錄時(shí),會(huì)將組中的記錄拆分成兩個(gè)組,一個(gè)組中4條記錄,另一個(gè)5條記錄。這個(gè)過(guò)程會(huì)在頁(yè)目錄中新增一個(gè)來(lái)記錄這個(gè)新增分組中最大的那條記錄的偏移量。

? InnoDB可能不可以一次性為這么多數(shù)據(jù)分配一個(gè)非常大的存儲(chǔ)空間,如果分散到多個(gè)不連續(xù)的頁(yè)中存儲(chǔ)的話需要把這些頁(yè)關(guān)聯(lián)起來(lái),FIL_PAGE_PREVFIL_PAGE_NEXT就分別代表本頁(yè)的上一個(gè)和下一個(gè)頁(yè)的頁(yè)號(hào)。這樣通過(guò)建立一個(gè)雙向鏈表把許許多多的頁(yè)就都串聯(lián)起來(lái)了,而無(wú)需這些頁(yè)在物理上真正連著。需要注意的是,并不是所有類型的頁(yè)都有上一個(gè)和下一個(gè)頁(yè)的屬性,不過(guò)我們本集中嘮叨的數(shù)據(jù)頁(yè)(也就是類型為FIL_PAGE_INDEX的頁(yè))是有這兩個(gè)屬性的,所以所有的數(shù)據(jù)頁(yè)其實(shí)是一個(gè)雙鏈表,就像這樣

? InnoDB存儲(chǔ)引擎會(huì)把數(shù)據(jù)存儲(chǔ)到磁盤上,但是磁盤速度太慢,需要以頁(yè)為單位把數(shù)據(jù)加載到內(nèi)存中處理,如果該頁(yè)中的數(shù)據(jù)在內(nèi)存中被修改了,那么在修改后的某個(gè)時(shí)間需要把數(shù)據(jù)同步到磁盤中。

單頁(yè)內(nèi)查詢:

根據(jù)主鍵查找的時(shí)候,用的是二分法,先計(jì)算中間槽的位置對(duì)應(yīng)記錄的主鍵值(這個(gè)槽的最后一條記錄),用二分法找到所在的槽,然后找到該槽所在分組中主鍵最小的那條記錄(通過(guò)找到上一個(gè)槽對(duì)應(yīng)的記錄的下一個(gè)節(jié)點(diǎn)),從那條記錄開(kāi)始遍歷該槽所在的組中的各個(gè)記錄。

多頁(yè)查詢:

1、定位記錄所在的頁(yè)(如何定位到頁(yè),就需要用到索引了)

2、在該頁(yè)用單頁(yè)的方法查詢

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容