如何跟踪源代码管理中的数据库更改?

时间:2008-12-09 13:57:42

标签: sql-server svn version-control sourcegear-vault

我们在大多数项目中使用SQL Server 2000/2005和Vault或SVN。我还没有找到一个适当的解决方案来捕获源控制系统中的数据库模式/ proc更改。

我们当前的解决方案非常繁琐且难以实施(将您更改的对象编写脚本并将其提交到数据库)。

我们有很多关于如何通过一些自定义开发来解决这个问题的想法,但我宁愿安装一个现有的工具(付费工具很好)。

那么:您如何跟踪数据库代码更改?你有推荐的工具吗?


修改

感谢所有建议。由于时间的限制,我宁愿不在这里自己动手。大多数建议都有缺陷,他们需要开发人员遵循一些程序。

相反,理想的解决方案是监视SQL数据库的更改并将任何检测到的更改提交给SCM。例如,如果SQL Server有一个可以记录任何DML更改的加载项,那么将该对象的脚本提交给SCM,我会很激动。

我们在内部讨论了两个系统:   1.在SQL 2005中,使用对象权限限制您更改对象,直到执行“结帐”。然后,签入过程会将其编入SCM脚本。   2.运行预定作业以检测任何更改并将其(匿名)提交给SCM。

如果我可以跳过用户操作部分并让系统自动处理所有这些,那就太好了。

13 个答案:

答案 0 :(得分:15)

使用Visual Studio数据库版本编写数据库脚本。像魅力一样工作,你可以使用任何源代码控制系统,当然最好是有VS插件。此工具还具有许多其他有用的功能。在这篇精彩的博客文章中查看它们

http://www.vitalygorn.com/blog/post/2008/01/Handling-Database-easily-with-Visual-Studio-2008.aspx

或查看MSDN以获取官方文档

答案 1 :(得分:6)

使用各种第三方工具可以直接从SSMS跟踪数据库更改。 ApexSQL Source Control自动编写版本控制中包含的任何数据库对象。该工具无法自动执行提交。相反,用户需要选择要提交的更改。

从存储库获取更改时,ApexSQL Source Control会识别SQL数据库参照完整性。因此,它将创建一个同步脚本,其中包括将包含在事务中的所有依赖对象,因此,如果未遇到错误,或者未应用任何选定的更改,则将应用所有更改。无论如何,数据库完整性不受影响。

答案 2 :(得分:5)

我不得不说我认为视觉工作室数据库项目也是源控制困境的合理解决方案。如果设置正确,您可以从IDE运行针对数据库的脚本。如果您的脚本是旧的,请获取最新版本,然后针对数据库运行它。如果需要,还有一个脚本可以重新创建所有对象,必须手动将新对象添加到此脚本中,但只能添加一次

我喜欢每个表,proc和函数都在它自己的文件中。

答案 3 :(得分:3)

一个穷人的解决方案是添加一个预提交钩子脚本,将最新的db模式转储到一个文件中,并将该文件与您的代码一起提交到SVN存储库。然后,您可以从任何修订版中区分db模式文件。

答案 4 :(得分:1)

我只是将SQL-alter-Statement提交给完整的SQL-CreateDB语句。

答案 5 :(得分:1)

在SQL2000中将每个对象生成到自己的文件中,然后将它们全部检查到源代码管理中。让您的源代码控制处理更改历史记录。

在SQL 2005中,您需要编写一些代码来将所有对象生成为单独的文件。

答案 6 :(得分:1)

从头开始滚动你自己不是很可行,但是如果你使用像Redgate SQL Compare SDK这样的sql比较工具为你生成你的更改文件,那么你不需要花很长时间来完成所需的操作。只需将这些文件检入源代码管理。我为自己推出了类似的东西,可以在几个小时内更新从我们的开发系统到我们的实时系统的更改。

答案 7 :(得分:1)

在我们的环境中,我们永远不会手动更改数据库:所有更改都是在发布时由脚本完成的,脚本保存在版本控制系统中。此过程的一个重要部分是确保所有脚本可以针对相同的DB再次运行,脚本是幂等的?)而不会丢失数据。例如,如果添加列,请确保在列已存在的情况下不执行任何操作。

您对“建议有缺陷,他们需要开发人员遵循某些程序”的评论确实是一个告诉。这不是一个缺陷,它是一个功能。版本控制可帮助开发人员遵循以下过程并减少程序的痛苦。如果您不想遵循过程,则不需要版本控制。

答案 8 :(得分:0)

我们的dbas会定期检查SVN中的内容并删除任何不受源代码管理的对象。在开发者永远不会忘记再次将某些东西放入源代码控制之前,它只需要一次。

我们也不允许任何人在没有脚本的情况下将对象移动到prod,因为我们的devs没有prod权限,这很容易执行。

答案 9 :(得分:0)

在一个项目中,我在设计中仔细注意安排数据库中的所有重要数据都可以从外部位置自动重建。在启动时,如果数据库丢失,应用程序将创建数据库,并使用应用程序源代码中的模式(因此使用应用程序进行版本控制)从外部数据源填充数据库。数据库存储名称(sqlite文件名,尽管大多数数据库管理器允许多个数据库)包括模式版本,每当我们提交模式更改时,我们都会增加模式版本。这意味着当我们将应用程序重新启动到具有不同模式的新版本时,将自动创建并填充新数据库存储。如果我们必须将部署恢复为旧模式,那么旧版本的新版本将使用旧数据库存储,因此我们可以在发生故障时快速降级。

本质上,数据库就像传统的应用程序堆一样,具有持久性,事务安全性,静态类型(因为我们使用Python而非常方便)和唯一性约束的优点。然而,我们根本不担心删除数据库并重新开始,并且人们知道如果他们在数据库中尝试一些手动黑客攻击,那么它将在下一次部署时被恢复,就像进程状态的黑客将被恢复一样在下次重启时。

我们不需要任何迁移脚本,因为我们只是切换数据库文件名并重新启动应用程序并重建自身。它有助于对应用程序实例进行分片,以便为每个客户端使用一个数据库。它还减少了对数据库备份的需求。

如果从外部源构建数据库所需的时间比允许应用程序保持关闭的时间长,则此方法不起作用。

答案 10 :(得分:0)

如果你使用的是.Net,就像Rails采用迁移的方法一样,那么我会推荐Migrator.Net

我找到了一个nice tutorial,它在Visual Studio中进行设置。他还提供了一个参考样本项目。

答案 11 :(得分:0)

我们开发了一个更新数据库的自定义工具。数据库模式存储在数据库中立的XML文件中,然后由该工具读取和处理。模式存储在SVN中,我们添加适当的注释以显示更改的内容。它对我们来说非常好。

虽然这种解决方案对于大多数项目来说肯定是过度杀伤,但它有时会让生活更轻松。

答案 12 :(得分:0)

为了跟踪插入更新和删除等所有更改,SVN会有很多开销。 最好只跟踪改变架构的ddl更改,例如(alter,drop,create)。 您可以通过创建表和trgger来轻松地执行此模式跟踪,以便将数据插入到该表中。 任何时候你想要你可以通过查询该表获得更改状态 有很多示例herehere