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

时间:2009-10-07 22:22:57

标签: sql-server database version-control verify

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

例如,我有一个名为“Version”的数据库(版本号存储在那里)。但是开发人员可以在不更改版本号的情况下访问和编辑数据库。例如,如果开发人员更新存储过程但未更新版本数据库状态与版本值不同步。

如何跟踪这些变化?我不需要跟踪更改的内容,只需要检查数据库表,视图,过程等是否与Version表中保存的数据库版本同步。

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

假设我们使用的是SQL Server 2005。

编辑:

我想我应该提供有关当前环境的更多信息 - 我们有一个“基线”,其中包含创建基本版本所需的所有脚本(包括我们应用的数据对象和“元数据”)。但是,这个“基础”版本有许多安装,带有一些额外的数据库对象(附加表,视图,过程等)。当我们对“基础”版本进行一些更改时,我们还必须更新一些安装(不是全部) - 那时我们必须检查“基础”是否处于正确状态。

由于

11 个答案:

答案 0 :(得分:6)

你好像打破了“Three rules for database work”的第一和第二条规则。每个开发人员使用一个数据库,并为您的模式使用单个权威来源已经有很大帮助。然后,我不确定您的数据库是Baseline,更重要的是,您使用的是change scripts。最后,您可以在Views, Stored Procedures and the LikeBranching and Merging中找到其他一些答案。

实际上,Jeff Atwood在这篇伟大的文章中提到了所有这些链接:Get Your Database Under Version Control。必须阅读恕我直言。

答案 1 :(得分:5)

我们使用DBGhost来控制数据库的版本。创建当前数据库的脚本存储在TFS中(与源代码一起),然后DBGhost用于生成增量脚本以将环境升级到当前版本。 DBGhost还可以为任何静态/引用/代码数据创建增量脚本。

它需要从传统方法转变思维,但这是一个很好的解决方案,我不能推荐。虽然它是第三方产品,但它可以无缝地融入我们的自动构建和部署过程。

答案 2 :(得分:1)

我正在使用基于this codeproject article的简单VBScript文件为所有数据库对象生成删除/创建脚本。然后我将这些脚本置于版本控制之下。

因此,为了检查数据库是否是最新的还是尚未进入版本控制的更改,我这样做:

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

答案 3 :(得分:1)

您必须限制对所有数据库的访问权限,并且只允许开发人员访问本地数据库(他们开发的地方)以及可以进行集成的开发服务器。最好的办法是让他们只能在本地访问他们的开发区域并使用自动构建执行集成任务。你可以使用像redgates sql compare这样的工具来做数据库上的差异。我建议您将所有更改保存在源代码管理(.sql文件)下,这样您就可以了解谁在什么时候执行了什么操作的历史记录,以便您可以在需要时还原数据库更改。

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

如果您是存储库中具有单个分支概念的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。< / p>

如果你是一个perforce多分支类型的构建主机,那么你将不得不等到我写一些关于那种自动化和配置管理的内容。

<强>更新

@Sazug:“是的,当我们使用基本脚本+附加脚本时,我们使用某种多分支构建:)没有完整文章的那种自动化的任何基本技巧?”最常见的有两种形式的数据库:

  • 您在新的非生产类型环境(仅限活动开发人员)中控制数据库
  • 在您开发时积累实时数据的生产环境

第一个设置更容易,可以从开发到生产完全自动化,并在需要时包括回滚产品。为此,您只需要一个脚本文件夹,您可以在.sql文件中维护对数据库的每个修改。我不建议您保留一个tablename.sql文件,然后将其版本化为.cs文件,其中该sql工件的更新实际上会随着时间的推移在同一文件中进行修改。鉴于sql对象非常依赖于彼此。从头开始构建数据库时,脚本可能会遇到重大更改。出于这个原因,我建议您为每个修改保留一个单独的新文件,并在文件名的前面加上序列号。例如000024-ModifiedAccountsTable.sql之类的东西。然后,您可以使用自定义任务或NAntContrib之外的任务或直接执行多个SQL.exe命令行工具之一来针对从000001-fileName.sql到最后一个文件的空数据库运行所有脚本在updateScripts文件夹中。然后将所有这些脚本签入到您的版本控制中。而且,因为你总是从一个干净的数据库开始,所以如果某个新的sql破坏了构建,你总是可以回滚。

在第二种环境中,自动化并不总是最佳途径,因为您可能会影响生产。如果您正在积极开发/生产环境,那么您确实需要一个多分支/环境,以便在实际推动生产环境之前测试自动化方式。您可以使用与上述相同的概念。但是,你不能真正从头开始使用prod db并且回滚更加困难。出于这个原因,我建议在构建过程中使用类似的RedGate SQL Compare。签入.sql脚本以进行更新,但您需要在运行更新之前自动执行staging db和prod db之间的差异。然后,如果出现问题,您可以尝试同步更改并回滚产品。此外,在自动推送sql更改之前,应采取某种形式的备份。在生产中没有注意人眼的情况下做任何事情都要小心!如果你在所有dev / qual / staging / performance环境中进行真正的持续集成,那么在推送到生产环境时会有一些手动步骤......这真的不是那么糟糕!

答案 4 :(得分:0)

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

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

如果不是 - 请查看DDL触发器。这种触发器是检查事情是否发生的最简单方法。

你甚至可以记录发生了什么。

答案 5 :(得分:0)

希望有人有比这更好的解决方案,但我使用几种方法来做到这一点:

  • 拥有一个“trunk”数据库,这是当前的开发版本。所有工作都在这里完成,因为它准备包含在发布中。
  • 每次发布​​完成后:
    • 最后一个版本的“干净”数据库被复制到新数据库,例如“DB_1.0.4_clean”
    • SQL-Compare用于将更改从trunk复制到1.0.4_clean - 这也允许检查确切包含的内容。
    • 再次使用SQL Compare查找先前版本和新版本之间的差异(从DB_1.0.4_clean更改为DB_1.0.3_clean),这会创建更改脚本“1.0.3到1.0.4.sql”。 / LI>

我们仍然在构建自动化这个部分的工具,但目标是有一个表来跟踪数据库所处的每个版本,以及是否应用了更改脚本。升级工具查找最新条目,然后逐个应用每个升级脚本,最后数据库为最新版本。

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

  • 我们实际上做了一段时间,这是一个巨大的痛苦。这很容易忘记,同时,还有一些变化没有完成 - 所以使用单独创建的更改脚本创建的完整升级脚本有时会添加一个字段,然后将其删除,全部在一个版本。如果有索引更改等,这显然会非常痛苦。

SQL比较的好处在于它生成的脚本在事务中 - 如果失败,它会将整个事情卷回来。因此,如果生产数据库已经以某种方式进行了修改,则升级将失败,然后部署团队实际上可以在生产数据库上对_clean数据库使用SQL Compare,并手动修复更改。我们只需要这样做一次或两次(该死的客户)。

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

答案 6 :(得分:0)

如果您有Visual Studio(特别是数据库版本),则可以创建Database Project并将其指向SQL Server数据库。该项目将加载架构,基本上为您提供了许多其他功能。它的行为就像一个代码项目。它还为您提供了编写整个表和内容脚本的优势,因此您可以将其保留在Subversion下。 构建项目时,它验证数据库是否具有完整性。这很聪明。

答案 7 :(得分:0)

在我们的一个项目中,我们将数据库版本存储在数据库中。

对数据库结构的每次更改都编写到单独的sql文件中,除了所有其他更改之外,还会增加数据库版本。这是由更改数据库结构的开发人员完成的。

根据当前的db版本和最新的更改脚本检查部署脚本,并在必要时应用这些sql脚本。

答案 8 :(得分:0)

首先,开发人员应该无法访问您的生产数据库,或者开发人员(以及其他所有人)应该遵守严格的指示,不得对变更控制系统之外的生产系统进行任何类型的更改。

在您期望工作的任何系统中,变更控制至关重要(整个系统中涉及> 1名工程师)。

每个开发人员都应该拥有自己的测试系统;如果他们想对其进行更改,他们可以,但系统测试应该在一个更受控制的系统测试系统上完成,该系统具有与生产相同的更改 - 如果你不这样做,你就不能依赖于版本因为他们在不兼容的环境中进行测试而工作。

进行更改时,应创建并测试相应的脚本,以确保它们在当前版本之上完全应用,并且回滚有效*

*你正在编写回滚脚本,对吗?

答案 9 :(得分:0)

我同意开发人员无权更改生产数据库的其他帖子。开发人员应该共享一个共同的开发数据库(并且冒险踩到彼此的脚趾),或者他们应该拥有自己的个人数据库。在前一种情况下,您可以使用SQL Compare等工具部署到生产环境。在后一种情况下,您需要在开发生命周期中定期同步开发人员数据库,然后再进行生产。

在Red Gate,我们将很快发布一个新工具SQL Source Control,旨在使这个过程变得更加容易。我们将集成到SSMS中,并通过单击按钮启用向源控件添加和检索对象。如果您有兴趣了解更多信息或注册我们的早期访问计划,请访问此页面:

http://www.red-gate.com/Products/SQL_Source_Control/index.htm

答案 10 :(得分:0)

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