3. InnoDBテーブル構造

列アドレス:

MySQLシリーズの記事の列



1。概要

InnoDBテーブルはインデックス構成テーブルです。テーブル全体は主キーに従って構築されたB +ツリーであり、データの行全体がリーフノードに格納されます(行のオーバーフローがない場合)。主キーが指定されていない場合、InnoDBは最初に空でない一意のインデックスを主キーとして使用しようとし、次に自動的に6バイトの主キーを作成します。

2.論理ストレージ構造

テーブル(テーブルスペース)->セグメント(セグメント)->エリア(エクステント)->ページ(ページ)

論理的な観点から見ると、InnoDBテーブルのすべてのデータは、セグメント、リージョン、およびページで構成されるテーブルスペースに配置されます。

ここに画像の説明を挿入

2.1テーブルスペース

デフォルトでは、InnoDBストレージエンジンには、すべてのデータを格納するための共有テーブルスペースibdata1があります。パラメータinnodb_file_per_tableが有効になっている場合、キャッシュに挿入されたテーブルデータ、インデックス、ビットマップページなどの各テーブルのデータは、独自のテーブルスペースに個別に配置でき、他のタイプのデータ(ログの取り消し、二重書き込みバッファ、バッファの変更など)トランザクション情報などのデータは、引き続き元の表スペースに保管されます。

2.2セグメント

表スペースはセグメントで構成され、共通セグメントには、データ・セグメント、索引セグメント、およびロールバック・セグメントが含まれます。データセグメントはB +ツリーのリーフノードであり、インデックスセグメントは非リーフノードです。

2.3ゾーン

エリアは連続するページで構成され、そのサイズは1MBです。デフォルトでは、InnoDBページのサイズは16KBです。つまり、地区内には64の連続するページがあります。地区の継続性を確保するために、InnoDBは一度に4〜5地区に申請します。

2.4ページ

ページはInnoDBディスク管理の最小単位であり、デフォルトのサイズは16KBです。InnoDBには圧縮ページが導入されており、ページサイズは2KB、4KB、または8KBに設定できます。

InnoDBページタイプには、データページ(インデックスページ)、Blobページ、元に戻すページ、システムページなどがあります。一般的なページタイプは次のとおりです。

  • データページ(Bツリーノード)
  • uodo 页(undo Log Page)
  • 非圧縮BLOBページ
  • 圧縮BLOBページ
  • トランザクションデータページ(トランザクションシステムページ)
  • バッファービットマップページの挿入(バッファービットマップの挿入)
  • バッファフリーリストの挿入(バッファフリーリストの挿入)

2.4ライン

InnoDBストレージエンジンは行指向です。つまり、データはページに行で格納されます。

3.データページ(インデックスページ)の構造

InnoDBはデータページの形式でデータを編成しますデフォルトの非圧縮データページは16KBです。ibdの中央では、0〜16KBのオフセットはデータページ0、16KB〜32KBのオフセットはデータページ1などです。

データページは大きく3つの部分に分けることができます。1つの部分はページの基本情報を格納し、もう1つの部分はデータレコードを格納しますデータレコードは、レコードのキー値の順に格納され、レコードのポインタによって一方向に接続さます。他の部分は、高速化に使用されるデータページのディレクトリを格納します。見つける。このディレクトリはまばらであることに注意してください。つまり、ディレクトリ内のすべてのレコードにインデックスが付けられるわけではありません。平均して、6つのレコードごとに1つのディレクトリしかありません。

ここに画像の説明を挿入

ファイルヘッダーデータページファイルヘッダー
ファイルヘッダーは、ページヘッダー情報、現在のページの上位ページポインターや下位ページポインターなどのテーブルスペース関連情報を記録するために使用されるため、B +ツリーでは、リーフノードは二重にリンクされたリストです。InnoDBデータページは論理的には連続していますが、物理的には、データページの継続的な割り当てと解放により、個別になっている場合があります。

ページヘッダーデータページヘッダー
ページヘッダーは、ページ内のレコード数など、データページのステータス情報とメタデータを記録します

Infimum、Supremum Recordの最小レコードと最大レコード
仮想レコードは、それぞれ最小レコードと最大レコードを表すレコードの境界を制限するために使用されます。たとえば、Infimumはページ上のすべての実際のレコードよりも小さいです。

ここに画像の説明を挿入

ユーザーレコード

ユーザーレコードは実際に行レコードを格納し、キーの順序に従ってソートされます。レコードは、単一リンクリスト(次のレコードを指す)を介して接続されます。デフォルトのレコードは互いに隣接していますが、削除されたレコードのスペースが再利用されると、スペースの断片化が発生する可能性があります(元のスペースが新しいレコードの長さよりも大きい)。

フリースペース

空き容量を記録します。

ページ辞書

ページ辞書は、キー値の順序で(ページに対する)レコードの相対位置を格納する疎ディレクトリです。レコードポインターは二分法を使用してすばやく見つけることができます。ディレクトリ内のレコードポインタはDictory Slotsと呼ばれます。InnoDBのディレクトリは疎であるため、すべてのレコードにスロットがあるわけではなく、平均6つのレコードがディレクトリスロットを共有します。たとえば、(a、b、c、d、e、f、g、h、i、j、k)がある場合、ページディレクトリは(a、e、i)になります。

InnoDBのページディクトリは疎ディレクトリであるため、バイナリ検索は大まかな場所に過ぎず、レコードポインターを通じてターゲットレコードを検索し続ける必要があります。

B +ツリーインデックス自体は特定のレコードを見つけることができません。レコードが置かれているページのみを見つけることができます。データベースがページをメモリにロードした後、ページディレクトリの疎ディレクトリを介して大まかに検索し、最終的にレコード間の単一レコードを使用します。リンクリストのポインタへのターゲットレコードを見つけます。

ファイルトレーラー

ページのチェックサムおよびその他の情報を記録して、ページの完全性を確認します。

4.行レコード形式

InnoDBストレージエンジンは行指向です。つまり、データはページに行で格納されます。InnoDBは4つの中国行レコード形式をサポートしています。一般的な形式は、コンパクト、ダイナミック、圧縮です。

MySQL 5.7のデフォルトの行レコード形式は動的です。

4.1コンパクトな行レコード形式

コンパクトは効率的な行レコード形式です。データを効率的に格納することを目的としています。REDUNDANTと比較すると、領域の使用量を約20%削減できますが、特定の操作のCPU使用量が増加します。

4.1.1全体構造

可変長フィールド長リスト

コンパクト行レコード形式のヘッダーは、可変長フィールド長リストであり、NULL以外の可変長フィールドの実際の長さが格納されます。MySQLのVARCHARタイプの最大長は65535を超えることができないため、各フィールドの長さは最大2バイトで表すことができます。

NULLフラグ

可変長フィールド長リストの後にはNULLフラグビットが続きます。これは、NULLになる可能性のある列のどれが実際にNULLであるかを示します。NULLの場合、ビットは1としてマークされます。この部分の長さは、テーブルでNULLになる可能性のある列の数によって異なります。たとえば、NULLになる可能性のある9つの列がテーブル定義にある場合、9列のNULLステータスを表すには2バイトのビットベクトルが必要です。

(VARCHARでもCAHRでも)実際にNULLである列は、NULLフラグの1ビットを除いて他のスペースを占有しません。

ヘッダー情報を記録する

次は、5バイトを占め、行変更レコードの基本情報を記録するレコードヘッダー情報です。例えば:

  • 削除するかどうか
  • ポインタ:InnoDBページ内の次のレコードの相対位置。行レコードはリンクリストを介して接続されます。

実際のデータ

レコードヘッダー情報の後に、各列の実際のデータが格納され、実際にNULLである列はスペースを占有しません。ユーザー定義の列に加えて、トランザクションIDとロールバックポインター列の2つの非表示列があります。主キーが定義されていない場合、6バイトのROWID列が存在します。

セカンダリインデックスの場合、この部分には行のプライマリキーが格納されます。主キーのいくつかの列(MySQLは複合インデックスをサポートしています)が既にセカンダリインデックスに含まれている場合、重複したレコードはありません。

4.1.2異なるタイプのデータを保存する方法

チャー

固定長のCHARタイプの場合、欠落している文字は0x20で埋められます。

CHAR(N)のNは文字数を表すため、可変長文字セット(UTF-8など)の場合、実際のバイト長は固定長データではありません。現時点では、InnoDBはこれを可変長文字型と見なし、CHAR型フィールドの実際の長さを文字長リストに記録します。したがって、可変長文字セットを使用する場合、CHARとVARCHARの格納に違いはありません。

VARCHAR

VARCHAR(N)のNは文字数を示し、VARCCHARの最大バイト長は65532(他のオーバーヘッドのため65535未満)を超えることはできません。たとえば、UTF-8文字セットでは、最大バイト長でNの最大値を3で割る必要があります。

PS:
MySQLのUTF-8文字セットは標準のUTF-8ではなく、最大3バイトをサポートしますが、標準のUTF-8は文字エンコードに1〜4バイトを使用するため、MySQLはUTF- 8 mb4で構成します。

行のオーバーフロー

通常の状況では、行データはページに配置されますが、一部の長い列データの場合、InnoDBはそれをデータページの外とUncompress BOLBページに格納します。VARCHAR、BLOB、およびTEXTで行のオーバーフローが発生する可能性がありますが、長さが短い場合、BOLBでさえ完全にページに格納される可能性があります。

行オーバーフローが発生するかどうかは、ページのサイズと行のサイズに依存しますInnoDBは、データページに少なくとも2行のレコードが確実に格納されるようにします。

行がオーバーフローすると、コンパクト行フォーマットで、最初の768バイトがデータページに格納され、次に行オーバーフローページを指すように20バイトのポインターが格納されます。

ここに画像の説明を挿入

動的および圧縮行レコード形式では、完全な行オーバーフローメソッドが使用されます。データページにはポインターのみが存在し、列のプレフィックスバイトは格納されなくなります。

4.2動的および圧縮行レコード形式

動的および圧縮された行レコード形式は、コンパクトに基づいて改善されました。どちらも完全な行オーバーフローメソッドを使用します。データページに格納されるのはポインターのみで、列プレフィックスバイトは格納されません。

圧縮された行レコード形式のもう1つの機能は、格納された行データ(zlib)を圧縮することです。これにより、BLOB、TEXT、VARCHARなどの長いタイプのデータをより効率的に格納できます。

参照文書

"MysSQL Technology Insider(InnoDB Storage Engine)"
Taobao Database Kernel Monthly Report:MySQL・Expert Contribution・Inference and storage of null values in in InnoDB physical rows
MySQL official website:InnoDB Row Formats

おすすめ

転載: blog.csdn.net/cooper20/article/details/108632818