数据库变更管理 - 初始创建脚本设置,后续迁移脚本

6
我有一个数据库变更管理工作流程。它基于SQL脚本(因此,不是基于托管代码的解决方案)。
基本设置如下:
Initial/
    Generate Initial Schema.sql
    Generate Initial Required Data.sql
    Generate Initial Test Data.sql
Migration
     0001_MigrationScriptForChangeOne.sql
     0002_MigrationScriptForChangeTwo.sql
     ...

“启动数据库的过程是先运行所有初始化脚本,然后运行连续的迁移脚本。一个工具会处理版本需求等事项。”
“我的问题是,在这种设置中,是否也要维护这个?”
Current/
    Stored Procedures/
        dbo.MyStoredProcedureCreateScript.sql
        ...
    Tables/
        dbo.MyTableCreateScript.sql
        ...
    ...

“这”指的是一个脚本目录(按对象类型分隔),表示旋转当前/最新版本数据库的创建脚本。
出于某种原因,我非常喜欢这个想法,但我无法具体证明它的必要性。我错过了什么吗?
优点包括:
- 对于开发和源控制,我们将拥有与我们习惯的每个文件一个对象相同的设置 - 对于部署,我们可以通过运行Initial+Migrate或从Current/运行脚本来将新的DB实例旋转到最新版本 - 对于开发,我们不需要运行DB实例才能进行开发。我们可以在Current/文件夹上进行“离线”开发。
缺点包括:
- 对于每个更改,我们需要更新Current/文件夹中的脚本,并创建Migration/文件夹中的迁移脚本
谢谢您提前的任何建议!

如果有关系的话,我正在使用Red Gate工具堆栈(SQL Compare Pro等),尽管我认为上述描述的过程是与工具无关的。 - Martin Suchanek
这可能应该是一个社区wiki。 - Jim Counts
如果您已经在使用Red Gate工具,您可能会对SQL Source Control感兴趣,它可以作为早期访问版本进行尝试。请参见http://www.red-gate.com/Products/SQL_Source_Control/index.htm 我很乐意进一步讨论您的需求,并确定SQL Source Control是否可以有效地为您工作。您可以通过电子邮件与我联系(我是产品经理),我的邮箱是David.Atkinson@red-gate.com,我们可以进一步讨论此事。 - David Atkinson
它已经退出早期访问阶段,SQL Source Control 1.0现已发货!http://www.red-gate.com/products/SQL_Source_Control/index.htm - David Atkinson
3个回答

6
实际上,这是最好的方法。尽管听起来有些麻烦,但它比使用 SQL Compare 工具或 VSDB .schema 文件部署等替代方案要好得多。我已经争论了很长时间,支持完全相同的方法:版本控制和您的数据库。我的应用程序从初始脚本部署 v1 模式,然后为每个版本运行升级脚本。每个脚本都知道如何从版本 N-1 升级到版本 N,仅限于此。最终结果是当前版本。
最大的缺点是缺少权威的 .sql 文件,无法查找任何对象(过程、表、视图等)的当前版本。但是能够在任何先前版本上部署应用程序以及通过经过良好控制和测试的脚本部署的优势远远超过了缺点。
如果你因为使用这种部署流程(脚本部署v1,然后应用v1.1,然后v1.2...直到最后应用v4.5,当前版本)而感到不好,那么请记住:SQL Server 内部使用完全相同的过程在版本之间升级数据库。当你附加一个旧的数据库时,你会看到著名的“数据库正在从版本 611 升级到 612”,并且你会看到升级一步一步进行,不会直接升级到当前版本 651(或者在您的情况下是当前版本)。也不会运行差异工具以部署 v. 611 上的 v 651。这是因为最好的方法就是您所使用的方法,一次升级一步。
为了回答你的问题,我想说,发布当前版本的脚本化版本是有价值的,但我认为它应该是连续集成构建过程中的可交付成果。换句话说,你的构建服务器应该构建当前数据库(使用升级脚本),然后作为构建步骤,脚本输出数据库并生成当前版本模式脚本的构建版本。但是,这些只应用于搜索和代码检查的参考,而不是部署可交付成果,我的意见。

我对这种方法很感兴趣。我想象随着时间的推移,这个脚本的运行时间会大大增加。你最终是否会将早期的更改“卷起来”并合并到初始创建脚本中以解决这个问题? - Dolbz
@Dolbz:是的,但要记住,汇总意味着您会破坏某些升级路径的支持。例如,您的应用程序已达到v.5.0,并且您拥有从1.0、1.1、1.2、2.0、2.1等版本进行升级的脚本。您将它们汇总到v4.0,然后您就不能再升级之前的版本了。解决方法是保留旧的脚本作为升级的替代方案,或者如果您确定没有部署早于4.0版本的情况,则弃用该支持。 - Remus Rusanu
是的,说得很对。但是当然,在合并脚本之后,如果绝对需要,你仍然可以从源代码管理系统中获取到原始未合并的脚本。 - Dolbz

1

我认为从长远来看,这只会使事情变得更加复杂。 整个版本需要存在于单个脚本中,以便您可以在一个上下文中测试该脚本并确保在另一个上下文(如生产环境)中正常工作。


好的观点。这是另一件可能会出问题或至少需要测试的事情。就单个脚本而言,有一些工具可以将脚本文件夹生成一个(单个文件)迁移脚本(到任何目标),所以这一点是无关紧要的,尽管正如你所说,在那个时候不会进行测试。另一方面,在迁移过程中我们从未在生产环境中进行初始创建... - Martin Suchanek
你是说对你来说,Initial Create和Upgrade是平行的路径吗? - MaxGuernseyIII

0

Martin,

如果你在现实世界中,那么你的生产数据库只接受更新 - 你从来不会从头开始“创建”它。因此,对于你存储、观察、审查等最重要的事情是一组更新脚本。这些脚本将进入生产环境,因此这些才是真正重要的。

你正在做正确的事情,把它们作为主要内容。但开发人员需要能够获得“当前状态”的模式信息。DBA也喜欢这样做,尽管(太)频繁地通过登录到生产服务器并启动某种GUI工具来完成。(哎呀!)

我对你的方法唯一的保留是按对象类型分类的当前/上一个模式。这些脚本应该自动生成,从数据库本身转储而来。如果你可以按类型自动分类,那就太好了!如果不能,请尽力使它们易于导航,但指导原则始终应该是“从活动数据库自动生成”。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接