innodb一页为什么要存储两行记录_innodb数据记录存储结构
生活随笔
收集整理的這篇文章主要介紹了
innodb一页为什么要存储两行记录_innodb数据记录存储结构
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
innodb頁
- 數據存儲在磁盤上;數據處理的過程發生在內存中,需要把磁盤的數據加載到內存中;處理寫入或修改請求時,需要把內存中的內容刷新到磁盤上;
- innodb存儲引擎,不是一條一條從磁盤讀取記錄,而是把數據劃分為若干個頁,mysql以頁作為磁盤和內存之間交互的基本單元,也是mysql管理存儲空間的基本單元,頁的大小一般為16KB;
- 一般情況下, 一次最少從磁盤中讀取16KB的內容到內存中,一次最少把內存中16KB的內容刷新到磁盤中;
innodb行格式
- 記錄在磁盤上的存放格式稱為行格式或記錄格式;
- innodb設計了4種行格式:compact、redundant、dynamic、compressed,我們使用的5.7版本,默認的行格式是dynamic;
- 我們可以在創建和修改表時指定行格式:row_format=dynamic;
詳解compact行格式
compact行格式示意圖演示表結構演示表數據- 記錄的額外信息
- 變長字段長度列表
- 1、mysql支持的常見變長數據類型:varchar、text、blob,這種類型的字段稱為變長字段;
- 2、變長字段占用的存儲空間分為兩部分:真正的數據內容、占用的字節數;
- 3、變長字段長度列表:所有變長字段的真實數據占用的字節長度形成的一個列表,按照列的順序逆序存放;
- 變長字段長度列表
- 4、第一條記錄變長字段長度列表存儲格式見上圖,注意:1、字符集是ascii,每個字符只需要一個字節在進行編碼;2、變長字段長度列表存放順序是逆序;
- 5、用一個字節還是兩個字節表示真實數據占用的字節數?
- 介紹innodb規則前,先說明三個變量,W:一個字符最多需要使用的字節數(utf8是3,gbk是2,ascii是1);M:varchar(M),能最多存儲多少個字符;L:實際存儲的字符串占用的字節數;
- M*W>255 且 L>127 時,使用兩個字節,否則使用一個字節;
- 6、變長字段長度列表只存儲值為非null的列內容占用的長度;
- NULL值列表
- 1、行格式把null值的列統一管理,存儲到null值列表中,不會把null存儲到記錄真實數據中,以節省空間;
- 2、把每個允許存null值的列對應一個二進制位,二進制位按照列的順序逆序排序,1代表列的值為null,0代表列的值不是null;
- 3、mysql規定,null值列表用整數個字節的位表示,不夠的在字節高位補0;
- 4、第二條記錄對應的二進制位情況如下:
- 5、到此,兩條演示數據的存儲格式如下:
- 記錄頭信息
- 1、由固定的5個字節,也就是40個二進制位組成;
- 2、了解幾個關鍵的標記:
- 是否被刪除的標記;
- 當前記錄在記錄堆的位置信息;
- 記錄的類型(0:普通記錄,1:B+樹非葉子節點記錄,2:最小記錄,3:最大記錄)
- 下一條記錄的相對位置;
- 記錄頭信息
- 記錄的真實數據
- 真實數據部分,前三列屬于隱藏列,其中row_id隱藏列的存在視情況而定,看我們創建表是否定義主鍵或唯一索引,如果二者都沒有,引擎會默認添加row_id隱藏列作為表主鍵;
- 第二條記錄的c3和c4列的值為null,存儲在了null值列表處,記錄的真實數據處不在存儲,節省存儲空間;
- 注意第一條記錄的c3列,char(10)類型,雖然‘cc’字符串只占用了兩個字節,但整個列仍然占用了10個字節空間,真實數據以外的8個字節用空格字符填充,注意此處的字符集是:ascii;如果采用變長字符集,eg:gbk、utf8,char(10)類型的長度也會存儲到變長字段長度列表中,
- char(10)的類型,如果采用的定長字符集,該列占用的字節數不會被加到變長字段長度列表中,如果采用變長字符集,則會加;
- 變長字符集char(10)類型的列,至少占用10個字節,varchar(10)類型則沒有這個要求;
行溢出數據
- mysql對一條記錄占用的最大存儲空間是有限制的,除了blob、text類型之外,其他所有列(不包括隱藏列和記錄頭信息)占用的字節長度總和不能超過65535個字節;
- 我們存儲一個varchar類型的列,需要占用3部分空間:真實數據、真實數據占用的字節長度、null值標示;
- mysql以頁為單元管理存儲空間,記錄都會分配到某個頁中存儲,一個頁的大小一般是16KB,也就是16384字節,而一個varchar類型的列,最多可以存儲65532個列(65535-null值標示1字節-變長字段長度可能的2字節),這樣就可能造成一頁放不下一條記錄的情況;
- 對于compact、redundant行格式,對占用存儲空間非常大的列,記錄的真實數據處只會存儲該列的一部分數據,剩下的數據分散存儲在其他幾個頁中,記錄真實數據處用20個字節存儲指向這些頁的地址;
- 行溢出臨界點:列存儲多少字節時會發生行溢出?
- mysql規定,一頁至少存放兩條記錄;
- 假設表只有一個列;
- 每個頁除了存放我們的記錄外,還需要一些額外信息,加起來一共占用132個字節;
- 每個記錄需要的額外信息是27字節:
- 2字節真實數據的長度;
- 1字節null值列表;
- 5字節頭信息;
- 6字節row_id列;
- 6字節trx_id列;
- 7字節roll_pointer列;
- 求解公式:132+2*(27+n)<16384,n<8099;
dynamic行格式
- 類似compact行格式;
- 處理行溢出時:在記錄真實數據處,不會存儲真實數據的前768個字節,會把所有字節存儲到其他頁中,在真實數據處,只存儲其他頁面的地址;
- compressed行格式采用壓縮算法對頁面進行壓縮,以節省空間;
總結
以上是生活随笔為你收集整理的innodb一页为什么要存储两行记录_innodb数据记录存储结构的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: js能订阅mq吗_高颜值宠物营养品订阅盒
- 下一篇: c获取当前系统时间_Python系统:程