Rubyist

Always Check In Schema.Rb

有时,Rails开发者不确定schema.rb文件是否应该签入到源代码版本控制中。答案很简单:是的。

正如你所熟悉的,Rails鼓励开发者通过Migration来改变数据库的状态。一个迁移,增加了一些表,又一个迁移,增加了几个列,或删除一些东西。正如你所知,这是一个保持开发者之间数据库结构同步的伟大方式。

每添加一个Migration,然后运行它,schema.rb文件被修改,呈现出你的数据库的最终状态。这看似是自动完成,所以一些开发者认为,这个文件应该留在你的项目之外。

Don’t Store It Just Because David Heinemeier Hansson Said You Should

首先,这是一个可怕的理由。通常,像这样的争论很容易找到一个专家,找到相关的结论。例如: commit in Rails where DHH suggests you store schema.rb

这可以结束一场争论,但是这不是争论本身。 专家之所以是专家,因为他们对某些领域有着深刻的理解。

Don’t Store Generated Files, Except For Schema.Rb

作为一个编译语言的通用规则:你不应该把自动生成的文件放到版本控制当中。之所以成为规则,不是因为专家这样说,也不是因为大多数人觉得这是一个规则,而是因为不这样做的话你的程序就有可能无法正确运行。

如果你把自动生成文件放到版本控制当中,将来有一天你会发现,当你修改了生成文件的程序,你阻止了某个文件的产生,但是如果这个文件已经被放到了版本控制之中,你的程序出现了异常,直到你跟踪到版本控制里的那个文件还存在的时候你才恍然大悟..

此外,如果你修改了你的自动生成文件程序,不是阻止了某个文件的产生,而是想要换一个文件名字。以前放到版本控制当中的文件成了未使用的代码,这给其他开发人员带来了不必要的麻烦。更糟糕的是,这个未使用的代码的存在,也可能成为程序无法运行的原因。这样的代码被称为“code turds”,如果不打算使用,它就不应该出现。

尽管这样,schema.rb不会影响程序的执行,所以放到版本控制里面是没有一点危险的。避免将自动生成的文件放到版本控制里是一个好的规则,但是明白什么时候打破这个规则也是非常重要的。

File Churn In Source Control Is Not An Issue With Schema.Rb

当你关心你的数据库结构的变化过程,把schema.rb放到版本控制是很有价值的。很多Migration频繁发生的时候,是很难跟踪Migration是如何改变数据库的。但是,通过审查schema.rb的提交记录,却可以很容易揭示你的开发团队的问题。

Conflicts In Schema.Rb Are Valuable

如果你的开发团队对某个数据库字段的设计产生分歧,那么现在的问题不是去解决schema.rb的冲突,而是要去去解决开发者对数据库结构设计的分歧。而将schema.rb放到版本控制当中会很容易揭示这样的问题。

在你提交代码到任何分支之前,你应该:

  1. 运行测试
  2. 从版本库pull最新的代码然后合并修改
  3. 重新运行Migration
  4. 重新运行测试
  5. 提交你的修改,并包括schema.rb文件

以上这些步骤确保你的测试运行所用的数据库和其他人的是同步的。并且你提交的schema.rb文件是最新的。 可能你不希望运行两次测试,但是你要保证在从版本库签下最新代码并合并自己的修改后运行一次测试。

Store It Because Schema.Rb Is A Representation Of The Current State Of The Database

在开发过程中,schema.rb可以把数据库的精确结构展现给你。新的团队成员可以通过运行rake db:schema:load来得到一个全新的可以运行的数据库环境(除了少量种子数据外)。

对于新的开发人员来说,他不需要关心数据库结构迁移的过程,例如,某个列从username改成了login,又或者某个列从text类型变为了string类型。他们最直接的需求就是得到一个可以正确运行的数据库环境。而schema.rb已经做了这一切。

Application Code Mixed With Migrations Can Cause Problems

有时候你需要修改数据库结构,然后在Migration里面做ProductType.reset_column_information这样的事情,又会添加一些简单的数据。这里我们不讨论这样做是否是适当的。但是当你这样做的时候问题就会出现:如果你移除了ProductType这个模型,或者你把ProductType重命名为Category了,这样你必须去对Migration做额外的维护。这是一个毫无意义的工作。 其实这也是一个不应该混淆seed和migration的例子。

Migrations Are Slow

Migration会随着数据库结构的频繁改动和迁移文件的增多越来越慢,而schema.rb跳过了这些改动,直接呈现出数据库结构的最终状态,是快的。

Your Blank Slate Production Database Only Needs The Final State

一个空的生产环境数据库只需要迁移到最终状态,运行Migration也是多余的。schema.rb同样为你跳过不必要的迁移过程。 但是对于一个已经存在数据的生产环境数据库,千万不要运行rake db:schema:load,一定要使用Migration.

Keep Schema.Rb With Your Code

总之,添加schema.rb到项目版本控制对你的团队所有成员都是百利而无一害的。

  • 它可以快速迁移数据库到你期望的状态;
  • 它可以给你的数据库结构一个清晰的呈现;
  • 它可以揭示冲突;
  • 它不影响你的程序的正确运行。

原文地址:Always Check In Schema.Rb

标签 Migration, scheme.rb, DHH, seed

(使用BBCodeTextileGist)