rename_column会处理索引吗?

ran*_*guy 58 activerecord ruby-on-rails database-indexes ruby-on-rails-3 rails-activerecord

说,我们有这样的事情:

add_column :users, :single, :boolean
add_index :users, :single
Run Code Online (Sandbox Code Playgroud)

然后我们做

rename_column :users, :single, :married
Run Code Online (Sandbox Code Playgroud)

ActiveRecord和/或数据库是否也会处理索引的重命名,还是我必须手动删除索引并再次添加它?

mu *_*ort 96

对于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] || {})
Run Code Online (Sandbox Code Playgroud)

在里面copy_table_indexes:

columns = index.columns.map {|c| rename[c] || c }.select do |column|
  to_column_names.include?(column)
end
Run Code Online (Sandbox Code Playgroud)

因此,标准驱动程序将在您执行操作时保留索引,rename_column并且SQLite驱动程序会尽一切努力.

API文档没有指定任何特定的行为,因此其他驱动程序可能会做其他事情.最接近文档的是关于索引的说法是active_record/migration.rb:

rename_column(table_name, column_name, new_column_name):重命名列但保留类型和内容.

我认为任何司机都会保留索引,但不能保证; 如果不保留索引,驱动程序编写者肯定是愚蠢的.

这不是权威或权威的答案,但如果您使用标准PostgreSQL,MySQL(其中一个)或SQLite驱动程序,则应保留索引.


请注意,即使索引本身在列重命名后仍然存在,也无法保证索引名称将被更改.这不应该是一个问题,除非您正在做一些关心索引名称而不是涉及哪些列的事情(例如手动删除它).

Rails 4中的上述行为已更改:

  • 在Rails 4.0中,当重命名列或表时,也会重命名相关索引.如果您具有重命名索引的迁移,则不再需要它们.

因此,重命名表或列时,ActiveRecord将自动重命名索引以匹配新的表或列名称.感谢sequielo对此进行了单挑.

  • 我的迁移(通过更改)有效地更新了索引,但**不是**索引的名称.名称仍为"index_ [table_name] _on_ [old_col_name]" - Rails 3.2.11,sqlite3 (4认同)
  • "在Rails 4.0中,当重命名列或表时,也会重命名相关索引.如果您有重命名索引的迁移,则不再需要它们.",来源:http://edgeguides.rubyonrails.org/upgrading_ruby_on_rails. HTML#升级,从护栏-3-2至轨-4-0-主动纪录 (4认同)