我正在使用SQL-Server 2008和Visual Studio Database Edition。
通过此设置,保持架构同步非常简单。基本上,有一个“比较模式”工具,允许我将两个数据库和/或数据库模式的模式与源控制的创建脚本文件夹同步。
然而,就数据而言,情况不太清楚,数据可能有三种不同:
代码中引用的静态数据。典型示例:我的用户可以更改其设置,并将其配置存储在服务器上。但是,如果用户没有覆盖它,则每个设置都有一个系统范围的默认值。包含这些默认设置的表随着向程序添加更多选项而增长。这意味着当签入新功能/选项时,通常也会在数据库中创建系统范围的默认设置。
静态数据。例如。填充下拉列表的产品列表。该程序不依赖列表中特定产品的存在来工作。例如,这可以是在部署程序的新“unicode版本”时应在生产中部署的unicode编码产品列表。
其他数据,即其他所有内容(日志,用户帐户,用户数据等)
我觉得我的第三项不应该是源控制的(当然,它应该定期备份)
但是关于静态数据,我想知道该怎么做。
我应该将插入脚本附加到创建脚本吗?或者可以使用单独的脚本?
我(作为开发人员)如何警告执行部署的人员应该执行插入语句?
我应该区分我的两种数据吗? (第一个通常由开发人员创建,而第二个通常由非开发人员创建)
如何管理数据库静态数据?
答案 0 :(得分:7)
我已经解释了我在博客Version Control and Your Database中使用的技术。我使用数据库元数据(在本例中为SQL Server扩展属性)来存储已部署的应用程序版本。我只有从版本升级到版本的脚本。在启动时,应用程序从数据库元数据中读取已部署的版本(缺少元数据被解释为版本0,即尚未部署任何内容)。对于每个版本,都有一个应用程序功能,可以升级到下一个版本。通常,此函数运行执行升级的内部资源T-SQL脚本,但它可能是其他内容,例如在数据库中部署CLR程序集。
没有用于部署“当前”数据库架构的脚本。新版本将从版本1到当前版本的所有中间版本进行迭代。
我喜欢这种技术有几个优点:
这种方法多次拯救了我的皮肤,现在我是一个真正的信徒。只有一个缺点:在源代码中没有明显的地方可以找到“foo的当前形式是什么?”。因为最新版本的foo可能已经升级了2或3个版本并且之后没有更改,所以我需要查看那个版本的升级脚本。我通常只是查看数据库并查看其中的内容,而不是搜索升级脚本。
最后一点:这实际上不是我的发明。这完全取决于SQL Server自身如何升级数据库元数据(mssqlsystemresource)。
答案 1 :(得分:2)
如果要更改静态数据(将新项添加到用于生成下拉列表的表),则插入应位于源代码管理中,并与其余代码一起部署。如果其他代码需要插入工作,则尤其如此。否则,在部署代码时可能会忘记此步骤,而不会发生这么好的事情。
如果静态数据来自其他来源(例如在美国导入当前的机场代码),那么您可能只需要运行已经记录的导入过程。导入过程本身应该在源代码控制中(我们使用所有SSIS包执行此操作),但数据不必是。
答案 2 :(得分:2)
在Red Gate,我们最近在SQL Data Compare中添加了一项功能,允许将静态数据存储为DML(每个表一个.sql文件)以及SQL Compare当前支持的架构DDL。
了解其工作原理,here is a diagram解释其工作原理。
我们的想法是,当您想要将更改推送到目标服务器时,可以使用脚本作为源数据源进行比较,从而生成必要的DML同步脚本以更新目标。这意味着您不必假设每次都从头开始重新创建目标。我们希望在即将到来的SQL Source Control tool中支持静态数据。
Red Gate Software产品经理David Atkinson
答案 3 :(得分:1)
我非常喜欢你对三种数据的区分。
我同意第三。
在我们的应用程序中,我们尽量避免在数据库中放入第一个,因为它是重复的(因为它必须在代码中,数据库是重复的)。第二个好处是我们不需要连接或查询来从代码中访问该值,因此这会加快速度。
如果我们希望在数据库中有其他信息,例如,如果可以按客户站点更改,我们将两者分开。其他表仍然可以引用该数据(通过索引ex:0,1,2,3或代码ex:EMPTY,SIMPLE,DOUBLE,ALL)。
对于 second ,脚本应该在源代码控制中。我们将它们与结构分开(我认为它们通常会随着时间的推移而被替换,而结构会不断添加增量)。
我(作为开发人员)如何警告执行部署的人员应该执行插入语句?
我们有一个完整的程序,每个版本附带自述文件,脚本等等......
答案 4 :(得分:1)
我在开发CMS系统时遇到过这种情况。
我将静态数据(代码中引用的内容)附加到数据库创建脚本,然后添加一个单独的脚本以添加任何“初始化数据”(如国家,初始产品群等)。
答案 5 :(得分:1)
对于前两个步骤,您可以考虑对数据使用中间格式(即XML),然后使用自行开发的工具或CodeSmith之类的东西来生成SQL,以及可能的源文件,如果(对于例如,您有与代码中使用的枚举相关的查找表 - 这有助于实现一致性。
这有另一个好处,如果架构发生更改,在许多情况下您不必重新生成所有INSERT语句 - 只需更改工具即可。
答案 6 :(得分:1)
见this thread's answer。前两点的静态数据应该在源代码管理中,恕我直言。
编辑:*新
[Logins, Roles, Users; Tables; Views; Stored Procedures; UDFs; Static Data; (Audit Tables, Audit Triggers)]
答案 7 :(得分:1)
首先,我从未使用过Visual Studio Database Edition。使用此实用程序为您提供的任何工具,您都是幸运的(或被诅咒)。希望这包括很多灵活性。
我不知道我会在你的1型和2型静态数据之间做出很大的改变。两者都是定义一次然后永不更新的数据集,除非后续版本和更新,对吧?在这种情况下,主要区别在于数据是如何或为何原样,而不是如何存储或初始化数据。 (除非数据是特定于环境的,如用于开发的“A”,用于生产的“B”。这将是“类型4”数据,我将在这篇文章中高兴地忽略它,因为我已经使用SQLCMD解决了它变量,他们让我头疼。)
首先,我将创建一个脚本来创建数据库中的所有表 - 最好只有一个脚本,否则你可以有很多脚本(当重命名列时查找和替换变得非常笨拙)。然后,我会创建一个脚本来填充这些表中的静态数据。此脚本可以附加到表脚本的末尾,或者使其成为自己的脚本,甚至可以为每个表创建一个脚本,如果要加载数百或数千行,这是一个好主意。 (有些人制作一个csv文件,然后发出一个BULK INSERT,但我会避免这只是给你两个文件和一个复杂的过程[在部署时配置驱动器映射]来管理。)
要记住的关键是数据(存储在数据库中)可以并且会随着时间而改变。很少(如果有的话)你会很幸运地删除你的生产数据库,并用一个新的,有光泽的新数据库替换它,没有过去十年来所有那些狡猾的数据。数据库都是关于随时间的变化,而这正是脚本自成一体的地方。您可以从脚本开始创建数据库,然后随着时间的推移添加修改数据库的脚本 - 这也适用于您的静态数据(任何类型)。
(最终,我的方法类似于会计:你有账户,随着变化的到来你用日记账分录调整账户。如果你发现你犯了错误,你再也不会回去修改你的参赛作品,你只需要后续条目可以反转并修复它们。这只是一个类比,但逻辑是合理的。)
答案 8 :(得分:1)
我使用的解决方案是在源代码管理中创建和更改脚本,以及存储在数据库中的版本信息。
然后,我有一个安装向导,可以检测是否需要创建或更新数据库 - 通过根据数据库中存储的版本信息选择适当的脚本来管理更新过程。