性能使生产数据匿名化

时间:2015-03-23 15:30:16

标签: ruby-on-rails ruby

我们有一个拥有约1000名用户的生产数据库。出于测试目的,我们在开发和登台服务器上使用此数据库的匿名版本。但出于安全考虑,我们不希望将我们的实际生产数据放在5个不同的地方。

因此我们设计了一个简单的脚本:

user_count = 0
User.all.find_each(batch_size: 1000) do |user|
  user.email = "user#{user_count}@example.com"
  user.password = '123456'
  user.save!
  user_count += 1
end

问题在于表现糟糕。它已经需要几分钟才能运行,我们希望/希望用户数量会增长。

我们需要用户在脚本之后仍然拥有唯一的电子邮件。

任何使这种情况发生得更快的解决方案?

(我不确定它是否相关,但我们使用authlogic进行身份验证)

3 个答案:

答案 0 :(得分:1)

如果我理解正确,您需要一个填充数据生成的数据库,但在测试环境的几个字段中使用随机值。

您可以为此目的直接运行MySql查询,这将非常快。假设您有一个唯一的列MD5,您可以使用id函数生成随机值:

UPDATE users set email = CONCAT(MD5(id),"@example.com"), password = rand(a big number);

这将使用随机电子邮件ID更新用户,您可以使用MySql功能的其他组合,例如CONCATrand来相应地设置电子邮件。

答案 1 :(得分:1)

问题是你是在拉动所有用户并每次更新它们。我建议您直接更新数据库。 ActiveRecord将允许您执行直接SQL,因此这样的事情可能会起作用,具体取决于您加密密码的方式以及密码实际存储在哪个字段中:

password = my_password_hasher '123456'
sql = "UPDATE users SET email=concat('user', id, '@example.com'), password_digest = #{password}"
User.connection.execute sql

答案 2 :(得分:1)

我这样解决了。它将时间从160秒减少到0.09秒

u = User.last
u.password = '123456'
User.update_all("email = CONCAT('user', ID, '@example.com'), crypted_password = '#{u.crypted_password}', password_salt = '#{u.password_salt}'")