环境:ubuntu 10.10 + mysql 5.1 + rails 3.0.3 + ruby 1.9.2
今天创建组合索引时,遇到下面的错误:
Mysql2::Error: Specified key was too long; max key length is 1000 bytes: CREATE UNIQUE INDEX `unique_users_name_password` ON `users` (`name`, `password`)
问题重现:
表结构:(数据库,表,字段都是utf-8 编码,myisam引擎)
users: name: varchar(255) password: varchar(255)
Rails创建索引:
add_index :users , [:name,:password] , :unique=>true , :name=>"unique_users_name_password" # mysql 唯一索引可以指定多个字段
执行就 Error 了 ,
Google 后 ,得到是 myisam 表组合索引 有长度限制 , 总长度不能 超过 1000 bytes
计算下上面的 总长度(bytes)
utf8 编码 : 1 char = 3 bytes
255 * 3 + 255 * 3 = 1530 bytes
果然大于1000 了 ,修改 name 的字段长度:
change_column :users ,:name , :string , :limit => 100
再建索引 就 ok了……
那么 表改为 innodb 引擎呢 ,不error 了 ,但是 会抱下面的warning
warning:Specified key was too long;max key length is 767 bytes.
why?
原来 innodb表的组合索引的长度 是 767 bytes , 比 myisam 的还少 ,但是 innodb的可以顺利 建索引,超过767长度的部分 建不被索引,前面的取 前缀索引 ,这里 要注意!
建议;
1,表 设置为 innodb
2,建字段时,一定要根据实际情况,限制长度,在 rails migration中就是 加 :limit 参数
see:
http://blog.fesite.com/2009/02/09/mysql-specified-key-was-too-long-max-key-length-is-1000-bytes/
http://samyubw.blog.51cto.com/978243/223773