简体   繁体   English

在Rails DB迁移期间截断表是否有风险?

[英]Is it risky to truncate a table during a Rails DB migration?

I'm adding a migration that is adding a unique index to a MySQL table. 我正在添加一个向MySQL表添加唯一索引的迁移。 Is there any real risk in truncating any existing data in the table so the unique index can be added, given that existing data in the table may not be unique? 鉴于表中的现有数据可能不是唯一的,因此截断表中的任何现有数据是否存在任何实际风险,因此可以添加唯一索引?

It's important to mention that this app is still in development and has not yet been released to production, and therefore we would not be losing any real user data. 值得一提的是,该应用仍在开发中,尚未发布到生产环境中,因此我们不会丢失任何真实的用户数据。

Can anyone come up with a real-world scenario in which we might lose important data down the line? 谁能提出一个现实世界的场景,在这个场景中我们可能会丢失重要的数据?

Code example of the migration: 迁移的代码示例:

class AddUniqueIndexToFooOnBarAndBaz < ActiveRecord::Migration
  def up
    ActiveRecord::Base.connection.execute("TRUNCATE foo")
    add_index :foo, [:bar_id, :baz_id], unique: true
  end

  def down
    remove_index :foo, [:bar_id, :baz_id]
  end
end

tl;dr- you won't hurt anything really, but don't do that TRUNCATE anyway. tl; dr-您不会真正伤害任何东西,但是无论如何都不要这样做。 Do a db:reset 执行db:reset

What happens when you write a migration is that the db/schema.rb file gets changed and its version is set to the timestamp on the last migration that was run. 编写迁移时,将发生db/schema.rb文件被更改且其版本设置为上一次运行的迁移的时间戳的情况。 The migration files exists so that: 存在迁移文件是为了:

  1. You can have concrete files which demonstrate the changes to the database over time, using a DSL which makes sense. 您可以使用有意义的DSL,来获得具体的文件来说明数据库随时间的变化。
  2. You can rollback the changes to your database semi-arbitrarily, if you discover something is wrong during development (don't rollback your production DB, just write a new migration) 如果发现在开发过程中出现问题,则可以将更改半任意地回滚到数据库(不要回滚生产数据库,只需编写新的迁移)

This means that migration files should show what you're doing to the database and that TRUNCATE isn't really what you're doing to the DB, it's what you're doing to the data . 这意味着迁移文件应该显示您正在对数据库执行的操作,而TRUNCATE并不是您实际上对数据库所做的操作,而是您对数据所做的操作。 It won't break anything and that SQL snippet won't run if you deploy a new environment using a schema that's already migrated, but for any environment that's already up, it will. 如果使用已迁移的架构部署新环境,它不会破坏任何内容,并且不会运行SQL代码段,但是对于任何已经运行的环境,它都会运行。 That's just kinda weird and definitely unnecessary. 那有点奇怪,而且绝对没有必要。

The Details 细节

What happens when you deploy your app for the first time in an environment is you (should) run rake db:create db:schema:load db:seed or rake db:setup (which just farms out to the other commands). 当您在环境中首次部署应用程序时,会(应该)运行rake db:create db:schema:load db:seedrake db:setup (这只会出现在其他命令中)。 db:schema:load simply converts your schema.rb file into an actual database schema, with tables and indices and all that fun stuff. db:schema:load只需将您的schema.rb文件转换为具有表和索引以及所有有趣内容的实际数据库模式。 After you've run your migration, your schema file will have the index you want . 运行迁移后,架构文件将具有所需的索引 Then, whenever you deploy to production, your database will look like you want it to out of the box, before any data is added. 然后,无论何时部署到生产环境,在添加任何数据之前,您的数据库看起来都像是要开箱即用的。

In development, you shouldn't be attached to any data that's in your database- it's test data, unimportant and ephemeral. 在开发中,您不应该附加到数据库中的任何数据-它是不重要且短暂的测试数据。 You shouldn't feel bad wiping it all out, especially if you're truncating because the existing data might be invalid/duplicated. 您应该不会感到失望,尤其是在由于现有数据可能无效/重复而被截断的情况下,尤其如此。

Truncating a table has consequences whether you use a rails migration or not. 不管您是否使用Rails迁移,截断表都会产生后果。 The better question is to ask whether it's risky to truncate the table, period. 更好的问题是询问截断表,期间是否有风险。

Since you're not in production, there is no risk of impacting "real" people, but what you have to consider is how will truncating the table impact your data integrity and how as a developer, will you recover from any issues you may encounter. 由于您不在生产环境中,因此不存在影响“真实”人员的风险,但是您需要考虑的是,如何将表截断如何影响您的数据完整性以及作为开发人员如何从可能遇到的任何问题中恢复过来。

For example, if the data you're truncating is in a join table connecting two other tables, then you've lost the relationship between your two tables and you've basically rendered a significant chunk of your data useless. 例如,如果要截断的数据在连接其他两个表的联接表中,那么您就失去了两个表之间的关系,并且基本上已经使大部分数据变得无用了。 However, if the data is in an insignificant table, then the impact is a lot lower. 但是,如果数据在无关紧要的表中,则影响要小得多。

In short, yes, there are risks, but the best person to answer the level of this risk is you. 简而言之,是的,存在风险,但是应对这种风险程度的最佳人选是您。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM