列アドレス:
記事ディレクトリ
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