欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Mysql?InnoDB引擎中的數(shù)據(jù)頁結(jié)構(gòu)詳解

 更新時(shí)間:2022年05月31日 10:34:55   作者:把蘋果咬哭的測試筆記  
這篇文章主要為大家介紹了Mysql?InnoDB引擎中的數(shù)據(jù)頁結(jié)構(gòu)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

Mysql InnoDB引擎數(shù)據(jù)頁結(jié)構(gòu)

InnoDB 是 mysql 的默認(rèn)引擎,也是我們最常用的,所以基于 InnoDB,學(xué)習(xí)頁結(jié)構(gòu)。而學(xué)習(xí)頁結(jié)構(gòu),是為了更好的學(xué)習(xí)索引。

一、頁的簡介

頁是 InnoDB 管理存儲空間的基本單位,一個頁的大小一般是 16kb。

為了達(dá)成不同的目的,作者設(shè)計(jì)了多種類型的頁,比如:

  • 存放表空間頭部信息的頁
  • 存放 change buffer 信息的頁
  • 存放 inode 信息的頁
  • 存放 undo 日志信息的頁
  • ... ...

然而我們最關(guān)心的,還是那些存放進(jìn)表中那些數(shù)據(jù)記錄是在哪種頁上,官方稱這種存放記錄的頁為索引(INDEX)頁,但是為了便于理解,本篇暫把它稱為數(shù)據(jù)頁。

二、數(shù)據(jù)頁的結(jié)構(gòu)

這數(shù)據(jù)頁也有 16kb 的存儲空間,可以大致劃分為 7 個部分。

從結(jié)構(gòu)圖中可以看到,有些部分的占用字節(jié)數(shù)是確定的,有的是不確定的。我們最關(guān)心的用戶存儲的記錄,在 User Records部分。

不過,在一開始生成頁的時(shí)候,并沒有 User Records 部分。當(dāng)有新的記錄插入時(shí),就會從 Free Space部分申請一個記錄大小的空間,然后劃分到 User Records 部分,直到 Free Space 全部被 User Records 替代,表示這個頁已經(jīng)用完。如果還有新的記錄插入,需要申請新的頁。

我覺得這里可以把這個數(shù)據(jù)頁當(dāng)作是書本的頁,書頁上的內(nèi)容通常是一行行的呈現(xiàn),當(dāng)整個頁都用完了,就得翻到下一頁(新頁)去繼續(xù)寫了。

三、記錄在頁中的存儲結(jié)構(gòu)

那么,User Records 部分里的這些記錄,是如何管理的呢?

先來建一張表:

CREATE TABLE pingguo_demo(
	c1 INT,
	c2 INT,
	c3 VARCHAR(10000),
	PRIMARY KEY (c1)
	) CHARSET = ASCII ROW_FORMAT = COMPACT;

這里的指定使用行格式為 COMPACT(引擎中還存在其他的行格式),暫且知道 COMPACT 即可。

當(dāng)我們在數(shù)據(jù)庫的插入了一條記錄后,其實(shí)背后的行格式是這樣的:

注意這里橙色標(biāo)識的記錄頭信息,它又包含了很多重要信息:

  • 預(yù)留位1:占用 1 比特,沒有使用。
  • 預(yù)留位2:占用 1 比特,沒有使用。
  • deleted_flag:占用 1 比特,標(biāo)記該記錄是否被刪除。
  • min_rec_flag:占用 1 比特,在 B+ 樹(后面索引會講到)中每層非 葉子節(jié)點(diǎn)中的最小的目錄項(xiàng),都會添加此標(biāo)記。
  • n_owned:一個頁面中的記錄被分為若干個組,每個組里有一個記錄是“大哥”,其他記錄都是“小弟”。而這位“大哥”記錄的 n_owned 就是所在組的所有記錄條數(shù),而小弟們的 n_owned 都是 0
  • heap_no:占用 13 比特,表示當(dāng)前記錄在頁面堆中的相對位置。
  • record_type:占用 3 比特,表示當(dāng)前記錄的類型,0是普通記錄,1是 B+樹非葉節(jié)點(diǎn)的目錄項(xiàng)記錄,2是 Infimum 記錄,3是 Suprememum 記錄。
  • next_record:占用 16 比特,表示下一條記錄的相對位置。

四、記錄頭信息

現(xiàn)在,向上面新建的表中插入 4 條記錄:

INSERT INTO pingguo_demo VALUES
	(1, 100, 'aaaa'),
	(2, 200, 'bbbb'),
	(3, 300, 'cccc'),
	(4, 400, 'dddd');

那么,對應(yīng)這4條記錄的行格式應(yīng)該為:

注意,這里為了便于記憶,作了簡化。另外,記錄中的信息實(shí)際是二進(jìn)制位數(shù)據(jù),這里為了理解寫的是十進(jìn)制。而且,各條記錄在 User Records 中存儲是沒有空隙的,這里抽象表示。

1. deleted_flag

這個屬性用來標(biāo)記當(dāng)前記錄是否被刪除,1 表示被刪除,0 表示沒有被刪除。

嗯?我表里刪除了數(shù)據(jù)居然還在頁里。

是的,你以為被刪除了,其實(shí)還在磁盤上。為什么呢?

因?yàn)槿绻诖疟P上移除這些記錄,還要再重新排列其他記錄,會帶來性能消耗,所以只打了一個刪除的標(biāo)記。

然后,所有的刪除的記錄會組成一個垃圾鏈表。而記錄在這個鏈表中所占用的空間稱為可重用空間,當(dāng)后面有新記錄插入到表中,它們就可能覆蓋掉這些空間。

2. min_rec_flag

在 B+ 樹中每層非葉子節(jié)點(diǎn)中的最小的目錄項(xiàng),都會添加此標(biāo)記。這里說的目錄項(xiàng),要后續(xù)講解。

這里4條記錄的 min_rec_flag 都是 0,表示都不是 B+ 樹非葉子節(jié)點(diǎn)中的最小的目錄項(xiàng)記錄。

3. n_owned

要下一章講解。

4. heap_no

表示當(dāng)前記錄在頁面堆中的相對位置。

上面的4條記錄是抽象的描述,實(shí)際上這些記錄都是一條一條緊密無縫排列在一起的,這就是堆(heap)。

為了方便管理,把一條記錄在堆中的相對位置稱為 heap_no。

  • 在頁面前面的記錄 heap_no 相對較小
  • 在頁面后面的記錄 heap_no 相對較大
  • 每申請一條記錄的存儲空間時(shí),該記錄比物理位置在它之前的那條記錄的 heap_no 值大 1

上述 4 條記錄的 heap_no 分別為 2、3、4、5,嗯?怎么沒有 0 和 1?

虛擬記錄-Infimum 和 Supremum

這個在本文第二部分有提到過。其實(shí)這2條記錄是頁里自動添加的:

Infimum:代表頁面中的最小記錄

Supremum:代表頁面中的最大記錄

作者規(guī)定,無論向頁中插入了多少條記錄,任何用戶記錄都比 Infimum 記錄大,都比 Supremum 記錄小。

這 2 條虛擬記錄的結(jié)構(gòu)也很簡單。

所以,對于上面插入的 4 條用戶記錄,還應(yīng)該加上這2個默認(rèn)記錄,而且位置最靠前。

另外,還需要注意,當(dāng)堆中記錄的 heap_no 值分配后,就不會發(fā)生改動。即使刪除了堆中的某條記錄,這條被刪記錄的 heap_no 值也仍然不變。

5. record_type

這個屬性表示當(dāng)前記錄的類型,共 4 種:

0:表示普通記錄1:表示 B+ 樹非葉節(jié)點(diǎn)的目錄項(xiàng)記錄2:表示 Infimum 記錄3:表示 Supremum 記錄

6. next_record

這個屬性很重要,表示從當(dāng)前記錄的真實(shí)數(shù)據(jù)到下一條記錄的真實(shí)數(shù)據(jù)之間的距離。

  • 屬性值為正數(shù):說明當(dāng)前記錄的下一條記錄在當(dāng)前記錄的后面。
  • 屬性值為負(fù)數(shù):說明當(dāng)前記錄的下一條記錄在當(dāng)前記錄的前面。

比如,第 1 條記錄的 next_record 值為 32,那么從此記錄的真實(shí)數(shù)據(jù)地址向后找 32 字節(jié)就是下一條記錄的真實(shí)數(shù)據(jù)。再比如,當(dāng)值為 -111,那么就代表從此記錄向前找 111 字節(jié)。

很熟悉?沒錯,就是鏈表。

  • 下一條記錄,是指按照主鍵從小到大排列的下一條。
  • Infrimum 記錄的下一條記錄,就是本頁中主鍵值最小的用戶記錄。
  • 本頁主鍵值最大的用戶記錄的下一條記錄,就是 Supremum 記錄。

所以,現(xiàn)在再來重新看下記錄之間的示意圖,可以用單向鏈表來描述了:

如果這時(shí)候,刪掉其中的某條記錄,改變的是指針。

本文參考書籍:《mysql是怎樣運(yùn)行的》

以上就是Mysql InnoDB引擎中的數(shù)據(jù)頁結(jié)構(gòu)詳解的詳細(xì)內(nèi)容,更多關(guān)于Mysql InnoDB引擎數(shù)據(jù)頁結(jié)構(gòu)的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論