为什么使用数据库迁移而不是版本控制的模式

时间:2009-04-04 06:30:19

标签: orm migration

迁移无疑比仅仅启动phpMyAdmin和更改架构更好(就像我在php时期所做的那样),但在使用它们一段时间之后,我认为它们存在致命缺陷。

版本控制是一个已解决的问题。迁移的主要功能是保留数据库更改的历史记录。但是为每次更改存储不同的文件是一种笨拙的方式来跟踪它们。如果要添加新的虚拟属性,则不要创建post.rb的新版本(或表示增量的文件) - 为什么要在需要时创建新的迁移?添加新的非虚拟属性?

换句话说,正如您将post.rb检入版本控制一样,为什么不将schema.rb检查到版本控制中并直接对文件进行更改?

这在功能上与为每个delta保留文件相同,但使用起来要容易得多。我的心理模型是“我希望表X有这样的列(或者我真的希望模型X具有这样的属性)” - 为什么你必须从这里推断如何从现有的模式中获得;只需打开schema.rb并为表格X提供正确的列!

但即使是类包装表的想法也是一个实现细节!为什么我不能打开post.rb并说:

 Class Post
    t.string :title
    t.text :body
 end

如果你使用这样的模型,你必须决定如何处理现有数据。但即便如此,迁移也是过度的 - 当您迁移数据时,当您使用迁移的down方法时,您将失去保真度。

无论如何,我的问题是,即使你想不出一个更好的方式,迁移也不是很严重吗?

6 个答案:

答案 0 :(得分:9)

  

为什么不将schema.rb检查到版本控制中并直接对文件进行更改?

因为数据库本身与版本控制不同步。

例如,您可能正在使用源树的头部。但是,您要连接到已定义为过去版本的数据库,而不是您已签出的版本。迁移允许您逐步升级或降级数据库架构从任何版本升级到任何版本。

但要回答你的上一个问题,是的,迁移有点严重。他们在另一个修订控制系统之上实施冗余修订控制系统。但是,这些修订控制系统都没有真正与数据库同步。

答案 1 :(得分:6)

简单地解释其他人所说的内容:迁移可让您在架构发展过程中保护数据。只有在您的应用投入生产之后,维护单个schema.rb文件的概念才具有吸引力。此后,您需要一种在架构更改时迁移现有用户数据的方法。

答案 2 :(得分:5)

还有一些重要的数据相关问题需要考虑,哪些迁移可以解决。

假设我的架构的旧版本有feetinches列。出于效率目的,我希望将其合并到inches列中,以便更轻松地进行排序和搜索。

我的迁移可以在更新数据库时(即在删除feet列之前)将所有英尺和英寸数据合并到英寸列(英尺* 12英寸)中

显然,在迁移过程中,当您稍后将更改应用到生产数据库时,它会自动生效。

答案 3 :(得分:2)

我认为“即使你不能想出更好的方法”,那么是的,在宏观的计划中,迁移是有点粗暴的。 Ruby,Rails,ORM,SQL,Web应用程序也是如此......

迁移具有(并非无关紧要)优势。总体而存在往往胜过满意而不存在。我确信可能有令人愉快且不存在的方法来迁移您的数据,但我不确定这意味着什么。 : - )

答案 4 :(得分:2)

就目前而言,它们令人烦恼且不足,但很可能是我们目前可用的最佳选择。相当多的聪明人花了很多时间来解决这个问题,到目前为止,这是他们能够想出的最好的。经过大约20年的手工编码数据库版本更新后,当我找到ActiveRecord时,我非常迅速地将迁移视为一项重大改进。

正如您所说,版本控制是一个已解决的问题。在某种程度上我同意:特别是文本文件已经解决了,对于其他文件类型则更少,而对数据库等资源来说根本就没有。

如果将迁移视为数据库的版本控制增量,迁移将如何显示?它们是您必须应用于从一个版本到另一个版本的模式的总和。我不知道即使是git,因为它的超级强大,它可以采用两个模式文件并生成必要的DDL来实现这一点。

至于在模型中声明表格内容,我相信这就是DataMapper的作用(没有个人经验)。我认为那里也可能有一些DDL推理功能。

“即使你想不出更好的方式,迁移还不是很严重吗?”

是。但它们不如我们拥有的任何其他东西。当您完成非粗略替代方案时,请告诉我们。

答案 5 :(得分:0)

好的,我会在这里猜测一下你说你可能一个人工作。在一个小组开发项目中,每个人都有责任为开发人员编写的代码所需的数据库更改负责,这一点非常重要。

另一种选择是更大的程序员团队(例如我工作的10-15名Java开发人员)最终依靠几个专职的全职数据库管理员来完成这项工作以及其他维护,优化等职责。< / p>