***

5898 ワード

***
一、振り返る
***
大きな方向から:MySQLのアーキテクチャ設計、InnoDBのアーキテクチャ設計を学びました.
より深い:rodo logとbinlogが協力する2段階のプロトコルの提出を学び、バッファプールの設計原理と高同時、動的調整をサポートする管理メカニズムを理解しました.
次に、データ行フォーマットについて説明します.データがデータ・ページに格納されるフォーマットについて説明します.
二、行ストレージフォーマット
InnoDBストレージエンジンには、COMPACT、Redundant、Dynamic、COMPRESSEDの4つの行ストレージフォーマットがサポートされています.
次に、COMPACT行フォーマットを重点的に紹介します.
COMPACT行のストレージフォーマットは大体このように似ています.
         ,null   ,   ,column01  ,column02  ,column0n  ......

ps:ディスク領域の最大利用率を得るために、各データ行が密接に隣接しています.
次にCOMPACT行フォーマットの各知識点を詳しく紹介します.勉強が終わったら、各行のデータがしっかりと並んでいても、MySQLは各行のデータを正確に見つけることができることを知っています.
三、長くなるフィールドはどのように保存しますか?
1、長くなるフィールドの記憶問題
varcharタイプが長くなることはよく知られています.例えばvarchar(50)では、このフィールド値の長さ範囲は0~50文字です.ただし、各フィールドの値がちょうど50文字ではなく、長いものも短いものもあるに違いありません.
では、データを格納する場合、フィールド定義時の最大長に従って値を格納しますか?
いいえ、すべて最大長で保存すると、値が50文字未満の場合、ディスク領域とメモリ領域が浪費されます.
なぜメモリ容量も浪費し、データはディスクに保存されているのではないでしょうか.皆さんはバッファの役割を忘れないでしょうか?ハハ、バッファプールとディスクのデータ交換の単位はデータページであり、データ行はデータページに格納されていることを覚えておいてください.
2、長くなるフィールド長リスト
InnoDBでは、変長フィールド長リストを使用して、上記の問題を解決します.
  • 変長フィールド長リストは、各変長フィールド値の長さを記録し、格納された長さは16進数である.
  • 複数の変長フィールドがある場合、変長フィールド長リストは逆順序で格納される.

  • 次に、一例を用いて、変長フィールド長リストの使用原理を説明する.
    --    
    create table test(
    	c1 varchar(10) comment '  1-  ',
        c2 varchar(5) comment '  2-  ',
        c3 varchar(20) comment '  3-  ',
        c4 char(1) comment '  4-  ',
        c5 char(1) comment '  5-  '
    ) ENGINE=InnoDB;
    --     
    insert into test values('hello','ni','hao','a','a');
    

    彼らの長さ(16進数)を計算してみましょう.
  • helloの長さは5、16進数は0 x 05
  • niの長さは2、16進数は0 x 02
  • haoの長さは3、16進数は0 x 03
  • では、実際のストレージフォーマットは次のようになります.
    0x03 0x02 0x05 null        hello hi hao a a
    

    四、NULL値フィールドはどのように保存しますか?
    1、NULLフィールドの記憶問題
    default NULLとして定義されたフィールドで、値は空でも空でもかまいません.フィールド値がNULLの場合、データ行にはどのように格納されますか?「NULL」フィールドを直接保存しますか?
    分析してみましょう.
  • もしそうなら、ディスクスペースを無駄にします.もともと値はNULLです.あなたは今私に4文字サイズの文字列を作ってくれました.
  • そうでなければ、このフィールドがNULLであるかどうかをどのように認識しますか?

  • 2、NULL値リスト
    InnoDBでは、NULL値リストを使用して上記の問題を解決します.
  • NULL値リストは、NULLであってもよいフィールドの場合を記録する.
  • は、フィールド値がNULLであるか否かをバイナリbitビットで識別する.1はNULL、0はNULLではありません.
  • NULLとすることができる複数のフィールドがある場合、NULL値リストも逆順序で格納される.
  • 、NULL値リストのビット数は8 bitのN倍でなければなりません.例えば、リストが4 bitしかない場合は、上位に0を補い、8 bitに補います.

  • 次に、NULL値リストの使用原理を一例として説明する.
    --    
    create table test(
    	c1 varchar(10) not null comment '  1-  ',
        c2 varchar(5) comment '  2-  ',
        c3 char(1) comment '  3-  ',
        c4 varchar(30) comment '  4-  ',
        c5 varchar(50) comment '  5-  '
    ) ENGINE=InnoDB;
    --     
    insert into test values('howinfun',null,'m',null,'foshan');
    

    長いフィールドの長さを計算します.
  • howinfunの長さは8、16進数は0 x 08
  • foshanの長さは6、16進数は0 x 06
  • NULL値のフィールドを集計します.
  • c 2フィールドNULL
  • c 4フィールドNULL
  • では、実際のストレージフォーマットは次のようになります.
    0x06 0x08 00000101     howinfun m foshan
    

    3、NULL値リストを採用するのは「NULL」文字列を直接保存するのと比較して、どれだけの記憶差がありますか?
    これにより、この2つのシナリオのストレージギャップがどれほど大きいかを計算できます.
  • 1バイト8ビット、NULL値リストは、フィールド値がNULLであるか否かをバイナリビットで識別する.つまり、8つのフィールドを識別するには1バイトしかかかりません.
  • 文字列で格納され、1つの「NULL」文字列が4バイト(英語の1文字は1バイト、中国語の1文字は2バイト)で十分であれば、同じ8フィールドで36バイトが必要になります.

  • この差は非常に明らかです!
    五、データヘッダ
    COMPACT行フォーマットでは、長くなるフィールド長リストとNULL値リストを除いて、データヘッダに着きます.
    データヘッダのサイズは40ビットです.
    40 bitそれぞれにどんな情報があるかをご紹介します.
    名前
    サイズ(bit)
    説明
    予約ビット1
    1
    使用していません
    予約ビット2
    1
    使用していません
    delete_mask
    1
    レコードが削除されたかどうかをマーク
    min_rec_mask
    1
    B+木の各層の非葉ノードの最小値にこのマークが付いています
    n_owned
    4
    現在のレコードが所有しているレコードの数を示します
    heap_no
    13
    現在記録スタックに記録されている位置情報を示す
    record_type
    3
    現在のレコードのタイプを識別します.0は通常のタイプを表し、1はB+ツリーの非リーフノードを表し、2は最小値データを表し、3は最大値データを表します.
    next_record
    16
    次のレコードの相対位置を示す
    では、データヘッダの実際のストレージを見てみましょう.
    0x06 0x08 00000101 0000000000000000000010000000000000011001 howinfun m foshan
    

    六、1行のデータがディスクにどのように保存されているか
    1、文字セットコード
    上では、COMPACT行のフォーマットを紹介しましたが、1行のデータは本当にどのように保存されていますか?
    ライブラリの作成時とテーブルの作成時に文字セット符号化を指定できることはよく知られています.したがって、データはデータベースで指定された文字セットで符号化され、格納されます.
    次の例では、使用原理を説明します.
    --    
    create table test(
    	c1 varchar(10) not null comment '  1',
        c2 varchar(5) comment '  2',
        c3 char(1) comment '  3',
        c4 varchar(30) comment '  4',
        c5 varchar(50) comment '  5'
    )
    --     
    insert into test values('howinfun',null,'m',null,'foshan');
    

    仮定符号化後:
  • howinfun符号化後:616161
  • m符号化後:62
  • foshan符号化後:636363
  • では、実際のストレージフォーマットは次のようになります.
    0x06 0x08 00000101 0000000000000000000010000000000000011001 61616161 62 636363
    

    2、非表示フィールド
    長いフィールド長リスト、NULL値リスト、40 bitビットのデータヘッダ、および実際のデータに加えて、いくつかの非表示フィールドが含まれています.
  • DB_ROW_IDフィールド:プライマリ・キーとunique keyの一意のインデックスを指定しない場合、内部に自動的にROW_を追加します.IDをプライマリ・キーとして使用します.
  • DB_TRX_IDフィールド:トランザクションID、これがどのトランザクションによって更新されたデータであるかを識別する
  • DB_ROLL_PTRフィールド:トランザクションロールバック用のロールバックポインタ
  • 非表示フィールドを追加すると、上記の例の実際の記憶は次のようになります.
    0x06 0x08 00000101 0000000000000000000010000000000000011001 00000000094C(DB_ROW_ID)00000000032D(DB_TRX_ID) EA000010078E(DB_ROL_PTR) 616161 636320 6262626262 
    

    ps:カッコの中には説明用だけで、事実は存在しません.
    3、ラインオーバーフローの問題
    データ・ページのデフォルト・サイズは16 kbですが、一部のフィールドの値は16 kbよりはるかに大きい場合があります.
    例えば、長くなるフィールドタイプvarchar(N):Nは最大65532(65 kb)であり、これは16 kbよりはるかに大きい.
    もちろんtextフィールドとblogフィールドもありますが、これらは大きなフィールドで、16 kbを超えることができます.
    1行のデータのサイズが16 kbを超えると、行がオーバーフローする現象が発生します.
    どうやって解決しますか?
    1行のデータが16 kbを超えると、サイズを超えたフィールドにデータの一部のみが含まれ、20バイトのポインタが同時に含まれ、行のデータが超えた部分が格納されている他のデータページを指す可能性があります.