ただのメモ。
GrowthForecast のテーブルを作ろうと以下の DDL を打ったら失敗した。# 正確には、GF は自動で作ろうとしてくれるが、その時に失敗していた。
CREATE TABLE IF NOT EXISTS complex_graphs (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
service_name VARCHAR(255) NOT NULL COLLATE utf8_bin,
section_name VARCHAR(255) NOT NULL COLLATE utf8_bin,
graph_name VARCHAR(255) NOT NULL COLLATE utf8_bin,
number float UNSIGNED NOT NULL DEFAULT 0,
description VARCHAR(255) NOT NULL DEFAULT '',
sort INT UNSIGNED NOT NULL DEFAULT 0,
meta TEXT,
created_at INT UNSIGNED NOT NULL,
updated_at INT UNSIGNED NOT NULL,
PRIMARY KEY (id),
UNIQUE (service_name, section_name, graph_name)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
エラーメッセージは次のようなもの
ERROR 1071 (42000): Specified key was too long; max key length is 1000 bytes
あれ、なんで今まで大丈夫だったんだ?と思ったので調べた。1000 bytes 制限が出るのは、MyISAM の場合らしい。
MyISAM の場合、複合インデックスで全てのカラムの byte 数を合計した結果が 1000 bytes を超えるとダメで、(255 + 255 + 255) * 3 (utf8)
で 1000 bytes 超えたから出たようだ。
つまり、InnoDB プラグインかなにかがちゃんと設定できていなくて、InnoDB で table 作ったつもりが、MyISAM になってしまっていたということだな。
ちなみに InnoDB の場合は 767 byets 制限のメッセージが出る事がある。
ERROR 1071 (42000): Specified key was too long; max key length is 767 bytes
こちらは、複合インデックスでもカラムそれぞれの制限値[1][2]になっているようだ。今回の場合は 255 * 3 (utf8) = 765 bytes なので、制限を超えずちゃんとテーブルを作れる。
なお、mysql5.6 にして utf8mb4 に使おうとすると、255 * 4 (utf8mb4) = 1020 bytes となり、制限を超えてしまうが、その場合は、innodb_large_prefix
というオプションを ON にすると、3072 bytes まで扱える。
[1] http://blog.kamipo.net/entry/2012/11/13/102024 ひとつのカラムのキープレフィックスの最大値が767バイト
[2] http://treeapps.hatenablog.com/entry/20110508/p2 カラム分割も制限をかわす1つのテクニックになりうる