2010-05-18 88 views
6

背景SQL Server数据库变更工作流程的最佳实践

我的小组有4个SQL Server数据库:

  • 生产
  • UAT
  • 测试
  • 开发

我在开发环境中工作。当需要推广我一直在研究的对象(表格,视图,函数,存储过程)时,我向我的经理提出了一个请求,他向促进测试。经过测试,她向向UAT推销的管理员提交请求。在成功进行用户测试后,同一管理员将推向生产。

的问题

整个过程是尴尬的几个原因。

  1. 每个人都必须手动跟踪他们的更改。如果我更新,添加,删除任何需要跟踪的对象,以便我的升级请求包含我所做的一切。从理论上讲,如果我错过了测试或UAT应该抓住它的地方,但这不是确定的,反正它浪费了测试者的时间。
  2. 我做的很多修改都是迭代的,并在GUI中完成,这意味着没有记录我所做的更改,只有最终结果(至少据我所知)。
  3. 我们正处于构建数据集市的初期阶段,因此大部分更改(至少按计数方式)都是次要的:更改列的数据类型,将表的名称更改为我们结晶就是他们将被用于,调整功能和存储的特效等

问题

人们一直在做这方面的几十年的工作,所以我想有得成为管理流程的更好方式。我会喜欢的是,如果我可以在两个数据库之间运行差异来查看结构如何不同,请使用该差异来生成更改脚本,并将该更改脚本用作我的促销请求。这可能吗?如果没有,是否有其他方法来组织这个过程?

为了记录,我们是100%的微软商店,刚刚将所有内容更新到SQL Server 2008,因此该软件包中提供的任何工具都是公平的游戏。


我应该说明我不一定在寻找diff工具。如果这是同步我们的环境的最佳方式,那么很好,但如果有更好的方式,我正在寻找。

一个我想做得很好的例子是Ruby on Rails中的迁移。死简单的语法,所有更改都会自动记录下来,默认情况下,确定迁移需要运行的几乎非常简单。如果对于SQL Server有类似的东西,我很乐意。

我的理想解决方案是1)容易和2)很难搞砸。 Rails迁移都是;到目前为止,我在SQL Server上所做的一切都不是。

回答

3

Version Control and your Database

万物罪恶的根源正在于用户界面的变化。 SSMS是一个DBA工具,而不是开发人员。开发人员必须使用脚本对数据库模型/架构进行任何类型的更改。对元数据进行版本控制并从每个版本N到版本N + 1的升级脚本仅有经证明可以可靠工作。这是SQL Server本身用来跟踪元数据更改(资源数据库更改)的解决方案。

来自VS数据库项目的SQL比较或vsdbcmd和.dbschema文件等比较工具对于未能采用适当版本化方法的商店来说只是最后的选择。他们在简单的情况下工作,但我发现他们都在严重部署中失败。一个只是没有对数据库信任的工具做了更改+ 5TB表,如果这些工具试图复制资料...

+0

使用脚本来更新数据库和人工跟踪更新脚本自己正是我试图避免的那种情况。 – kubi 2010-05-18 21:56:25

+1

你不'追踪'更新。您将数据库更新视为代码的改进和功能。您将脚本视为源代码树的一部分,并将它们视为源代码,然后将它们作为源代码进行版本控制检查,然后将其作为源代码进行检查等。与避免编写项目.cs文件相同。 – 2010-05-18 22:55:18

2

RedGate销售SQL Compare,这是一个很好的工具来生成更改脚本。

Visual Studio也有支持数据库比较的版本。这以前叫做Database Edition

我在哪里工作,很久以前我们废除了Dev/Test/UAT/Prod分离,转而使用very quick release cycle。如果我们把生产中的东西弄坏了,我们会很快修复它。我们的客户当然更快乐,但是冒险避免企业事业,这可能是一种艰难的销售。

2

有几种工具可供您使用。一个来自Red-Gate,名为SQL Compare。真棒,强烈推荐。 SQL Compare可以让你在两个数据库之间的模式中做一个diff,甚至为你建立sql更改脚本。

请注意,他们现在也一直在研究SQL Server源代码管理产品。

另一个(如果你是一个视觉工作室商店)是作为Visual Studio一部分的模式和数据比较功能(不知道哪些版本)。

+0

SQL源控制将在其测试阶段,直到6月底,我们希望在这一点上有最终版本。该版本目前可从我们的网站下载(我是Red Gate的产品经理)。 – 2010-05-18 23:42:12

+0

SQL源控制1.0已经正式发布,并可在http://www.red-gate.com/products/SQL_Source_Control/index.htm – 2010-06-30 12:25:20

3

在我们的团队,我们处理数据库的变化是这样的:

  • 我们(重新)生成一个脚本其中创建完整的数据库,并与其他更改检查到版本控制在一起。我们有4个文件:表格,用户定义的函数和视图,存储过程和权限。这是完全自动的 - 只需要双击即可生成脚本。
  • 如果开发人员必须对数据库进行更改,她会在她的本地db上进行更改。
  • 对于每一项更改,我们都会创建更新脚本。这些很容易创建:开发人员重新生成本地数据库的数据库脚本。由于版本控制,所有更改现在都很容易识别。大多数更改(新表,新视图等)可以简单地复制到更新脚本中,其他更改(例如添加列)需要手动创建。
  • 更新脚本在我们的通用开发数据库上被测试,或者通过回滚本地数据库到最后一次备份 - 这是在开始更改数据库之前创建的。如果它通过,是时候提交更改。
  • 更新脚本遵循命名约定,因此每个人都知道以何种顺序执行它们。

这对我们很好,但如果几个开发人员大量修改相同的表和视图,仍然需要一些协调。但这并不经常发生。

重要的要点是:

  • 数据库结构只是通过脚本修改,除了本地开发商的分贝。这个很重要。
  • SQL脚本由源代码控制版本 - 数据库可以创建,因为它是在过去
  • 数据库中的任何点备份创建定期 - 至少在更改数据库之前
  • 对数据库的更改可以快速完成 - 因为这些更改的脚本相对容易创建。

但是,如果您的项目有很多持久的开发分支机构,则可能无法正常工作。

这是迄今为止不是一个完美的解决方案,并采取一些特殊的预防措施。例如,如果存在可能因数据库中存在的数据而失败的更新,则应在生产数据库的副本上测试更新。

与rails迁移相反,我们不创建脚本来反转更新的更改。但是,至少在数据方面,这并不总是可能的(即使重新创建列,丢失列的内容也会丢失)。

+1

+1对*如何*为“使用脚本来更新数据库”的详细信息。 – 2014-05-07 11:21:20

+2

从VS 2012开始,查看集成并促进Visual Studio中更新和创建更新脚本的数据库项目。上述答案仍然适用。在这里找到一些有用的文章:http://arcanecode.com/tag/visual-studio-database-projects/ – marapet 2014-05-07 15:28:24

2

同意SQL比较是一个了不起的工具。

但是,我们不会对数据库结构或对象进行任何更改,这些数据库结构或对象不像其他代码那样脚本化并保存在源代码管理中。然后,您确切知道您正在推广的版本属于哪个版本,因为您拥有该特定版本的脚本。

无论如何,通过GUI进行结构更改是一个坏主意。如果你有大量的数据,它至少比在SQL Server中使用alter table慢得多。你只想使用测试脚本来更改prod。

1

我同意marapet提出的意见,每个变更都必须编写脚本。
但是,您可能遇到的问题是创建,测试和跟踪这些脚本。
查看DBSourceTools中使用的修补引擎。
http://dbsourcetools.codeplex.com

它专门设计用于帮助开发人员在源代码控制下获取SQL服务器数据库。

这个工具将允许你在特定点为你的数据库建立基线,并创建一个命名版本(v1)。
然后,创建一个部署目标 - 并将指定的版本增加到v2。
将修补程序脚本添加到Patches目录中,以更改模式或数据。
最后,检查数据库和所有补丁到源代码控制中,与开发人员分发。

这给你一个可重复的过程来测试从v1到v2应用的所有补丁。
DBSourceTools还具有帮助您创建这些脚本的功能,即模式比较或脚本数据工具。

完成后,只需将patches目录中的所有文件发送到DBA以从v1升级到v2即可。

玩得开心。在一个版本表

  • 记住这是脚本文件名

  • 0
    1. 保持数据库版本的成功应用
    2. 记住,已应用于每个SQL脚本的MD5校验和。计算md5总和时应忽略空格。必须有效。
    3. 保持对谁适用的脚本保存在施加脚本有关信息资讯
    4. 数据库应在应用程序进行验证的启动
    5. 新的SQL脚本应该自动
    6. 应用如果脚本的MD5和那已经应用被改变了,应该抛出错误(在生产模式下)
    7. 当脚本被释放时,它不能被改变。它必须是 在生产环境中不可变的。
    8. 脚本应该写的方式,因此它可以被应用到不同类型的数据库(见liquibase)
    9. 由于大多数DDL语句是自动提交在大多数数据库,最好是有每一个DDL语句SQL脚本。
    10. DDL sql语句应该以某种方式运行,因此可以多次执行而不会出错。当你可以多次编辑脚本时,真的有助于开发模式。例如,创建一个新表,只有在它不存在的情况下,或者甚至在创建新表之前创建一个表。它会帮助你处于开发模式,一个脚本没有被释放,改变它,清除这个脚本的md5总和,再次运行它。
    11. 每个sql脚本都应该在自己的事务中运行。
    12. 触发器/程序应该在每个db 更新后删除并创建。
    13. SQL脚本保存在一个版本控制系统,如SVN
    14. 脚本的名称包含在它承诺日期,现有的(JIRA)问题ID,小描述
    15. 避免在脚本中加入回滚功能(liquibase允许做那)。这使得他们写作和支持变得更加复杂。如果您使用的每个脚本只有一个DDL语句和DML语句一个 事务中运行,甚至没有一个脚本将不会是一个大麻烦 解决它