比如,我们有这样的东西:
add_column :users, :single, :boolean
add_index :users, :single
然后我们就开始了
rename_column :users, :single, :married
ActiveRecord和/或数据库是否也会处理索引的重命名,还是必须手动删除索引并再次添加?
比如,我们有这样的东西:
add_column :users, :single, :boolean
add_index :users, :single
然后我们就开始了
rename_column :users, :single, :married
ActiveRecord和/或数据库是否也会处理索引的重命名,还是必须手动删除索引并再次添加?
对于PostgreSQL,rename_column
被实现为一个简单的ALTER TABLE ... RENAME COLUMN ...
,这确实保留了索引.
MySQL版本(两个版本)都是ALTER TABLE ... CHANGE ...
,这也保留了索引.
SQLite版本似乎会复制整个表(带有索引),删除旧表,然后将副本复制回原始表名.复制索引时,复制操作似乎会处理列重命名:
def copy_table(from, to, options = {})
#...
copy_table_indexes(from, to, options[:rename] || {})
在copy_table_indexes
之内:
columns = index.columns.map {|c| rename[c] || c }.select do |column|
to_column_names.include?(column)
end
因此,当你使用rename_column
时,标准驱动程序会保留你的索引,而SQLite驱动程序会努力做到这一点.
API文档没有指定任何特定的行为,不过其他驱动程序可能会执行其他操作.文档中关于索引的最接近的说法是:
rename_column(table_name, column_name, new_column_name)
:重命名列,但保留类型和内容.
我认为任何驱动程序都会保留索引,但这并不能保证;如果驱动程序编写人员不保存索引,那肯定是愚蠢的.
这不是一个明确或权威的答案,但如果使用标准的PostgreSQL、MySQL(任意一种)或SQLite驱动程序,则应该保留索引.
请注意,即使索引本身在列重命名后仍然存在,也不能保证索引name会被更改.这应该不会是一个问题,除非你做的事情(比如手动删除它)关心的是索引名,而不是涉及哪些列.
上述行为changed in Rails 4:
- 在Rails 4.0中,当列或表被重命名时,相关的索引也会被重命名.如果有重命名索引的迁移,则不再需要它们.
因此,当您重命名表或列时,ActiveRecord将自动重命名索引以匹配新的表或列名.多亏了sequielo人的提醒.