我有一个包含87个db列的rails模型,但是当我尝试添加任何额外的db列时,它失败了
ArbitaryDatum.columns.count
=> 87
ArbitaryDatum.table_name
=> "arbitary_data"
ActiveRecord::Migration.add_column :arbitary_data, :attr51, :string
-- add_column(:arbitary_data, :attr51, :string)
(1.4ms) ALTER TABLE `arbitary_data` ADD `attr51` varchar(255)
Mysql2::Error: Specified key was too long; max key length is 767 bytes: ALTER TABLE `arbitary_data` ADD `attr51` varchar(255)
ActiveRecord::StatementInvalid: Mysql2::Error: Specified key was too long; max key length is 767 bytes: ALTER TABLE `arbitary_data` ADD `attr51` varchar(255)
我检查了我使用的mysql版本,
mysql --version
mysql Ver 14.14 Distrib 5.5.62, for debian-linux-gnu (i686) using readline 6.3
我不明白为什么它不允许添加额外的表列
问。为什么我不能 Mysql2::Error: Specified key was too long
3条答案
按热度按时间sf6xfgos1#
mysql在innodb中的前缀限制为767字节,在myisam中的前缀限制为1000字节,
不幸的是,没有真正的解决办法。您唯一的选择是减小列的大小,使用不同的字符集(如utf-8),或者使用不同的引擎(如myisam)。在本例中,我将字符集切换为utf-8,从而将最大密钥长度提高到255个字符。
将字符集迁移为utf8
cgvd09ve2#
将数据库创建为utf8\u general\u ci,这样就没有问题了
du7egjpx3#
在为这个问题奋斗了三天之后,@muistooshort在评论中说的一件事把我拉向了正确的解决方案。
你可能想在他的评论中重温你的数据库设计,这让我困扰了好几天。所需要的只是正确的方向(这在评论中)&我解决了这个问题。
注意:所提供的数据很少被用来隐藏项目模式结构。
我在添加新列时遇到问题,如错误日志中所述,但这不是由于在表中添加新列造成的。这是由于数据库中现有的表结构造成的。
我是在从
config/schema.rb
与索引一起创建相同的新表arbitary_data_dup
```replaced
arbitary_data
witharbitary_data_dup
ActiveRecord::Migration.create_table "arbitary_data_dup", force: :cascade do |t|
# code to add 87 columns for table
end
following index threw error
ActiveRecord::Migration.add_index "arbitary_data_dup", ["attr1", "arbitary_structure_id"], name: "index_arbitary_data_on_attr1_and_arbitary_structure_id", unique: true, using: :btree
ActiveRecord::Migration.add_index "arbitary_data_dup", ["attr1"], name: "index_arbitary_data_on_attr1", length: {"attr1"=>191}, using: :btree
ActiveRecord::Migration.add_index "arbitary_data_dup", ["id"], name: "index_arbitary_data_on_id", using: :btree
ActiveRecord::Migration.add_index "arbitary_data_dup", ["arbitary_structure_id"], name: "index_arbitary_data_on_arbitary_structure_id", using: :btree
ActiveRecord::Migration.add_index "arbitary_data_dup", ["attr1", "arbitary_structure_id"], name: "index_arbitary_data_on_attr1_and_arbitary_structure_id", unique: true, using: :btree
-- add_index("arbitary_data_dup", ["attr1", "arbitary_structure_id"], {:name=>"index_arbitary_data_on_attr1_and_arbitary_structure_id", :unique=>true, :using=>:btree})
(52.5ms) CREATE UNIQUE INDEX
index_arbitary_data_on_attr1_and_arbitary_structure_id
USING btree ONarbitary_data_dup
(attr1
,arbitary_structure_id
)Mysql2::Error: Specified key was too long; max key length is 767 bytes: CREATE UNIQUE INDEX
index_arbitary_data_on_attr1_and_arbitary_structure_id
USING btree ONarbitary_data_dup
(attr1
,arbitary_structure_id
)ActiveRecord::StatementInvalid: Mysql2::Error: Specified key was too long; max key length is 767 bytes: CREATE UNIQUE INDEX
index_arbitary_data_on_attr1_and_arbitary_structure_id
USING btree ONarbitary_data_dup
(attr1
,arbitary_structure_id
)ActiveRecord::Migration.remove_index "arbitary_data", ["attr1", "arbitary_structure_id"]
-- remove_index("arbitary_data", ["attr1", "arbitary_structure_id"])
(148.6ms) DROP INDEX
index_arbitary_data_on_attr1_and_arbitary_structure_id
ONarbitary_data
-> 0.1698s
=> nil
ActiveRecord::Migration.add_column :arbitary_data, :attr51, :string
-- add_column(:arbitary_data, :attr51, :string)
(523.3ms) ALTER TABLE
arbitary_data
ADDattr51
varchar(255)-> 0.5238s
=> nil