23

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

  1. 能够存储和轻松检索数据库的版本号。
  2. 隐藏或更难被客户发现和操作。
  3. 当我们创建新版本时可以编辑/更改。
  4. 备份数据库或检测数据库会保留版本号以供取证。

我希望有一种方法可以在元数据中存储“版本”或不是普通表,可以通过系统存储过程访问/设置。

有什么想法或最佳实践吗?

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

4

4 回答 4

22

我是 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 中时,它会执行检查以确保它声称的版本与源代码控制中存储的版本相对应。

希望这可以帮助!

于 2012-04-17T21:04:48.437 回答
5

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

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

于 2012-04-17T18:32:50.823 回答
5

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

此外,还有一堆存储过程支持这个版本控制系统,所有的数据库变更一旦对数据库模式进行任何更改(例如添加表、删除列),都必须使用这些过程来测试和更新模式版本, ETC。)。

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

还有一个(可选的)技巧——我对中间版本使用了奇数的内部版本号,对已完成的版本使用了偶数的内部版本号。这样,一旦变更开始,它首先将内部版本号更改为下一个奇数值,然后做它想做的事情。如果您在任何时候看到一个奇怪的内部版本号(版本号中的第三部分),那么您确定某些更改没有完成!一旦 alter 完成最后一步,它会再次更改模式版本,这次更改为下一个偶数内部版本号,只是为了通知每个人它已经完成。

您可以在本文中查看完整的源代码、手册和示例:如何维护 SQL Server 数据库架构版本

于 2013-05-13T21:59:55.277 回答
1

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

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

于 2012-04-17T18:45:46.477 回答