验证数据库更改(版本控制)

10

我已经阅读了很多有关数据库版本控制重要性的帖子。然而,我无法找到一个简单的解决方案来检查数据库是否处于应该的状态。

例如,我有一个名为“Version”的表的数据库(版本号存储在其中)。但是,开发人员可以访问和编辑数据库,而不更改版本号。例如,如果开发人员更新存储过程并且没有更新版本,则数据库状态与版本值不同步。

如何跟踪这些更改?我不需要跟踪发生了什么变化,而只需要检查数据库表、视图、存储过程等是否与保存在Version表中的数据库版本同步。

为什么需要这样做?在部署时,我需要检查数据库是否“正确”。此外,并非所有表或其他数据库对象都应该被跟踪。是否可以在不使用触发器的情况下进行检查?是否可以在不使用第三方工具的情况下完成?数据库是否具有校验和?

假设我们使用SQL Server 2005。

编辑:

我认为我应该提供有关我们当前环境的更多信息-我们有一个“基线”,其中包括创建基本版本所需的所有脚本(包括数据对象和我们应用程序的“元数据”)。然而,有许多安装了此“基线”版本的其他数据库对象(其他表、视图、存储过程等)。当我们对“基线”版本进行一些更改时,我们还必须更新某些安装(而不是全部),在那时,我们必须检查“基线”是否处于正确状态。

谢谢

11个回答

6
你似乎违反了 "数据库工作的三条规则" 中的第一条和第二条。每个开发人员使用一个数据库和一个单一的权威模式源将会有很大帮助。我不确定你是否对你的数据库有基准线,更重要的是,你是否在使用变更脚本。最后,你可能会在视图、存储过程等方面分支和合并中找到其他答案。

实际上,所有这些链接都在Jeff Atwood的一篇伟大文章中提到:Get Your Database Under Version Control。我认为这是必读的。


嘿,没有人是完美的!我们尝试改变我们的开发流程,但这不可能一天内完成。有时候你必须采取小步骤来实现它。 - Sazug
抱歉Sazug,我只是想提供有用的资源,真的不是故意无礼。 - Pascal Thivent
请提供"数据库工作的三个规则"的链接,+1。 - Not So Sharp

5
我们使用DBGhost来对数据库进行版本控制。当前数据库的创建脚本存储在TFS(与源代码一起),然后使用DBGhost生成增量脚本以将环境升级到当前版本。DBGhost还可以为任何静态/参考/代码数据创建增量脚本。
这需要从传统方法转变思维,但是它是一个非常棒的解决方案,我强烈推荐。虽然它是第三方产品,但它可以无缝地适应我们的自动化构建和部署过程。

我已经使用DbGhost十年了,它从未让我失望。他们提供的支持是首屈一指的。 - penderi

1

我使用一个简单的VBScript文件,基于this codeproject article来生成所有数据库对象的drop/create脚本。然后将这些脚本放入版本控制中。

因此,为了检查数据库是否是最新的或者有未被放入版本控制的更改,我会执行以下步骤:

  • 从版本控制(我们使用的是subversion)获取drop/create脚本的最新版本
  • 对要检查的数据库执行SqlExtract脚本,覆盖版本控制中的脚本
  • 现在我可以使用我的subversion客户端(TortoiseSVN)检查哪些文件与版本控制下的版本不匹配
  • 现在要么更新数据库,要么将修改后的脚本放入版本控制中

1

你必须限制对所有数据库的访问,并仅向开发人员提供本地数据库(用于开发)和开发服务器的访问权限,以进行集成。最好的方法是让他们只能在本地访问其开发区域,并使用自动构建执行集成任务。您可以使用像Redgates SQL Compare这样的工具来对数据库进行差异比较。我建议您将所有更改保存在源代码控制下(.sql文件),以便您拥有运行历史记录,了解谁在何时做了什么,并在需要时还原数据库更改。

我还喜欢能够让开发人员运行本地构建脚本以重新启动其本地开发环境。这样,他们就可以随时回滚。更重要的是,他们可以创建集成测试,以自动化方式测试应用程序中的管道(存储库和数据访问)和存储过程中隐藏的逻辑。初始化运行(重置数据库),运行集成测试(在数据库中创建虚拟数据),重新初始化以将数据库恢复到干净状态等。

如果您是一个使用单分支概念的SVN/nant风格用户(或类似的用户),并且在您的存储库中,则可以在DotNetSlackers上阅读我关于此主题的文章:http://dotnetslackers.com/articles/aspnet/Building-a-StackOverflow-inspired-Knowledge-Exchange-Build-automation-with-NAnt.aspxhttp://dotnetslackers.com/articles/aspnet/Building-a-StackOverflow-inspired-Knowledge-Exchange-Continuous-integration-with-CruiseControl-NET.aspx
如果您是一个perforce多分支类型的构建管理员,那么您将不得不等待我写一些关于这种自动化和配置管理的内容。
更新:
@Sazug:“是的,在我们使用基本脚本+其他脚本时,我们使用某种形式的多分支构建:)没有完整文章的任何基本提示?”最常见的两种数据库有:
  • 你在一个新的非生产类型环境中控制数据库(仅限活动开发)
  • 一个生产环境,在你开发过程中积累实时数据
第一次设置要容易得多,可以从开发到生产完全自动化,并包括回滚生产(如果需要)。为此,您只需要一个脚本文件夹,在其中每个对数据库的修改都可以在一个 .sql 文件中进行维护。我建议您不要像处理 .cs 文件一样保留 tablename.sql 文件并对其进行版本控制,因为这些 SQL 对象彼此之间有很强的依赖关系。当您从头开始构建数据库时,您的脚本可能会遇到破坏性变更。出于这个原因,我建议您为每个修改保留一个单独的新文件,并在文件名前面添加一个序列号。例如,类似于 000024-ModifiedAccountsTable.sql 的东西。然后,您可以使用自定义任务或来自 NAntContrib 中的某些东西,或者直接执行许多 ??SQL.exe 命令行工具之一,以从 000001-filename.sql 到 updateScripts 文件夹中的最后一个文件运行所有脚本。所有这些脚本都将被检入您的版本控制中。由于您始终从干净的数据库开始,因此如果某个人的新 sql 破坏了构建过程,您可以始终回滚。
在第二个环境中,自动化并不总是最佳选择,因为可能会影响生产。如果您正在针对/为生产环境积极开发,则真正需要一个多分支/环境,以便您可以在实际推送到生产环境之前测试您的自动化。您可以使用与上述相同的概念,但是您不能从头开始对prod db进行回滚更加困难。因此,我建议在构建过程中使用RedGate SQL Compare或类似工具。.sql脚本用于更新目的,但在运行更新之前,需要自动化在暂存db和prod db之间进行差异。然后,您可以尝试同步更改,并且如果出现问题,则回滚prod。在自动推送sql更改之前,还应该进行某种形式的备份。在生产中进行任何没有警觉的人眼的操作时要小心!如果您在所有dev/qual/staging/performance环境中都进行真正的持续集成,然后在推送到生产时有一些手动步骤...那其实也不太糟糕!

限制访问是关键,这是解决问题的关键。其他的都只是细节。 - rmeador
是的,当我们使用基础脚本和附加脚本时,我们使用某种多分支构建 :) 对于这种自动化,有没有基本提示而不需要完整文章? - Sazug

0

我必须同意帖子的其余部分。在生产环境中,数据库访问限制将解决此问题。然后使用像DBGhost或DVC这样的版本控制工具将帮助您和团队维护数据库版本控制。


0

第一点:没有“规则”,很难保持事物的秩序。 例如,开发人员在没有通知的情况下更改任何内容将会给您带来严重的问题。

无论如何 - 您说“不使用触发器”。 有什么具体原因吗?

如果没有 - 请查看DDL触发器。这些触发器是检查是否发生了某些事情的最简单方法。

而且,您甚至可以记录正在发生的事情。


0
希望有人能提供比这更好的解决方案,但我使用了几种方法:
  • 拥有一个“主干”数据库,即当前的开发版本。所有工作都在此处完成,因为它正在准备包含在发布中。
  • 每次发布时:
    • 将上一个版本的“干净”数据库复制到新版本中,例如,“DB_1.0.4_clean”
    • SQL-Compare用于将更改从主干复制到1.0.4_clean - 这也允许检查确切包含了什么。
    • 再次使用SQL Compare查找前一个和新版本之间的差异(从DB_1.0.4_clean到DB_1.0.3_clean的更改),从而创建一个变更脚本“1.0.3 to 1.0.4.sql”。

我们仍在构建自动化此部分的工具,但目标是有一个表来跟踪数据库已经到达的每个版本,以及是否应用了变更脚本。升级工具查找最新条目,然后逐个应用每个升级脚本,最终数据库就更新到了最新版本。

我没有这个问题,但是保护_clean数据库免受其他团队成员修改是微不足道的。此外,因为我在事后使用SQL Compare生成更改脚本,所以开发人员无需跟踪它们。

  • 我们实际上做了一段时间,但是非常麻烦。很容易忘记,同时也会进行一些不必要的更改-因此使用单独创建的更改脚本创建的完整升级脚本有时会添加一个字段,然后将其删除,所有这些都在一个版本中。如果有索引更改等,这显然会非常痛苦。

SQL Compare的好处在于它生成的脚本是在事务中的-如果失败,它会回滚整个过程。因此,如果生产DB以某种方式被修改,则升级将失败,然后部署团队实际上可以使用SQL Compare对_production DB进行比较,并手动修复更改。我们只需要做一两次(该死的客户)。

.SQL更改脚本(由SQL Compare生成)存储在我们的版本控制系统(subversion)中。


0
如果你有 Visual Studio(特别是数据库版本),可以创建一个 Database Project 并指向 SQL Server 数据库。该项目将加载模式并基本提供许多其他功能,它的行为就像代码项目一样。 它还提供了一个优势,可以编写整个表和内容的脚本,以便在 Subversion 下保存。构建项目时,会验证数据库的完整性。 它非常智能。

0
在我们的一个项目中,我们将数据库版本存储在数据库内部。
每次对数据库结构的更改都会编写成单独的SQL文件,并且除了所有其他更改之外,还会增加数据库版本。这是由更改数据库结构的开发人员完成的。
部署脚本会检查当前数据库版本和最新更改脚本,并在必要时应用这些SQL脚本。

0
首先,您的生产数据库应该不可访问给开发人员,或者开发人员(以及其他所有人)应该严格遵守在变更控制系统之外不对生产系统进行任何形式的更改的指示。
在任何您希望正常工作的系统中,变更控制都是至关重要的(当整个系统涉及到超过1个工程师时)。
每个开发人员都应该拥有自己的测试系统;如果他们想对其进行更改,可以这样做,但系统测试应该在一个更受控制的系统测试系统上进行,该系统已应用与生产相同的更改 - 如果您不这样做,就无法依赖发布工作,因为它们在不兼容的环境中进行测试。
进行更改时,应创建并测试适当的脚本,以确保它们可以在当前版本之上干净地应用,并且回滚操作有效*。
*您正在编写回滚脚本,对吧?

我们正在采用一种新的流程,开发人员将无法访问生产数据库,但是很难展示在测试版本中开发然后升级到线上版本的好处,因为它不能自动完成。当然,在线上版本中开发要容易得多,但不够安全。回滚脚本仅适用于模式更改,而不适用于“元数据”更改?不,还没有回滚脚本... - Sazug
回滚脚本应适用于任何更改。如果需要将回滚脚本打包为shell脚本或小程序,则可以这样做。顺便说一句,最好尝试使数据库模式更改“向后兼容”,以便您可以升级数据库并保留旧的应用程序服务器,然后再升级它们。否则,您将面临多步部署和大量繁琐的测试。 - MarkR

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接