有什么有效的方法来处理代码分支之间共享的数据库模式?


12

在具有多个分支的项目上工作,其中每个分支最终都合并回主分支,并且本质上是隔离的,以便开发新功能。

该数据库(即MS SQL Server)具有共享的架构,但是每个分支都会随着进程的进行对架构进行更改。

我的主要询问是什么是处理从主分支到派生分支共享架构的好方法,这样对主分支所做的更改很容易合并到派生分支中,而无需在派生分支上进行新更改科?


2
只是合并应该像其他任何代码一样进行处理:自动合并,具有用户干预的回退,以及结果的检查/测试。(我更喜欢VS数据库项目处理每个文件一个对象的架构的方式。)在棘手位自带的现有数据库工作;-)如何向前迁移

2
这在很大程度上取决于您如何对架构进行版本控制。您是否要存储基础对象的创建脚本以及alter脚本?您是否正在使用架构比较工具来生成可在版本之间迁移的变更脚本?VS2010数据库项目?
Mark Storey-Smith


Answers:


7

我已成功使用以下方法,在版本控制和您的数据库中进行了详细说明:

  • 维护元数据中的版本号(我使用数据库扩展属性)
  • 任何模式更改都被编码为脚本,该脚本从当前版本更新到下一版本
  • 应用程序附带所有脚本,以从版本0(初始部署)一直升级到当前版本
  • 每个更改都是通过脚本完成的。包括“系统”数据更改,例如字典和查找表条目。
  • 部署后,该应用程序将检查磁盘上的架构版本,然后运行所有升级步骤以将该架构升级到当前所需的版本

我经常听到这样的观点:“与仅将对象定义脚本置于源代码控制之下有什么不同?”。差异是巨大的,因为当您部署新版本的应用程序时,您将不会简单地创建新数据库。大多数情况下,您的应用将必须升级现有数据库,包括现有数据。这是一个至关重要的区别,您的升级步骤需要确保升级期间现有数据的完整性和一致性。有些操作在代码上是微不足道的(向表对象定义脚本添加具有默认值的非空列,完成),但实际上它们在实际部署时非常痛苦(表有15亿行,add列将用完)如果以“简单”方式完成日志空间)。

分支如何工作:

  • 创建分支时,它将捕捉当前架构版本,例如版本1.6
  • 当团队开始在分支上工作时,它将添加新版本1.7,然后开始将升级步骤从1.6编码为1.7
  • 升级步骤随着分支中的修改而更改。它总是运行从v 1.6升级到1.7的脚本,但是这些脚本的确切功能取决于正常的代码迭代和分支中的签入。
  • 分支机构完成开发,为反向集成做准备(将其合并回基线)
    • 从基线到分支,它进行了新的前向集成。如果集成没有对架构版本进行任何更改,那么一切都很好,分支可以按原样反向集成。1.7版成为新的基准版本。
    • 有趣的是,与此同时另一个分支已反向集成到基础中,而现在基础架构版本已更改为1.7。在这种情况下,我们的分支机构必须将其部署目标架构版本提高到1.8,并检查以前从1.6升级到1.7的升级步骤,以查看其在新环境中的运行方式(从1.7升级到1.8)。逻辑架构冲突必须得到解决,脚本可能需要更改,测试必须完成。完成后,分支可以反向集成到基础中。现在,产品的已部署目标版本为1.8。
    • 当另一个以架构版本1.6分叉的分支想要反向集成时,它需要将其架构版本提高到1.9,测试从1.8到1.9的升级脚本,然后才能重新集成到基础中。

请注意,这里没有涉及任何工具,没有魔术模式差异脚本,没有向导,也没有右键单击-生成脚本。这是一个100%开发人员驱动的过程,基于源(脚本)。许多人发现整个过程很复杂,但确实可行。实际上,作为SQL Server用户,您已经在日常使用SQL Server时利用了此过程的结果:SQL Server本身使用非常相似的数据库升级过程,并且,正如您可能希望的那样,产品开发过程得到了广泛使用。分支和您提到的问题是一个非常实际的问题,必须解决。

顺便说一句,分支/集成的实际发生方式在源代码控制产品之间有所不同,我使用的是perforce 集成操作模式中熟悉的术语。


+1,尤其是对于每次更改都是通过脚本完成的
a_horse_with_no_name 2011年

1

尽管我的回答可能不如Remus'那么冗长,但我发现这是一个非常好的解决方案。我尚未在生产中设置它,所以YMMV *。

液基

本质上,这是一个XML文件,您可以在其中对数据库进行模式更改,作为XML文件中的新元素。例如:

<createTable tableName="department">
            <column name="id" type="int">
                <constraints primaryKey="true" nullable="false"/>
            </column>

它具有完善的语法,因此您几乎可以对数据库执行任何操作。

您还可以在Liquibase安装中指定要版本控制的数据库。然后,使用包含的Java可执行文件(jar文件)“运行” .xml。实质上,这将重新创建XML中对数据库指定的那些更改。

真正的好处是,您可以将此XML文件存储在与代码相同的版本文件夹中。所以在我的情况下就是Git。我在项目文件夹(与/.git相同的级别)中有此XML文件,然后每当切换分支时,XML文件都会更改为该分支版本,然后运行.jar文件,数据库现在将反映该分支。

*注意:由于我无法将Java连接到SQL Server,因此我尚未完成实现。需要一些jdbc驱动程序,而我当时并不在意。因此,您的里程可能会有所不同。


1

在Red Gate,我们即将发布一个利用SQL Compare和SQL Source Control的数据库版本控制解决方案。这使用迁移脚本升级方法,并使用与源代码管理修订版相对应的版本扩展属性标记数据库。

我们希望在12月中旬发布。现在有候选发布版本。有关更多信息,请访问:

http://www.red-gate.com/products/sql-development/sql-source-control/entrypage/migration

我们希望在未来的几个月中以该解决方案为基础,所以请告诉我们您的想法。


0

如果通过生成脚本并将这些脚本保持在源代码控制之下来处理模式更改,那么您应该能够像对待其他任何代码合并一样对待更改。您可以选择自动合并或采取更多手动干预。


真的不是。手动合并基础对象创建脚本是可行的,但是要进行更改,参考数据插入和数据运动脚本会变得非常混乱,非常迅速。
Mark Storey-Smith,

同意 在Red Gate,我们相信创建脚本可以很好地合并并且可以自动化。但是,必须手动合并版本之间的迁移脚本,以避免错误的依赖关系排序和更改代码重复。
David Atkinson

0

在类似的情况下,我在一个实时网站和几个开发分支上工作,这些分支需要更改数据库架构。

我通过编写可以很好地与git一起使用的post-checkout和post-merge挂钩解决了该问题。我将所有迁移以SQL文件的形式存储在一个单独的目录中,并将它们与更改的PHP代码一起提交。每次我执行

git checkout

或一个

git merge

git将自动调用相应的上迁移和下迁移。请参阅我在Github上的实现。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.