InnoDB
テーブルの物理的なレコード構造は、テーブルが作成された時に指定された行フォーマットによって決まります。MySQL
5.1 ではデフォルトで InnoDB が
COMPACT
フォーマットを利用しますが、MySQL
の古いバージョンとの互換性を保持する為にはREDUNDANT
フォーマットが有効です。
InnoDB ROW_FORMAT=REDUNDANT
テーブル内のレコードは、次の特徴を持っています:
各インデックス レコードは6バイトのヘッダを含んでいます。このヘッダは、連続するレコードをリンクする為と、行レベル ロックで使用される。
集合インデックス内のレコードには、すべてのユーザ定義カラムのフィールドが含まれます。これに加えて、トランザクション ID 用の6バイトのフィールドと、ロール ポインタ用の7バイトのフィールドが1つずつ含まれています。
ユーザがテーブルに主キーを定義していない場合は、集合インデックスの各レコードは6バイトの行 ID フィールドも含みます。
セカンダリ インデックスの各レコードには、集合インデックス キーに対して定義されたすべてのフィールドも含まれます。
レコードには、そのレコードの各フィールドへのポインタも含まれます。レコード内のフィールド長の合計が128バイト未満の場合はポインタが1バイト、128バイト以上の場合はポインタが2バイトになります。これらのポインタの配列はレコード ディレクトリと呼ばれます。これらのポインタが指し示すエリアはレコードのデータ部分と呼ばれます。
InnoDB は内部的に固定長フォーマットの
CHAR(10)
のような固定長文字カラムを格納します。InnoDB
は VARCHAR
カラムから後続領域を切り捨てます。
SQL NULL
値はレコード
ディレクトリ内で1か2バイトを蓄えておきます。それ以外に、SQL
NULL
値は可変長カラム内に格納されるとレコードのデータ部分にゼロ
バイトを蓄えます。それは固定長カラム内でレコードのデータ部分内にカラムの固定長を蓄えます。NULL
値に固定領域を蓄える目的は、そうする事でインデックス
ページの崩壊を起こさずに NULL
からのカラムを非 NULL
値に、更新する事ができるという事です。
InnoDB ROW_FORMAT=COMPACT
テーブル内のレコードには次の特徴があります:
各インデックス レコードは可変長ヘッダに先導される5バイトのヘッダを含んでいます。このヘッダは、連続するレコードをリンクする為と、行レベルロックで使用されます。
レコード ヘッダは NULL
カラムを指示する為にビット
ベクタを含んでいます。ビット
ベクタは(n_nullable
+7)/8
バイトを占めています。NULL
カラムがこのベクタ内のビット以外の領域を占める事はありません。
各非 NULL
可変長フィールドに対して、レコード
ヘッダは1か2バイトのカラム長を含みます。カラムの一部が外部的に格納されたり、最大長が255バイトを超える、または実際の長さが127バイトを超えたりしなければ2バイトだけ必要になります。
レコード
ヘッダにはカラムのデータ内容が続きます。NULL
のカラムは省略されます。
集合インデックス内のレコードには、すべてのユーザ定義カラムのフィールドが含まれます。これに加えて、トランザクション ID 用の6バイトのフィールドと、ロール ポインタ用の7バイトのフィールドが1つずつ含まれています。
ユーザがテーブルに主キーを定義していない場合は、集合インデックスの各レコードは6バイトの行 ID フィールドも含みます。
セカンダリ インデックスの各レコードには、集合インデックス キーに対して定義されたすべてのフィールドも含まれます。
InnoDB は内部的に固定長フォーマットの
CHAR(10)
のような固定長、固定幅文字カラムを格納します。InnoDB
は VARCHAR
カラムから後続領域を切り捨てます。
InnoDB は、後続領域を切り取る事で内部的に
UTF-8 CHAR(
カラムを n
)n
バイトで格納しようとします。ROW_FORMAT=REDUNDANT
内では、そのようなカラムは3*n
バイトを占めます。最小領域 n
を蓄える目的は、これによって多くの場合、インデックス
ページの崩壊を起こさずにカラムの更新ができるからです。