1. 程式人生 > 其它 >第四章從一條記錄說起——InnoDB的記錄儲存結構

第四章從一條記錄說起——InnoDB的記錄儲存結構

技術標籤:MySQL是怎樣執行的讀書筆記mysql資料庫java

4.1準備工作

儲存引擎主要乾的工作是實現資料的讀取和寫入。

4.2InnoDB頁簡介

InnoDB是將資料儲存在磁碟中的,每次讀取或者寫入資料都會和磁碟互動,但是磁碟I/O速度很慢,所以InnoDB會以頁為單位來與磁碟互動,一般一頁的大小為16KB。

4.3InnoDB的行格式

InnoDB的行格式一般有4種,分別是COMPACT,REDUNDANT,DYNAMIC,
COMPRESSED。

4.3.1指定行格式的語法

行格式的指定語法一般如下:

#可以在建立表的時候指定
CREATE TABLE 表名(屬性) ROW_FORMAT=行格式名稱
#也可以直接修改
ALTER TABLE 表明 ROW_FORMAT=行格式名稱

4.3.2COMPACT行格式

COMPACT行格式的結構如下所示:
在這裡插入圖片描述其中COMPACT的行格式由記錄的額外資訊和記錄的真實資料兩部分組成組成。

1、記錄的額外資訊

  • 變長欄位列表:在MySQL中一般有一些變長的型別,如VARCHAR(M),text,blob等,InnoDB會將非NULL的變長欄位的位元組長度按照列的順序的逆序儲存到變長欄位列表中,而行中儲存真實資料。對於變長欄位是用兩個位元組來儲存變長長度還是用1個位元組儲存遵循以下規則:如果該列能夠儲存的最大位元組數(M(儲存的最大字元數)*W(字符集中每個字元所佔用的最大位元組數))小於等於256時直接採用1個位元組儲存,如果大於256時,假設實際儲存的長度L小於等於127時,便採用1個位元組,否者用2個位元組,因為此時如果是需要用1位來作為標誌位標誌是讀取1個位元組還是2個位元組。除此之外,當某個欄位的資料特別多的時候,可能採用溢位頁來儲存剩下的資料。由於每頁最多為16KB即16384位元組,所以兩個位元組一定能表示出該欄位的長度。
  • NULL值列表:將可以將為NULL值的列按列的順序的逆序儲存到NULL值列表中,其中如果該位為NUll值,便將該位對應的值設定為1,並且高位補0。
  • 記錄頭資訊:由5個位元組固定表示,來描述記錄的一些屬性。如該記錄是否被刪除,是否是目錄項等。

2、記錄的真實資料

  • 對於記錄的真實資料中除了顯示出來的列之外,還有row_id,trx_id,roll_pointer三列隱藏列。

    列名作用
    row_id行ID唯一標識1行
    trx_id事務ID
    roll_pointer回滾指標

    注意:InnoDB中一定有主鍵,如果未人為設定了主鍵,便選取非空的唯一鍵作為主鍵,此時都不會新增row_id否者用row_id充當主鍵。

3、CHAR(M)列的儲存格式:當CHAR(M)的欄位採用變長編碼時,也會將其在變長欄位長度列表中記錄該欄位所佔的位元組數,但是如果採用定長編碼時便不會。同時,如果CHAR(M)如果採用變長編碼的形式,其中要求該欄位至少佔用M個位元組。

4.3.3REDUNDANT行格式

其中REDUNDANT沒有COMPACT緊湊,在一般在MySQL5.0之前常使用。

其行格式如下
在這裡插入圖片描述

  • 欄位長度偏移列表:該行格式會將該記錄中所有的列,包括隱藏列的偏移量按逆序儲存到欄位長度偏移量列表中。一般該欄位的長度為相鄰兩個偏移量之差。
  • 記錄頭資訊:會有一個1byte_offs_flag來標記該偏移量儲存是1個位元組還是2個位元組。
  • 1byte_offs_flag的選取:如果記錄總長度小於等於127遍直接用1個位元組儲存,否者用2個位元組儲存。其中為什麼是127,因為會在偏移量中選取最高位作為NULL值的標記位。
  • NULL值處理:偏移量中選取最高位作為NULL值來標記該欄位是否為NULL,並且如果欄位是定長型別,比如char(M),則直接將其設定為M*一個字元需要的最大位元組數(如utf8為3)個位元組,並且將儲存實際資料的地方初始化為0,這樣可以直接在原位置更新;對於變長型別,便不會在真實資料處記錄資料。

4.3.4溢位列

當某列的資料超過臨界點時,稱之為溢位列,此時COMPAT記錄格式會記錄該列的前768個位元組,然後用20位元組用來指向儲存剩餘資料的地址,其中剩餘資料是以連結串列的形式儲存在其他頁中。

4.3.5DYNAMIC格式和COMPRESSED格式

其中DYNACMIC格式和COMPACT格式類似,但是在處理溢位列的時候,他不會儲存前768個位元組,而是隻儲存20個位元組的指標。COMPRESSED則會採用壓縮演算法來使得儲存空間更小。