日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) >

innodb一页为什么要存储两行记录_innodb数据记录存储结构

發(fā)布時(shí)間:2025/4/16 54 豆豆
生活随笔 收集整理的這篇文章主要介紹了 innodb一页为什么要存储两行记录_innodb数据记录存储结构 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

innodb頁(yè)

  • 數(shù)據(jù)存儲(chǔ)在磁盤上;數(shù)據(jù)處理的過(guò)程發(fā)生在內(nèi)存中,需要把磁盤的數(shù)據(jù)加載到內(nèi)存中;處理寫入或修改請(qǐng)求時(shí),需要把內(nèi)存中的內(nèi)容刷新到磁盤上;
  • innodb存儲(chǔ)引擎,不是一條一條從磁盤讀取記錄,而是把數(shù)據(jù)劃分為若干個(gè)頁(yè),mysql以頁(yè)作為磁盤和內(nèi)存之間交互的基本單元,也是mysql管理存儲(chǔ)空間的基本單元,頁(yè)的大小一般為16KB;
  • 一般情況下, 一次最少?gòu)拇疟P中讀取16KB的內(nèi)容到內(nèi)存中,一次最少把內(nèi)存中16KB的內(nèi)容刷新到磁盤中;

innodb行格式

  • 記錄在磁盤上的存放格式稱為行格式或記錄格式;
  • innodb設(shè)計(jì)了4種行格式:compact、redundant、dynamic、compressed,我們使用的5.7版本,默認(rèn)的行格式是dynamic;
  • 我們可以在創(chuàng)建和修改表時(shí)指定行格式:row_format=dynamic;

詳解compact行格式

compact行格式示意圖

演示表結(jié)構(gòu)

演示表數(shù)據(jù)
  • 記錄的額外信息
    • 變長(zhǎng)字段長(zhǎng)度列表
      • 1、mysql支持的常見(jiàn)變長(zhǎng)數(shù)據(jù)類型:varchar、text、blob,這種類型的字段稱為變長(zhǎng)字段;
      • 2、變長(zhǎng)字段占用的存儲(chǔ)空間分為兩部分:真正的數(shù)據(jù)內(nèi)容、占用的字節(jié)數(shù);
      • 3、變長(zhǎng)字段長(zhǎng)度列表:所有變長(zhǎng)字段的真實(shí)數(shù)據(jù)占用的字節(jié)長(zhǎng)度形成的一個(gè)列表,按照列的順序逆序存放;

第一條記錄的存儲(chǔ)格式
      • 4、第一條記錄變長(zhǎng)字段長(zhǎng)度列表存儲(chǔ)格式見(jiàn)上圖,注意:1、字符集是ascii,每個(gè)字符只需要一個(gè)字節(jié)在進(jìn)行編碼;2、變長(zhǎng)字段長(zhǎng)度列表存放順序是逆序;
      • 5、用一個(gè)字節(jié)還是兩個(gè)字節(jié)表示真實(shí)數(shù)據(jù)占用的字節(jié)數(shù)?
        • 介紹innodb規(guī)則前,先說(shuō)明三個(gè)變量,W:一個(gè)字符最多需要使用的字節(jié)數(shù)(utf8是3,gbk是2,ascii是1);M:varchar(M),能最多存儲(chǔ)多少個(gè)字符;L:實(shí)際存儲(chǔ)的字符串占用的字節(jié)數(shù);
        • M*W>255 且 L>127 時(shí),使用兩個(gè)字節(jié),否則使用一個(gè)字節(jié);
      • 6、變長(zhǎng)字段長(zhǎng)度列表只存儲(chǔ)值為非null的列內(nèi)容占用的長(zhǎng)度;
    • NULL值列表
      • 1、行格式把null值的列統(tǒng)一管理,存儲(chǔ)到null值列表中,不會(huì)把null存儲(chǔ)到記錄真實(shí)數(shù)據(jù)中,以節(jié)省空間;
      • 2、把每個(gè)允許存null值的列對(duì)應(yīng)一個(gè)二進(jìn)制位,二進(jìn)制位按照列的順序逆序排序,1代表列的值為null,0代表列的值不是null;
      • 3、mysql規(guī)定,null值列表用整數(shù)個(gè)字節(jié)的位表示,不夠的在字節(jié)高位補(bǔ)0;
      • 4、第二條記錄對(duì)應(yīng)的二進(jìn)制位情況如下:

第二條記錄null值列表情況
      • 5、到此,兩條演示數(shù)據(jù)的存儲(chǔ)格式如下:

存儲(chǔ)格式分析
    • 記錄頭信息
      • 1、由固定的5個(gè)字節(jié),也就是40個(gè)二進(jìn)制位組成;
      • 2、了解幾個(gè)關(guān)鍵的標(biāo)記:
        • 是否被刪除的標(biāo)記;
        • 當(dāng)前記錄在記錄堆的位置信息;
        • 記錄的類型(0:普通記錄,1:B+樹(shù)非葉子節(jié)點(diǎn)記錄,2:最小記錄,3:最大記錄)
        • 下一條記錄的相對(duì)位置;
  • 記錄的真實(shí)數(shù)據(jù)

真實(shí)數(shù)據(jù)部分
    • 真實(shí)數(shù)據(jù)部分,前三列屬于隱藏列,其中row_id隱藏列的存在視情況而定,看我們創(chuàng)建表是否定義主鍵或唯一索引,如果二者都沒(méi)有,引擎會(huì)默認(rèn)添加row_id隱藏列作為表主鍵;
    • 第二條記錄的c3和c4列的值為null,存儲(chǔ)在了null值列表處,記錄的真實(shí)數(shù)據(jù)處不在存儲(chǔ),節(jié)省存儲(chǔ)空間;
    • 注意第一條記錄的c3列,char(10)類型,雖然‘cc’字符串只占用了兩個(gè)字節(jié),但整個(gè)列仍然占用了10個(gè)字節(jié)空間,真實(shí)數(shù)據(jù)以外的8個(gè)字節(jié)用空格字符填充,注意此處的字符集是:ascii;如果采用變長(zhǎng)字符集,eg:gbk、utf8,char(10)類型的長(zhǎng)度也會(huì)存儲(chǔ)到變長(zhǎng)字段長(zhǎng)度列表中,
    • char(10)的類型,如果采用的定長(zhǎng)字符集,該列占用的字節(jié)數(shù)不會(huì)被加到變長(zhǎng)字段長(zhǎng)度列表中,如果采用變長(zhǎng)字符集,則會(huì)加;
    • 變長(zhǎng)字符集char(10)類型的列,至少占用10個(gè)字節(jié),varchar(10)類型則沒(méi)有這個(gè)要求;

行溢出數(shù)據(jù)

  • mysql對(duì)一條記錄占用的最大存儲(chǔ)空間是有限制的,除了blob、text類型之外,其他所有列(不包括隱藏列和記錄頭信息)占用的字節(jié)長(zhǎng)度總和不能超過(guò)65535個(gè)字節(jié);
  • 我們存儲(chǔ)一個(gè)varchar類型的列,需要占用3部分空間:真實(shí)數(shù)據(jù)、真實(shí)數(shù)據(jù)占用的字節(jié)長(zhǎng)度、null值標(biāo)示;
  • mysql以頁(yè)為單元管理存儲(chǔ)空間,記錄都會(huì)分配到某個(gè)頁(yè)中存儲(chǔ),一個(gè)頁(yè)的大小一般是16KB,也就是16384字節(jié),而一個(gè)varchar類型的列,最多可以存儲(chǔ)65532個(gè)列(65535-null值標(biāo)示1字節(jié)-變長(zhǎng)字段長(zhǎng)度可能的2字節(jié)),這樣就可能造成一頁(yè)放不下一條記錄的情況;
  • 對(duì)于compact、redundant行格式,對(duì)占用存儲(chǔ)空間非常大的列,記錄的真實(shí)數(shù)據(jù)處只會(huì)存儲(chǔ)該列的一部分?jǐn)?shù)據(jù),剩下的數(shù)據(jù)分散存儲(chǔ)在其他幾個(gè)頁(yè)中,記錄真實(shí)數(shù)據(jù)處用20個(gè)字節(jié)存儲(chǔ)指向這些頁(yè)的地址;

  • 行溢出臨界點(diǎn):列存儲(chǔ)多少字節(jié)時(shí)會(huì)發(fā)生行溢出?
    • mysql規(guī)定,一頁(yè)至少存放兩條記錄;
    • 假設(shè)表只有一個(gè)列;
    • 每個(gè)頁(yè)除了存放我們的記錄外,還需要一些額外信息,加起來(lái)一共占用132個(gè)字節(jié);
    • 每個(gè)記錄需要的額外信息是27字節(jié):
      • 2字節(jié)真實(shí)數(shù)據(jù)的長(zhǎng)度;
      • 1字節(jié)null值列表;
      • 5字節(jié)頭信息;
      • 6字節(jié)row_id列;
      • 6字節(jié)trx_id列;
      • 7字節(jié)roll_pointer列;
    • 求解公式:132+2*(27+n)<16384,n<8099;

dynamic行格式

  • 類似compact行格式;
  • 處理行溢出時(shí):在記錄真實(shí)數(shù)據(jù)處,不會(huì)存儲(chǔ)真實(shí)數(shù)據(jù)的前768個(gè)字節(jié),會(huì)把所有字節(jié)存儲(chǔ)到其他頁(yè)中,在真實(shí)數(shù)據(jù)處,只存儲(chǔ)其他頁(yè)面的地址;
  • compressed行格式采用壓縮算法對(duì)頁(yè)面進(jìn)行壓縮,以節(jié)省空間;

總結(jié)

以上是生活随笔為你收集整理的innodb一页为什么要存储两行记录_innodb数据记录存储结构的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。