fuelphpのマイグレーションでvarchar型、text型にインデックスを付ける
環境
fuelphp : 1.7.1
PHP : 5.3.3
mysql : 5.5.34
charsetをutf8mb4にしたため普通に
\DBUtil::create_index('table', 'text_data');
とかやると
Index column size too large. The maximum column size is 767 bytes.
が出て怒られる。
やったこと
my.cnfに
innodb_file_format = Barracuda innodb_file_per_table = 1 innodb_large_prefix
を追加。
キープレフィックスの制限を大きくする(3072バイトまで)
ここまでは普通の対応なのだが、ここから荒業。
DBUtilクラスのcreate_tableメソッドにはrow_formatを指定するところが無いので、
エンジンを指定するときに無理やりいれてしまう。
公式ドキュメントを引用すると
\DBUtil::create_table( 'users', array( 'id' => array('constraint' => 11, 'type' => 'int', 'auto_increment' => true), 'name' => array('type' => 'text'), 'email' => array('constraint' => 50, 'type' => 'varchar'), 'title' => array('constraint' => 50, 'type' => 'varchar', 'default' => 'mr.'), 'text_data' => array('type' => 'text'), 'password' => array('constraint' => 125, 'type' => 'varchar'), ), array('id'), false, 'InnoDB row_format=DYNAMIC', 'utf8_unicode_ci',array() );
上記の’InnoDB row_format=DYNAMIC’の部分。
本来ここはストレージエンジンを指定する場所だが、ここに入れておくとうまくSQLに展開してくれた。
次にインデックスの追加
text型の場合、キーの長さを指定する。
普通に書くとエスケープ?されるのでDB::exprで囲む
\DBUtil::create_index('users', \DB::expr('text_data(1023)'), 'text_index');
こんな感じ。
これでとりあえずインデックス付けれました。
が、一つ問題があって、text型のカラムを1023バイトって指定したにもかかわらず実際に出来たテーブルを見ると
KEY `text_index` (`text_data`(768))
と768バイトでインデックスが追加されてました。
上でinnodb_large_prefixを指定してるのになんでこのバイト数なのか。。
varchar(300)のカラムとかもインデックス追加してて上記のエラーが出ないのでinnodb_large_prefixはちゃんと反映されてるはず・・・。
なのですがこれは結構調べましたが結局わかりませんでした。