MySQLのVARCHAR型について255バイトまではストレージ節約できるよ~みたいな記事を見かけるので少し調べてみた。
以下にこの辺は記載されています。
https://dev.mysql.com/doc/refman/8.0/ja/char.html
前提としておさえておくこと
VARCHAR(5) と指定したときの5はバイト数ではなく文字数
つまりaaaaa
の1バイト文字 x 5でも あいうえお
の2バイト文字 x 5でも保持できます。
VARCHAR(255)って何が嬉しいの?
これにはMySQLがVARCHARカラムに対してどのようにストレージをを確保・利用するかを理解する必要があります。
・計算式
1つのカラム/レコードに対して必要なバイト数 = 長さプレフィックス + カラムの保持する文字列データ
長さプレフィックス
長さプレフィックスとは可変長のVARCHARに対してどれだけ長さが必要かを示す数値(バイト数)です。
例えばVARCHAR(10)に対して
aaa
を格納した場合、 以下のようになります。
[長さプレフィックス1バイト][文字列データ]
[3][a][a][a]
この長さプレフィックスが必要とする(↑だと3という情報を保持する)バイト数は、カラムに保持する文字列長(バイト数)によって決まります。
文字列長(バイト数) | 長さプレフィックスとして必要バイト数 |
---|---|
1~255 | 1 |
256~65,535 | 2 |
例えばVARCHAR(70)の場合、
1バイト文字が70入れば70バイトで長さプレフィックスは1バイト。
4バイト文字が70入れば280バイトで長さプレフィックスは2バイト。
カラムの保持する文字列データ
これはシンプルで
varchar(10)にaaaaをいれたら4バイト。
4バイト文字を10文字いれたら40バイトという計算です。
aaaaで4バイトとなったとき、長さプレフィックスは1バイトで足りるので、合計のストレージは
長さプレフィックス(1バイト)+ 文字列長(4バイト) = 5バイトです。
長さプレフィックスが1バイトか2バイトかってそんなに気にしなくてもよいのでは?
注意しておく必要があるのがカラム/レコード単位で必要ということですね。
レコード数 | 長さプレフィックス1の場合 | 長さプレフィックス2の場合 |
---|---|---|
1万 | 0.0095MB | 0.02MB |
100万 | 0.95MB | 2MB |
1000万 | 9.5M | 20MB |
1億 | 95M | 200MB |
まとめ
- レコード数とカラムが多い(レコード100万以上とか)テーブルは長さプレフィックスは意識しておいたほうがよさそう
- レコード数やカラム数が多くない場合、そんなに気にしなくてよい。(ほぼ影響なし)
- 何文字が上限と決まっているのであればその値をセットするのがベスト
- 何文字くるかわからないけど、多めにとっておきたいというのであれば255文字を基準にするのもありだと思う
- 255文字にしても中身に何バイト文字が入ってくるかで長さプレフィックスは1バイトになるときも2バイトになるときもあるので全てのケースにおいて節約とまではいかないよ