在SQL Server中存储数据库架构版本的最佳实践?

时间:2012-04-17 18:29:54

标签: sql-server database-schema

我有一个应用程序将部署在带有SQL Server的生产PC上。 我希望能够在我的数据库中存储和检索模式的版本。 我对能够实现这一目标的最佳实践感兴趣,主要有以下目标:

  1. 能够存储并轻松检索数据库的版本号。
  2. 隐藏或更难以被客户查找和操纵。
  3. 创建新版本时可以进行编辑/更改。
  4. 备份数据库或删除数据库会保留版本#for forensics。
  5. 我希望有一种方法可以在元数据中存储“版本”,而不是普通表,可以通过系统存储过程访问/设置。

    任何想法或最佳做法?

    编辑:我发现可能有希望的一个选项是使用SQL Server扩展属性,将带有“Schema_Version”的数据库的值赋值给版本号。它没有加密(但值可能是),并且没有隐藏,但至少从我们的一些用户和现场人员浏览的实际数据库结构中删除(令我沮丧!:))

4 个答案:

答案 0 :(得分:20)

我是Red Gate的SQL Source Control和SQL Compare的产品经理。我们必须解决这个同样的问题,因为我们的工具需要知道数据库所处的版本,以便选择适当的迁移脚本来构建完整的部署脚本。

我们考虑了一个版本表,这是最常设计的本土解决方案。但是,根据我们的研究,我们了解到用户希望保持数据库对象集“未受污染”,因此我们选择了数据库级扩展属性。我们将其附加到脚本中,如下所示:

IF EXISTS (SELECT 1 FROM fn_listextendedproperty(N'SQLSourceControl Database Revision', NULL, NULL, NULL, NULL, NULL, NULL))
  EXEC sp_dropextendedproperty N'SQLSourceControl Database Revision', NULL, NULL, NULL, NULL, NULL, NULL
EXEC sp_addextendedproperty N'SQLSourceControl Database Revision', @RG_SC_VERSION, NULL, NULL, NULL, NULL, NULL, NULL

当数据库加载到SQL Compare时,它会执行检查以确保它声称的版本与源代码管理中存储的版本相对应。

希望这有帮助!

答案 1 :(得分:5)

说实话,我们只存储每个数据库的模式编号。我们在数据库中有一个表,它仅由软件配置管理团队使用,该团队告诉我们当前版本,以便我们可以快速查看哪个版本所在的环境。我不担心把它放在数据库之外的某个地方,因为这只会让事情复杂化。

我想如果你真的想要保证安全,你总是可以创建一个存储过程,其中包含硬编码的值。然后,您可以加密存储过程,以便他们无法在您不知情的情况下查看/篡改它。您可以在更改sp的版本时更新sp。您也可以进入系统并在编译后从系统表中删除存储过程代码,但我真的不会这样做。它只会导致问题。

答案 2 :(得分:5)

我已经实现了一个基于一个表的解决方案,该表跟踪每个版本开始和结束其有效性时带有时间戳的四段模式版本(主要版本,次要版本,构建版本,修订版本)。只有一行有NULL表示结束时间戳,那是当前版本。

此外,还有一堆支持此版本控制系统的存储过程,并且所有数据库更改必须使用这些过程在对数据库模式进行任何更改时立即测试和更新模式版本(例如,添加表,删除列等。)。

请注意,更改的完整历史记录存储在跟踪数据库版本的表中。当出现任何问题时,解决方案非常灵活。例如,如果alter在执行过程中断,则在版本表中会记住它已成功完成的所有更改,因为在每个步骤之后它都会增加修订号。您可以改进更改并再次运行它,它将自动跳过成功完成的步骤,并从上次没有进行的第一步继续。

还有一个(可选的)技巧 - 我为中间版本使用了奇数内部版本号,甚至为已完成的版本构建了数字。这样,一旦alter开始,它首先将内部版本号更改为下一个奇数值,然后执行它想要的内容。如果您在任何时候看到一个奇怪的内部版本号(版本号中的第三个段),那么您确定某些更改未完成!一旦alter完成了它的最后一步,它只是再次更改模式版本,这次更改为下一个偶数版本号,只是为了通知每个人它已经完成。

您可以在本文中查看完整的源代码,手册和示例:How to Maintain SQL Server Database Schema Version

答案 3 :(得分:1)

我在之前的公司所做的是将版本存储在一个包含几个字段(主要版本,次要版本,构建和日期)的表中,以便我可以获得更新的历史记录。在表上设置适当的权限足以防止篡改。

如果您真的想让DBA难以阅读,您可以将这些值作为加密字符串存储在表中。这种方式现在只有你如何解码它们。