<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
從結構圖中可以看到,有些部分的佔用位元組數是確定的,有的是不確定的。我們最關心的使用者儲存的記錄,在 User Records部分。
不過,在一開始生成頁的時候,並沒有 User Records 部分。當有新的記錄插入時,就會從 Free Space部分申請一個記錄大小的空間,然後劃分到 User Records 部分,直到 Free Space 全部被 User Records 替代,表示這個頁已經用完。如果還有新的記錄插入,需要申請新的頁。
我覺得這裡可以把這個資料頁當作是書本的頁,書頁上的內容通常是一行行的呈現,當整個頁都用完了,就得翻到下一頁(新頁)去繼續寫了。
那麼,User Records 部分裡的這些記錄,是如何管理的呢?
先來建一張表:
CREATE TABLE pingguo_demo( c1 INT, c2 INT, c3 VARCHAR(10000), PRIMARY KEY (c1) ) CHARSET = ASCII ROW_FORMAT = COMPACT;
這裡的指定使用行格式為 COMPACT(引擎中還存在其他的行格式),暫且知道 COMPACT 即可。
當我們在資料庫的插入了一條記錄後,其實背後的行格式是這樣的:
注意這裡橙色標識的記錄頭資訊,它又包含了很多重要資訊:
現在,向上面新建的表中插入 4 條記錄:
INSERT INTO pingguo_demo VALUES (1, 100, 'aaaa'), (2, 200, 'bbbb'), (3, 300, 'cccc'), (4, 400, 'dddd');
那麼,對應這4條記錄的行格式應該為:
注意,這裡為了便於記憶,作了簡化。另外,記錄中的資訊實際是二進位制位資料,這裡為了理解寫的是十進位制。而且,各條記錄在 User Records 中儲存是沒有空隙的,這裡抽象表示。
這個屬性用來標記當前記錄是否被刪除,1 表示被刪除,0 表示沒有被刪除。
嗯?我表裡刪除了資料居然還在頁裡。
是的,你以為被刪除了,其實還在磁碟上。為什麼呢?
因為如果在磁碟上移除這些記錄,還要再重新排列其他記錄,會帶來效能消耗,所以只打了一個刪除的標記。
然後,所有的刪除的記錄會組成一個垃圾連結串列。而記錄在這個連結串列中所佔用的空間稱為可重用空間,當後面有新記錄插入到表中,它們就可能覆蓋掉這些空間。
在 B+ 樹中每層非葉子節點中的最小的目錄項,都會新增此標記。這裡說的目錄項,要後續講解。
這裡4條記錄的 min_rec_flag 都是 0,表示都不是 B+ 樹非葉子節點中的最小的目錄項記錄。
要下一章講解。
表示當前記錄在頁面堆中的相對位置。
上面的4條記錄是抽象的描述,實際上這些記錄都是一條一條緊密無縫排列在一起的,這就是堆(heap)。
為了方便管理,把一條記錄在堆中的相對位置稱為 heap_no。
上述 4 條記錄的 heap_no 分別為 2、3、4、5,嗯?怎麼沒有 0 和 1?
虛擬記錄-Infimum 和 Supremum
這個在本文第二部分有提到過。其實這2條記錄是頁裡自動新增的:
Infimum:代表頁面中的最小記錄
Supremum:代表頁面中的最大記錄
作者規定,無論向頁中插入了多少條記錄,任何使用者記錄都比 Infimum 記錄大,都比 Supremum 記錄小。
這 2 條虛擬記錄的結構也很簡單。
所以,對於上面插入的 4 條使用者記錄,還應該加上這2個預設記錄,而且位置最靠前。
另外,還需要注意,當堆中記錄的 heap_no 值分配後,就不會發生改動。即使刪除了堆中的某條記錄,這條被刪記錄的 heap_no 值也仍然不變。
這個屬性表示當前記錄的類型,共 4 種:
0:表示普通記錄1:表示 B+ 樹非葉節點的目錄項記錄2:表示 Infimum 記錄3:表示 Supremum 記錄
這個屬性很重要,表示從當前記錄的真實資料到下一條記錄的真實資料之間的距離。
比如,第 1 條記錄的 next_record 值為 32,那麼從此記錄的真實資料地址向後找 32 位元組就是下一條記錄的真實資料。再比如,當值為 -111,那麼就代表從此記錄向前找 111 位元組。
很熟悉?沒錯,就是連結串列。
所以,現在再來重新看下記錄之間的示意圖,可以用單向連結串列來描述了:
如果這時候,刪掉其中的某條記錄,改變的是指針。
本文參考書籍:《mysql是怎樣運行的》
以上就是Mysql InnoDB引擎中的資料頁結構詳解的詳細內容,更多關於Mysql InnoDB引擎資料頁結構的資料請關注it145.com其它相關文章!
" target="_blank">接上一篇,現在知道記錄在頁中按照主鍵大小順序串成了單連結串列。那麼我使用主鍵查詢的時候,最順其自然的辦法肯定是從第一條記錄,也就是 Infrimum 記錄開始,一直向後找,只要存在總會找到。這種在資料量少的時候還好說,一旦資料多了,遍歷耗時一定非常長。
於是,作者又想到了一個好辦法,靈感來自於書本中的目錄。我們翻書的時候想查詢一些內容,就會去檢視目錄,然後直接確定好內容所在的頁碼。
那麼對於 InnoDB 來說,過程如下:
這個地方就是頁目錄 Page Directory。而上述的地址偏移量就是該記錄的真實資料與頁面中第 0 個位元組之間的距離,這些地址偏移量被稱為槽。
每個槽佔用 2 位元組,頁目錄就是由多個槽組成。
在上一篇中,建立的表裡存在 4 條資料,那麼在頁中還要算上 Infimum 和 Supremum,共 6 條記錄。
這時候 InnoDB 會把它們分出 2 個組:
每個槽中,存放著每個組裡最大的那條記錄所在頁面中的地址偏移量。
從圖中,需要關注頁目錄的一些點:
為什麼這 6 條記錄要這樣分?因為作者對於每組中的記錄數量有規定:
現在繼續向測試表裡插入 12 條資料,也就是說在頁中共有 18 條記錄。
然後這些記錄就被分成了 5 個組,這裡參考書籍上的示意圖(只保留一些關鍵屬性):
現在,要查詢主鍵是 6 的記錄,要如何進行?
因為 5 個槽的編號分別為 0、1、2、3、4 挨著的,並且裡面的主鍵值也都是從小到大進行排序的,可以使用二分法(不清楚的可以百度),那麼初始情況下 low=0,high=4:
這裡有個問題,槽對應的值都是這個組的主鍵最大的記錄,如何找到組裡最小的記錄?比如槽 2 對應最大主鍵是 8 的記錄,那如何找到最小記錄。
解決辦法是:
在一個資料頁中查詢指定主鍵值的記錄,過程分為 2 步:
通過二分法確定該記錄所在分組對應的槽,然後找到該槽所在分組中主鍵值最小的記錄。
通過記錄的 next_record 屬性比那裡該槽所在組的各個記錄,最終找到目標記錄。
本文參考書籍: 《mysql是怎樣執行的》
以上就是Mysql InnoDB引擎中頁目錄和槽的查詢過程的詳細內容,更多關於Mysql InnoDB引擎頁目錄的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45