Rails迁移创建Session表唯一索引遇MySQL键长度限制求助
解决Rails迁移创建Session表时的MySQL键长度限制问题
问题原因
MySQL InnoDB引擎对单列索引有默认键长度限制(767字节)。当数据库使用utf8mb4字符集时,每个字符占用4字节,而Rails默认string类型长度为255,255×4=1020字节,超出了767字节的限制,因此创建唯一索引时触发报错。
解决方案
方案1:限制字段长度并指定索引长度(推荐)
修改迁移文件,给session_id设置合适的长度,同时在创建索引时指定长度,确保总字节数不超过767:
def change create_table :sessions do |t| # 191×4=764,符合767字节限制 t.string :session_id, null: false, limit: 191 t.text :data t.timestamps end add_index :sessions, :session_id, unique: true, length: 191 add_index :sessions, :updated_at end
方案2:修改表字符集为utf8(仅适用于无需支持4字节字符场景)
创建表时指定字符集为utf8(即utf8mb3,每个字符占3字节),255×3=765,符合限制:
def change create_table :sessions, options: "CHARACTER SET utf8 COLLATE utf8_general_ci" do |t| t.string :session_id, null: false t.text :data t.timestamps end add_index :sessions, :session_id, unique: true add_index :sessions, :updated_at end
方案3:开启InnoDB大前缀支持(全局配置)
若MySQL版本为5.7.7+或8.0+,可修改MySQL配置文件(如my.cnf)开启大前缀支持,允许最长3072字节的索引键:
[mysqld] innodb_large_prefix = on innodb_file_format = barracuda innodb_file_per_table = on
重启MySQL服务后重新执行迁移即可。
验证
执行迁移命令:
rails db:migrate
迁移成功后,可通过MySQL命令查看索引:
SHOW INDEX FROM sessions;
内容的提问来源于stack exchange,提问作者Anton-Ivanov
相关产品推荐
相关产品推荐

