【mysql學習】InnoDB數據結構

原來知道有一些索引失效的條件,最近看了看mysql底層數據結構,明白了爲何會失效 ,記錄之。衆所周知,經常使用的mysql數據引擎有兩種,今天全是以InnoDB爲基礎開啓探索之旅的,另外一種有時間再說吧。mysql

數據頁與數據行

咱們都知道,數據庫數據是存在磁盤中的,不過真正處理數據是在內存中進行的。這就須要從硬盤上不斷地把數據讀到內存中,因爲內存和磁盤速度差了好幾個數量級,因此爲了不頻繁交互帶來的性能問題,mysql一次會多讀取一些,是多少呢?讀一頁。一頁有16KB,也就是說一次讀取通常都是16KB的倍數。頁是硬盤內存交互的基本單位。sql

咱們平時所說的一條記錄叫數據行,InnoDB有四種不一樣類型的數據行,Compact、Redundant、Dynamic和Compressed。主要介紹下Compact數據庫

爲了方便後面說明,建個表:數據結構

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  `age` smallint(3) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=111 DEFAULT CHARSET=utf8;

數據行結構

  • 變長字段長度列表:相似於varchar() 這種可變長度,記錄某個屬性的長度,方便快速讀取某屬性的值。長度值是倒敘存放的。
  • Null值列表:記錄可爲空的那些值,是否爲空。
    爲了方便說明舉例:
id  name    age
99  haha    (null)

1 表示 這個屬性爲null,0表示這個屬性不爲null。因此name對應着0,age對應着1。因爲是倒敘存放的,因此 Null值列表 這個地方存放的是 10(age,name);性能

  • 記錄頭信息
    數據有不少,關鍵的:
    delete_mask:標記該記錄是否被刪除
    record_type:表示當前記錄的類型,0表示普通記錄,1表示B+樹非葉子節點記錄,2表示最小記錄,3表示最大記錄。

接下來就是真實數據了,值得一提的是,還有三個隱藏項搜索引擎

  1. row_id:若是沒有主鍵ID,數據庫會自動生成一個行的標識ID。因此這個值是可選的。
  2. transaction_id:事務ID
  3. roll_pointer:回滾指針。

頁行關係

數據頁內部結構
如上圖所示,是一張數據頁內部結構。一個16KB的頁,內部存放着不少行,好比說那3條記錄,除此以外,內部存放着兩個特殊的記錄,最小記錄最大記錄。數據頁內部記錄之間是以單鏈表的形式存放的,頭尾分別是那兩個特殊的記錄。在內存中有不少頁,頁和頁之間是用雙鏈表鏈接的。這樣方便快速定位到數據在哪一頁上。3d

B+ 索引

聚簇索引

ok,如今知道了數據頁、數據行,和它們之間的數據結構以後,就能夠看看咱們所謂的索引了。正如開頭所說的,這邊只介紹InnoDB的聚簇索引,另外一種搜索引擎,先不提它(嗯,如今甚至連名字都不提)。指針

聚簇索引,就是說有一顆樹,葉子節點就是真實數據行所構成的數據頁。code

聚簇索引
通常爲了搜索快一點,咱們主鍵都是自動生成的(例如我們的User表),因此最下面那層是根據id排序生成的。最底下那層的葉子節點是真實的數據,有4頁,每頁裏面有一個單鏈表,就是咱們的真實數據行。第二行有兩頁,每頁中也是有個數據行構成的單鏈表,這是的數據行只包含了頁碼(最底下那層某頁)、某頁最大id,因而可知,第二行比最底下那行頁數少了不少不少。就這樣,一層一層的抽取,必定會有一個所謂的跟頁。咱們搜索數據就是從跟頁開始的,一層一層往下找的。因爲一個數據頁能夠存放16KB數據,因此三四層的樹狀圖就已經能存放不少不少數據了,因此不要擔憂樹會很深。再強調一下,頁內是單鏈表,同層的頁和頁之間是雙鏈表。blog

二級索引

上面那是以主鍵爲搜索條件的索引,通常這棵樹是自動生成的。

咱們每每還會本身創建索引,好比給age添加索引。與聚簇索引相似,只不過葉子節點存的不是全部數據(而且根據age大小排序),而是存的該age屬性和主鍵id,非葉子節點寸的是頁碼和下面那層某頁最大的age值。這樣,你肯定了要搜的是哪些主鍵,還要回表(拿着這些主鍵回去聚簇索引找)去查詢真實的數據。這邊腦洞一下,即便你給age建立了索引,真正執行的時候,也不必定是經過查看二級索引,再回表的方式查數據(好比說經過二級索引搜索出來的是全部的id,再回表查詢,得不償失啊,還不如直接從聚簇索引直接去搜呢)。也可能根據聚簇索引直接搜索。具體採用哪一種方式mysql本身會評估。

聯合索引

還有種特殊的二級索引,聯合索引,好比說給(name、age)添加聯合索引,底層數據結構和普通二級索引沒什麼區別,只不過葉子節點存的不是全部數據(而且先根據name大小排序,name相同的狀況下再根據age排序),而是存的該name、age屬性和主鍵id,非葉子節點寸的是頁碼和下面那層某頁最大的name值。因此若是搜索條件只有age,沒有name的話,聯合索引會失效,因此要遵循最左原則。

相關文章
相關標籤/搜索