1

ENUM がどのように機能し、ストレージ スペースをどのように処理するかを確認するためにテストを行いましたが、予想とは異なる結果が得られました。

VARCHAR(100)1,000,000 行が取り込まれたタイプの 1 つのフィールドを持つ 1 つのテーブル。各行には、長さ 100 の 6 つの文字列のうちの 1 つからランダムに選択された値があります。

次に、 に変換しENUM、 に戻しVARCHAR(100)ます。これが結果です(データサイズ)。

1. 行 1,000,000 = 99.2 MiB、VARCHAR(100)

2. 行 1,000,000 = 6,835.9 KiB、Enum ('blah100Characters1','blah100Characters2',...,'blah100Characters6')

3. 行 1,000,000 99.2 MiB、VARCHAR(100)

タイプはVARCHAR(100)期待どおりに報告され、("L + 1 bytes, 0 <= L <= 255") 1,000,000 x 100 = 100,000,000 = 99.2 MiB のマニュアルの MySQL 仕様と一致します

---編集: えーと、その 1 バイトを追加しますが、それはこの議論には関係ありません :o)

ただし、ENUM の MySQL 仕様 (「列挙値の数に応じて 1 または 2 バイト (最大 65,535 値)」) によると、6 つの可能な組み合わせで、行ごとに 1 バイトのデータ要件があると予想されます. 1,000,000 x 1 = 1,000,000 = 976.5 KiB

変換されたテーブルが 6,835.9 KiB を必要とする理由を誰か説明してもらえますか?奇妙なことに、これは予想のほぼ 7 倍です。

4

1 に答える 1

1

最大 7 バイトを追加します (同じ結果が得られます)。スペースの一部はパディングで、一部は削除フラグ用です。

パディングがあることを証明するには、追加の列挙型 (または小さな整数) を追加します。テーブルのサイズは変わりません。

削除フラグがあることを証明するには、途中の行を削除します。テーブルのサイズは変わりません。

このページによるとmyisam_data_pointer_size、デフォルト値が 6 バイト (および削除用に 1 バイト) であることに関係しています。

そして、私がこれを行うかのように、彼は正しいようです:

alter table foo MAX_ROWS=10;

テーブルのサイズが小さくなります。

さらに、この「バグ」レポートから、削除されたレコードが次のレコードへのポインタとして保存されているように聞こえます。その場合、行の最小スペースはポインタ サイズ (デフォルトでは 6 バイト) に削除バイトを加えたものになります。これは、レコードが削除されると、削除バイトが設定され、残りの 6 バイトが次のレコードを指すために使用されるためです。

詳細情報が必要な場合は、MyISAM テーブルの「リンク チェーンの削除」を参照してください (固定レコード数を使用する場合)。

于 2012-08-17T04:09:41.983 に答える