RDSでtext型のカラムを300個程度持つテーブルを作成する必要があったときのこと。CREATE TABLEを行う際にRow size too largeエラーが消えずに色々試しました。
パラメータグループはデフォルトの値から以下のように変更しています。
innodb_file_format Barracuda innodb_large_prefix 1
character_set関連の設定はテスト用に作ったテーブル内の日本語が文字化けしたために設定したものであって今回の内容には直接関係ないと思います。
Row size too largeで調べると上記の設定をするといいよ、という情報がたくさん見つかります。とりあえず上記の設定をパラメータグループに対して行いRDSインスタンスを再起動した後で以下のCREATE TABLE文を実行してみました。
CREATE TABLE `sample` ( `id` int(11) NOT NULL AUTO_INCREMENT, `text1` text, `text2` text, `text3` text, `text4` text, `text5` text, -- 中略 `text298` text, `text299` text, `text300` text, PRIMARY KEY (`id`) ) ROW_FORMAT=DYNAMIC ENGINE=InnoDB DEFAULT CHARSET=utf8;
が、変わらず以下のエラーが出る(´;ω;`)
[Err] 1118 - Row size too large (> 8126). Changing some columns to TEXT or BLOB may help. In current row format, BLOB prefix of 0 bytes is stored inline.
その後、
- sql_modeをセッション中空にしてみる → ×(解決せず)
- innodb_log_file_sizeを増やす → ×(デフォルト値の100倍にしてみたらRDSのディスク容量が0になった^q^)
- innodb_strict_modeをセッション中0にしてみる → ○
ということで以下のようなSQLでテーブルを作成することができました。
SET innodb_strict_mode = 0; CREATE TABLE `sample` ( `id` int(11) NOT NULL AUTO_INCREMENT, `text1` text, `text2` text, `text3` text, `text4` text, `text5` text, -- 中略 `text298` text, `text299` text, `text300` text, PRIMARY KEY (`id`) ) ROW_FORMAT=DYNAMIC ENGINE=InnoDB DEFAULT CHARSET=utf8;
以下のようなtext型カラムにランダムな128文字をセットするSQLが無事通ることを確認しました( ・`д・´)
insert into sample ( text1, text2, text3, -- 省略 text299, text300 ) values ( sha2(md5(rand()), 512), sha2(md5(rand()), 512), -- 省略 sha2(md5(rand()), 512), sha2(md5(rand()), 512), sha2(md5(rand()), 512) );
特別な理由がない限りこういうテーブルは作っちゃいけないんだと思います。