用于跟踪数据库架构更改的机制 [已关闭]

2022-08-30 06:57:02

跟踪和/或自动执行数据库架构更改的最佳方法是什么?我们的团队使用 Subversion 进行版本控制,我们已经能够通过这种方式自动执行一些任务(将构建推送到临时服务器,将测试代码部署到生产服务器),但我们仍在手动进行数据库更新。我想找到或创建一个解决方案,使我们能够在具有不同环境的服务器之间有效地工作,同时继续使用Subversion作为后端,通过后端将代码和数据库更新推送到各个服务器。

许多流行的软件包都包含自动更新脚本,用于检测数据库版本并应用必要的更改。这是即使在更大规模(跨多个项目,有时跨多个环境和语言)的情况下实现这一目标的最佳方法吗?如果是这样,是否有任何现有的代码可以简化流程,或者最好只是推出我们自己的解决方案?以前有没有人实现过类似的东西,并将其集成到Subversion后提交钩子中,或者这是一个坏主意?

虽然支持多个平台的解决方案更可取,但我们肯定需要支持Linux / Apache / MySQL / PHP堆栈,因为我们的大部分工作都在该平台上。


答案 1

在Rails世界中,有迁移的概念,其中对数据库的更改是在Ruby中进行的,而不是特定于数据库的SQL。您的Ruby迁移代码最终被转换为特定于您当前数据库的DDL;这使得切换数据库平台变得非常容易。

对于对数据库所做的每个更改,您都会编写一个新的迁移。迁移通常有两种方法:应用更改的“向上”方法和撤消更改的“向下”方法。单个命令使数据库保持最新,并且还可用于使数据库达到特定版本的架构。在 Rails 中,迁移保存在项目目录中自己的目录中,并像任何其他项目代码一样签入到版本控制中。

这本Oracle Rails迁移指南很好地涵盖了迁移。

使用其他语言的开发人员已经研究了迁移,并实现了他们自己的特定语言版本。我知道Ruckusing,一个以Rails迁移为模型的PHP迁移系统;它可能是你要找的。


答案 2

我们使用类似于 bcwoord 的东西来保持我们的数据库架构在 5 个不同的安装(生产、暂存和一些开发安装)中保持同步,并在版本控制中备份,并且运行良好。我来详细阐述一下:


为了同步数据库结构,我们有一个脚本,update.php和许多编号为1.sql,2.sql,3.sql等的文件。该脚本使用一个额外的表来存储数据库的当前版本号。N.sql文件是手工制作的,从数据库的版本(N-1)到版本N。

它们可用于添加表,添加列,将数据从旧列格式迁移到新列格式,然后删除列,插入“主”数据行(如用户类型等)。基本上,它可以做任何事情,并且使用适当的数据迁移脚本,您永远不会丢失数据。

更新脚本的工作方式如下:

  • 连接到数据库。
  • 备份当前数据库(因为事情出错)[mysqldump]。
  • 创建簿记表(称为_meta)(如果它不存在)。
  • 从表中读取_meta当前版本。如果未找到,则假定为 0。
  • 对于编号高于 VERSION 的所有.sql文件,请按顺序执行它们
  • 如果其中一个文件产生错误:回滚到备份
  • 否则,请将簿记表中的版本更新为执行文件的最高.sql。

所有内容都进入源代码管理,并且每个安装都有一个脚本,用于通过单个脚本执行(调用 update.php使用正确的数据库密码等)更新到最新版本。我们通过自动调用数据库更新脚本的脚本来更新暂存和生产环境,因此代码更新附带必要的数据库更新。

我们还可以使用相同的脚本从头开始重新创建整个数据库;我们只需删除并重新创建数据库,然后运行将完全重新填充数据库的脚本。我们还可以使用该脚本填充空数据库以进行自动测试。


设置这个系统只需要几个小时,它在概念上很简单,每个人都可以获得版本编号方案,并且它具有向前推进和发展数据库设计的能力,而不必对所有数据库进行通信或手动执行修改,这是非常宝贵的。

不过,在粘贴来自phpMyAdmin的查询时要小心!这些生成的查询通常包括数据库名称,您绝对不希望这样做,因为它会破坏您的脚本!类似于“创建表”。(...)如果系统上的数据库不称为 mydb,则将失败。我们创建了一个注释前的SVN钩子,它将禁止.sql包含该字符串的文件,这是一个明确的迹象,表明有人在没有正确检查的情况下从phpMyAdmin复制/粘贴。mydbnewtablemydb


推荐