我真的不同意增量迁移被腐烂。在我看来,拥有一套本土脚本会比拥有一个真正的工具来完成这样的工作更糟糕,因为这样可以更容易地跟踪这些更改。以前我自己也遇到过类似的情况,所以希望我能分享一些见解。
根据我的经验,RDBMS 模式和分支不能很好地混合。根据您的分支,架构可能至少应该有点相似,在这种情况下,迁移不应有太大差异。或者我可能只是误解了问题的全部程度。例如,如果您试图将客户特定的代码保留在分支上,那么也许您应该考虑一种将其模块化的方法。我们做了类似的事情,有规定客户特定模式更改的规则,并且代码只能依赖于公共代码库,而不是相反。我们还根据模块和日期设置模块变更集之间的优先级,因此我们大部分都知道应用变更的顺序。当然是 YMMV,但在不知道您当前的设置的情况下很难给出具体信息。
在我以前的公司,我们成功地使用了一个名为Liquibase的工具,这听起来与您正在使用的类似。基本上,它是一种用于获取数据库模式的工具,以及从一个已知状态到另一个已知状态的所有数据。相同的变更集只应用一次,因为 liquibase 维护一个带有校验和的变更日志。变更日志以特定的 XML 格式编写。如果您需要其他选择,我强烈建议您尝试一下。
无论如何,我们处理客户代码和分支的方式是为给定的分支提供特定的数据库/模式。这样您就可以从分支点获得架构和数据,并且只将差异迁移到当前情况。我们没有撤消更改,即使理论上 liquibase 可以支持这一点,因为我们觉得它太麻烦且容易出错。鉴于 liquibase 保持它自己的状态,迁移总是像在给定分支上获取当前状态一样简单,然后全部应用。仅应用了新的变更集,使架构处于良好状态。
我们使用了分布式的mercurial,就像 git 一样,所以设置非常相似。我们还在开发笔记本电脑上安装了开发人员特定的本地数据库,以及针对不同客户和不同阶段(开发、集成、生产)的多个环境,因此该模型经过了真正的测试,效果出奇地好。我们在变更集中有一些冲突,但在引入问题后不久我们就能够解决这些冲突。本地开发环境确实是最难的部分,因为在开发过程中可能已经引入了一些架构更改,这些更改并不总是与后来的更改集兼容,但是更改的结构化性质,并且具有要恢复的已知状态导致很少真正的问题。
这种方法有一些注意事项:
- 对模式的所有和任何更改都必须在变更集中实现。造成混乱的最大原因总是有人只是摆弄了一下。
- 第一点也适用,即使您使用的是修改架构的工具,例如像Hibernate这样的 ORM 工具。您需要非常熟悉此工具才能了解它所做的更改和所需的更改。
- 所有用户都必须接受这一点,并接受教育以遵守规则。检查 1。
- 当迁移大量变更集开始花费太多时间时,就会出现一个问题。此时您将需要创建一个新的基线,这可能有点棘手,尤其是在有很多分支的情况下。最好提前计划好,至少知道所有现有的数据库分支。
- 您需要提前计划一下分支,以了解它们是否会在某个时候迁移回 master。简单的合并可能不适用于模式更改。
- 对于寿命很长的分支和分离的数据集,这个模型可能不够强大
然而,关键是,您对数据库的结构和控制越多,迁移就越容易。因此,像Liquibase这样的工具可能是一种非常有价值的资产,可以帮助您跟踪这些变化。这在更大程度上适用于更复杂的模型,而不是简单的模型,所以请至少不要考虑放弃你已经拥有的所有工具。并花一些时间探索其他替代工具。
一些结构和控制总比没有好,甚至更糟,认为你可以控制一大堆手动脚本。