InnoDB記錄存儲結構介紹

       Mysql存儲引擎分爲 Innodb,myisam,memory等,不同的存儲引擎一般是由不同的人爲實現不同的特性而開發的,真實數據在不同的存儲引擎中存放的格式一般般也是不同的,比如memory時不餘姚使用磁盤作爲存儲介質的,因而一旦服務器關閉或者重啓那麼數據就會消失。由於Innodb是其默認存儲引擎,是最常最常使用使用的存儲引擎。

 

InnoDb 存儲引擎

1,簡介

       將數據存在磁盤,但是真正處理數據是在內存中完成的,故需要 需要將數據加載到內存中,如果處理寫入或者修改 還需要將數據刷新到磁盤。InnoDb 採用方法是將數據分爲若干個頁,以頁作爲磁盤和內存之間交互的基本單位,InnoDb中頁的大小一般爲16KB,也就是一般情況下,一次最少從磁盤中讀取16Kb的內容到內存中,一次最少把內存中16KB數據刷新到磁盤上

2,行格式  

       我們平時都是以記錄爲單位向表中插入數據的,這些記錄在磁盤上存儲方式,我們可以叫他 行格式或者記錄格式,行格式分爲四種類型:Compact,Redundant,Dynamic,Compressed,我在navicate for mysql上面看到 已經不止上面提到的這四種了。

我們可以使用語句去設置表的行格式:

CREATE TABLE 表名 (字段名)  ROW_FORMAT = 行格式名稱

ALTER TABLE 表名  ROW_FORMAT = 行格式名稱

比如 我們可以創建一張表:

CREATE TABLE `test_demo` (
  `c1` varchar(10) DEFAULT NULL,
  `c2` varchar(10) NOT NULL,
  `c3` char(10) DEFAULT NULL,
  `c4` varchar(10) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=ascii ROW_FORMAT=COMPACT

我們可以看到 這個表的 行格式 是 compact,另外我們也誰自那個這個表的字符集是 ASCII 【ASCII 字符集 只包含 數字,符號,大小寫字母和一些不可見字符】,故漢字是無法存進去的,下面我們向表插入兩條記錄:

INSERT INTO record_format_demo(c1,c2,c3,c4)VALUES('aaaa','bbb','cc','d'),('eeee','fff',NULL,NULL);

SELECT * FROM record_format_demo

 

Compact 行格式

        它的一條記錄可以分爲 記錄額外信息 和 記錄真實數據 。那麼什麼是記錄額外信息呢?記錄額外信息是 服務器爲了描述這條記錄而不得不額外添加的一些信息,它又分爲 變長字段長度列表,NULL值列表,記錄頭信息。

        變長字段列表

        比如VARCHAR,TEXT,BLOB 類型,這些數據類型的字段, 我們可稱之爲 變長字段,它的存儲字節不是固定的,所以我們在存儲數據時候需要把這些數據佔用的字節數也存起來,這樣讓服務器知道它到底多長。變長字段佔用存儲空間分爲:真正數據內容和佔用的字節數。在compact 行格式中,把所有對的變長字段真實數據佔用字節長度存儲在記錄的開頭位置,從而形成一個變長字段長度列表,各變長字段數據佔用的字節數按照逆序存放。

       比如,test_demo表的第一條記錄,因爲此表對的 c1,c2,c4都是VARCHAR(10)類型的,即變長類型,所以這三個字段的長度都需要保存在記錄開頭,因爲表使用ASCII字符集,故c1長度是 十進制 4,十六進制 0x04,c2長度是 十進制 3 ,十六進制 0x03,c4 長度是 十進制 1,十六進制 0x01,因爲這些長度是按照列的逆序存放 故結果是 010304,結果就是:

 

變長字段長度列表中只存儲值爲 非NULL 的列內容佔用的長度,值爲 NULL 的列的長度是不儲存的 。也就是說對於第二條記錄來說,因爲c4列的值爲NULL,所以第二條記錄的變長字段長度列表只需要存儲c1c2列的長度即可。其中c1列存儲的值爲'eeee',佔用的字節數爲4c2列存儲的值爲'fff',佔用的字節數爲3,所以變長字段長度列表需2個字節。

(2)NULL值列表

       compact行格式會將值爲NULL的列統一管理,放在NULL列表,它的處理過程是這樣的:首先統計表中允許爲NULL的列,如果沒有則NULL值列表也就不存在了,否則 每個允許存儲NULL的列對應一個二進制位,二進制位按照逆序排列 故 順序爲 C4,C3,C1

(3)記錄頭信息

     記錄頭信息 是由固定的5個字節組成也就是40個二進制位,不同對的位代表不同的意思。


預留位1:1bit  沒有使用

預留位2:   1bit 沒有使用

delete_mask:  1bit   標記該記錄是否被刪除

min_rec_mask: 1bit    B+樹的每層非葉子節點中最小的記錄都會添加該標記

n_owned:   4bit   表示當前記錄擁有的記錄數

heap_no:  13bit   表示當前記錄在記錄堆的位置信息

record_type: 3bit   表示當前記錄的類型,0 表示普通記錄,1表示B+樹非葉子節點記錄,2 表示最小記錄,3表示最大記錄

next_record: 16bit    表示下一條記錄相對位置

(4)記錄真實數據

      記錄真實數據,相對於test_demo表來說,我們除了會記錄 c1,c2,c3,c4這幾列對的數據以外,mysql會爲每個記錄添加一些列(隱藏列),

 

實際上這幾個列的真正名稱其實是:DB_ROW_ID、DB_TRX_ID、DB_ROLL_PTR

InnoDB對於表主鍵的生成策略:優先使用用戶自定義的主鍵作爲主鍵,如果用戶沒有定義主鍵,那麼選取一個unique鍵作爲主鍵,如果表中連一個unique鍵都沒有的話,那麼innodb會爲表默認添加一個名爲row_id的隱藏列作爲主鍵。

其他幾種行格式 暫時不介紹了。下面簡單總結一下吧

總結

  1. 頁是MySQL中磁盤和內存交互的基本單位,也是MySQL是管理存儲空間的基本單位。

  2. 指定和修改行格式的語法如下:

    CREATE TABLE 表名 (列的信息) ROW_FORMAT=行格式名稱
    
    ALTER TABLE 表名 ROW_FORMAT=行格式名稱
    
  3. InnoDB目前定義了4中行格式

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章