schema.rbにROW_FORMATの記載が出てきてびっくりしたのでまとめてみた!


グロービスでは2022年までの5年間、「アジア化」をテーマに、Edtechを推進し、日本初の学習プラットフォームの提供を行っています。サーバーサイドエンジニアとしてRailsを書いてます。Let's go global♬

…今日はそんな開発中にdb/schema.rbに膨大なdiffが出てビビった話w

「innodb_file_format」と「row_format」って?

Railsの開発やっている時、DBで気にするのは、character_setくらいでした。
ゼロからRailsのアプリ作って、MySQL立てて…って何も考えずやると、

$ show variables like "chara%";
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | latin1 |  <--- latin1になってる!!
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+

みたいな感じになって、my.cnfの設定直してMySQLを再起動するハメになったり。

文字通りだけど、
innodb_file_formatはファイルのフォーマットで、row_formatは行のフォーマット。

だから、「innodb_file_format」って?

innodb_file_formatには、Antelopeとそれより新しいフォーマットのBarracudaがあって、インデックスレコードの使い方が違う。

Antelope
可変長カラム(VARCHARとか、TEXTとか)の先頭768バイトをインデックスレコードに格納し、残りをオーバーフローページに格納する。
可変長カラムが多いと行の最大長に達してしまう…

Barracuda
可変長カラム(VARCHARとか、TEXTとか)の全てを外部のオーバーフローページに格納し、クラスタインデックスレコードにそのページへのポインタ(20B)のみを格納する。
ポインタのみを格納するためより多くの文字列を格納できる。

そして、「row_format」って?

row_formatにはinnodb_file_formatにも依存する形で4つある。
テーブルにするとわかりやすい!

innodb_file_format row_format 簡単な内容 file_format毎のデフォルトrow_format
Antelop Redundant 昔使われてた…
Antelop Compact Redundantよりもデータサイズが小さくないるようになっている?
Barracuda Dynamic データ圧縮をされない
Barracuda Compressed データ圧縮をされる

まとめ

ちなみに、MySQL5.7.7以上だとBarracudaがデフォルトのinnodb_file_formatだそう。
schame.rbは、ROW_FORMAT=DYNAMIC(緑枠線囲い)が増えたのだけど、
heroku->AWS移行時にMySQLのバージョンが上がったのが原因っぽい気がする。

たまに、こうやって調べると色々勉強になる^^

(参考)設定を確認するためのコマンド

/* innodb_file_formatがわかる */
$ SHOW GLOBAL VARIABLES LIKE '%innodb_file_%';

/* row_formatがわかる */
$ SHOW TABLE STATUS LIKE '%table_name%';

/* MySQLのバージョンを確認 */
$ select version();