在处理大量用户群时,使迁移无痛

时间:2015-07-06 21:08:13

标签: mysql sql ruby-on-rails ruby

我想知道当你拥有庞大的用户群时,处理缓慢迁移的最佳方法是什么?

例如,我正在将用户的电子邮件列移动到user_emails表,以允许用户发送多封电子邮件。所以,我的迁移看起来像这样:

class MoveLegacyPrimaryEmailToUserEmails < ActiveRecord::Migration
  def change
    users = User.all
    users.each do |user|
      user_email = UserEmail.new
      user_email.user_id = user.id
      user_email.email = user.legacy_primary_email
      user_email.save!
      user.primary_user_email_id = user_email.id
      user.save!
    end
  end
end

根据我已完成的模拟,运行需要约66分钟。为了加快速度并避免停机,我将其转换为原始SQL语句:

class MoveLegacyPrimaryEmailToUserEmails < ActiveRecord::Migration
  def change
    execute <<-SQL
      INSERT INTO user_emails (email, user_id)
        SELECT legacy_primary_email, id FROM users;
    SQL
    execute <<-SQL
      UPDATE users
        INNER JOIN user_emails
        ON users.legacy_primary_email = user_emails.email
        SET users.primary_user_email_id = user_emails.id;
    SQL
  end
end

这是处理这类问题的正确方法,还是我遗漏了一些明显的问题?

1 个答案:

答案 0 :(得分:1)

我通常会在多阶段部署中看到这个问题:

  1. 部署使用新数据库结构的代码(如果可用),如果没有,则返回旧数据。
  2. 将数据迁移到新结构。
  3. 部署仅使用新数据结构的代码。
  4. 将旧结构迁移到遗忘状态。
  5. 话虽如此,我不喜欢照看长达数小时的部署。如果你可以通过编写原始SQL来快速完成它,那就去做吧。如果这足以让它足够快,只需一步即可完成部署,奖金!