iT邦幫忙

2021 iThome 鐵人賽

DAY 4
0
自我挑戰組

那些Mysql我不知道的事系列 第 4

認識Innodb儲存引擎

我們知道儲存引擎是實際實現讀取、儲存資料的重要東西
所以今天就來針對Innodb(MySQL的預設引擎)來探討,更深入的了解它的細節,幫助我們未來面對不同的場景,更有概念去解決問題。

Innodb簡介

Innodb把資料儲存在磁碟,所以在server重啟的時候,資料依然都在。
要注意的是它會先把資料從磁碟讀出放到記憶體,實際上處理資料都是在記憶體這端,處理完再將資料寫回磁碟。由於讀取磁碟的速度遠遠慢於讀取記憶體的速度,如果Innodb把資料一筆一筆從磁碟讀取到記憶體裡的話會慢死,因此MySQL設計者將資料劃分為許多頁的概念,磁碟與記憶體互動的最小單位就是一頁,一頁的大小一般為16kb,也就是說每次會從磁碟讀取一頁(16kb)的資料到記憶體,每次也是更新一頁(16kb)的資料回磁碟。

Innodb行格式

前面提到Innodb將資料儲存在磁碟中,這些存於磁碟中資料的格式也就是所稱的行格式,總共有四種compact、redundant、dynamic、compressed。先稍微知道就好,不用硬記。

可以這樣建立compact行格式的table

mysql> create database ryan_demo_db character set utf8mb4 collate utf8mb4_0900_ai_ci;
Query OK, 1 row affected (0.03 sec)

mysql> use ryan_demo_db;
Database changed
mysql> create table ryan_demo_table (c1 varchar(10), c2 varchar(10) not null, c3 char(10), c4 varchar(10)) charset=ascii row_format=compact;
Query OK, 0 rows affected (0.18 sec)

mysql> insert into ryan_demo_table(c1,c2,c3,c4) values ('aaaa','bbb','cc','d'),('eeee','fff',NULL,NULL);
Query OK, 2 rows affected (0.02 sec)
Records: 2  Duplicates: 0  Warnings: 0

mysql> select * from ryan_demo_table;
+------+-----+------+------+
| c1   | c2  | c3   | c4   |
+------+-----+------+------+
| aaaa | bbb | cc   | d    |
| eeee | fff | NULL | NULL |
+------+-----+------+------+
2 rows in set (0.00 sec)

補充說明:
在建立資料庫的時候如果不是版本8.0的話,照著我的語法下可能會失敗,應是字元集或校對規則名稱不同,請自行更新為符合你版本的唷。

Innodb行格式-compact

先有認知一筆紀錄實際上包含2個部分(真實資料及額外資訊)
真實資料大家理解沒有問題,但額外資訊有什麼呢?
主要有3個部分

  1. 變長欄位長度列表
  2. NULL值列表
  3. 紀錄標頭資訊

我知道這些雖然是中文字,但根本不知道在說什麼...
來~我們一個一個來看

第一個變長欄位長度列表
首先對資料型態要有基本認知,參考這篇
可知道資料分為儲存位元組不固定(可變式)的資料(ex : varchar、text等)及儲存位元組固定的資料(ex : int、date等)。因此MySQL針對可變式資料額外增加一個變長欄位長度列表,為的就是紀錄實際需要多少位元組來儲存。

第二個NULL值列表
新增一筆資料時,有時許多欄位都是NULL值,如果這些值都存在真實資料的位置很佔空間,所以設了一個NULL值列表來儲存避免浪費。

第三個標頭資訊(很重要,在後續如何查詢資料上會用得到)
這邊是由5個位元組也就是40個位元組成。
全部有以下8種欄位

  1. 預留位元1
  2. 預留位元2
  3. deleted_flag(標記紀錄是否被刪除)
  4. min_rec_flag(B+樹的每層非葉子節點中最小的目錄項紀錄都會增加該標記)(看不懂是正常的,後續會再詳細說明,知道有這參數就好)
  5. n_owned(一個頁面中的紀錄會被分成很多組,每組中有一個帶頭大哥,其餘紀錄都是小弟,帶頭大哥紀錄的n_owned值代表該組所有的紀錄筆數,小弟紀錄的n_owned值都為0)
  6. heap_no(表示目前紀錄在頁面堆疊中的相對位置)
  7. record_type(表示目前的紀錄類型。0:普通紀錄、1:B+樹非葉子節點的目錄項紀錄、2:Infimum紀錄、3:Supermum紀錄)(看不懂是正常的,後續會再詳細說明,知道有這參數就好)
  8. next_record(下一筆紀錄的相對位置)

至於redundant、dynamic、compressed也是類似的概念,由於我感覺還不是特別重要,就不在這多贅述。

由於內容繁多避免消化不良,今日就只介紹Innodb的主要儲存行格式,明日在說明重要的資料頁結構,了解實際上儲存資料的細節。

敬請期待


上一篇
既熟悉又陌生的字元集與比較規則
下一篇
Innodb資料頁結構-Part1(使用者紀錄、空閒空間、頁面中最小與最大的紀錄)
系列文
那些Mysql我不知道的事30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言