2012-04-17 59 views
15

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

  1. 能够存储和方便地检索数据库的版本号。
  2. 被客户隐藏或更难找到和操纵。
  3. 能够在我们创建新版本时进行编辑/更改。
  4. 备份数据库或删除数据库将保留用于取证的版本#。

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

任何想法或最佳实践?

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

+1

为什么你会在意,如果客户端可以访问的领域?如果他们直接编辑它,是不是只会弄乱应用程序,然后这将是他们自己的错误? – mellamokb 2012-04-17 18:32:02

+0

@mellamokb - 伟大的标注,但我们需要这特别是因为在现场人们正在做的是:与数据库搞混。我们希望这是用于法医调查,因此隐藏它(例如在SQL元数据中)只会降低更改的可能性。 – pearcewg 2013-01-31 21:46:07

+2

@pearcewg如果你想取证,那么你步入安全领域,然后你就错过与你的需求点。你不应该试图保护那些拥有它的人的数据库 - 这就是所谓的“过度保护设计”。如果你觉得真的很深,你会发现绝对没有办法让你知道一个有SA密码的人是否搞乱了数据库。这就是整个问题。让解决方案“更难以找到和操纵”只会让你在没有时感到受到保护。 – 2013-05-14 12:30:57

回答

17

我是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比较,它执行检查,以确保它声称的版本是对应于版本存储在源代码控制。

希望这会有所帮助!

+0

大卫:这是一个很好的答案,基本上是我想为更多的研究后的解决方案。谢谢! – pearcewg 2012-04-18 12:59:58

+0

没问题。很高兴帮助!当然,这并不妨碍客户端对数据库进行更改,这会使其与您标记的版本号不一致。这被称为数据库漂移,是一个相当普遍的问题。 – 2012-04-18 19:37:09

5

实际上,我们只存储每个数据库的架构编号。我们在数据库中有一张表格,仅供软件配置管理团队使用,该表格告诉我们当前的版本,以便我们可以快速地查看各种环境的版本。我不会担心把它放在db之外的地方,因为这只会让事情变得复杂。

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

1

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

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

5

,我实现了基于跟踪四段架构版本(主要,次要,建立,修订版)与时间戳时,每一个版本的开头和结尾的有效性一个表中的解决方案。只有一行具有用于结束时间戳的NULL,并且这是当前版本。

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

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

还有一个(选配)招 - 我用奇怪的版本号为中间版本,甚至搭建完成的版本号。这样,一旦开始更改,它会首先将内部版本号更改为下一个奇数值,然后执行所需内容。如果在任何时候你看到一个奇怪的版本号(版本号中的第三段),那么你肯定有一些修改没有完成!一旦修改完成了最后一步,它只需再次更改模式版本,这次是下一个偶数内部版本号,只是为了通知大家它已完成。

您可以查看整个源代码,用户手册和例子在这篇文章中:How to Maintain SQL Server Database Schema Version

+0

我喜欢使用奇数来表示正在进行数据库升级的想法。 – 2015-04-01 23:33:34