跟踪数据库架构更改的机制

pix*_*x0r 134 php mysql database svn migration

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

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

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

Joe*_*lla 56

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

对于您对数据库所做的每个更改,您都要编写一个新的迁移.迁移通常有两种方法:应用更改的"向上"方法和撤消更改的"向下"方法.单个命令使数据库保持最新,还可用于将数据库引入特定版本的模式.在Rails中,迁移保存在项目目录中的各自目录中,并像任何其他项目代码一样检入版本控制.

这个Oracle Rails迁移指南很好地涵盖了迁移.

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


rix*_*rrr 50

我们使用类似于bcwoord的东西来保持我们的数据库模式在5个不同的安装(生产,登台和一些开发安装)中同步,并在版本控制中备份,并且它运行良好.我会详细说明一下:


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

它们可用于添加表,添加列,将数据从旧列格式迁移到新列格式,然后删除列,插入"主"数据行(如用户类型等).基本上,它可以执行任何操作,并使用适当的数据迁移脚本,你永远不会丢失数据.

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

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

一切都进入源代码控制,每个安装都有一个脚本,可以通过单个脚本执行更新到最新版本(使用正确的数据库密码调用update.php等).我们SVN通过自动调用数据库更新脚本的脚本更新登台和生产环境,因此代码更新带有必要的数据库更新.

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


设置这个系统只需要几个小时,它在概念上很简单,并且每个人都获得了版本编号方案,并且在能够继续前进和发展数据库设计方面具有无可估量的价值,而无需通信或手动执行修改在所有数据库上.

请注意从phpMyAdmin粘贴查询时!那些生成的查询通常包括数据库名称,你绝对不需要它,因为它会破坏你的脚本!像CREATE TABLE这样的东西mydb.newtable如果系统上的数据库未被称为mydb,则(...)将失败.我们创建了一个预注释的SVN钩子,它将禁止包含该mydb字符串的.sql文件,这是一个确定的迹象,即有人在没有正确检查的情况下从phpMyAdmin复制/粘贴.


Bra*_*ood 12

我的团队编写了所有数据库更改脚本,并将这些脚本与应用程序的每个版本一起提交到SVN.这允许数据库的增量更改,而不会丢失任何数据.

要从一个版本转到下一个版本,您只需要运行一组更改脚本,并且您的数据库是最新的,并且您仍然可以获得所有数据.它可能不是最简单的方法,但绝对有效.


小智 10

这里的问题实际上是让开发人员可以轻松地将他们自己的本地更改编写到源代码控制中以与团队共享.多年来我一直面临这个问题,并受到Visual Studio for Database专业人员功能的启发.如果你想要一个具有相同功能的开源工具,试试这个:http://dbsourcetools.codeplex.com/ 玩得开心, - Nathan.


小智 10

如果您仍在寻找解决方案:我们正在提出一个名为neXtep designer的工具.它是一个数据库开发环境,您可以使用它来控制整个数据库.您在版本控制的存储库上工作,可以跟踪每个更改.

当您需要发布更新时,您可以提交组件,产品将自动生成以前版本的SQL升级脚本.当然,您可以从任何2个版本生成此SQL.

然后您有很多选择:您可以使用这些脚本并将其与您的应用程序代码一起放入SVN,以便它可以通过现有机制进行部署.另一种选择是使用neXtep的传递机制:脚本以称为"传递包"(SQL脚本+ XML描述符)的方式导出,安装程序可以理解此包并将其部署到目标服务器,同时确保条件一致性,依赖性检查,注册已安装的版本等

该产品是GPL,基于Eclipse,因此可在Linux,Mac和Windows上运行.它目前还支持Oracle,Mysql和Postgresql(DB2支持即将推出).查看维基,您可以在其中找到更多详细信息:http: //www.nextep-softwares.com/wiki


dea*_*mer 7

将架构转储到文件中并将其添加到源代码管理中.然后一个简单的差异会告诉你改变了什么.

  • 模式差异也存在更基本的问题.如何区分列drop + add与列重命名.答案很简单:你做不到.这就是您需要记录实际架构更改操作的原因. (7认同)

Sam*_*fee 7

Scott Ambler撰写了一系列关于数据库重构的文章(并共同撰写了一本书),其理念是你应该基本上应用TDD原则和实践来维护你的模式.您为数据库设置了一系列结构和种子数据单元测试.然后,在更改任何内容之前,您可以修改/编写测试以反映该更改.

我们已经做了一段时间了,它似乎工作.我们编写代码以在单元测试套件中生成基本列名和数据类型检查.我们可以随时重新运行这些测试,以验证SVN checkout中的数据库是否与应用程序实际运行的实时数据库匹配.

事实证明,开发人员有时也会调整他们的沙盒数据库而忽略更新SVN中的模式文件.然后代码依赖于尚未检入的数据库更改.这种类型的错误可能很难确定,但测试套件会立即启动它.如果将其内置到更大的持续集成计划中,这将特别好.


Rob*_*Rob 6

K. Scott Allen在架构版本控制方面有一两篇不错的文章,它使用了其他答案中引用的增量更新脚本/迁移概念; 请参阅http://odetocode.com/Blogs/scott/archive/2008/01/31/11710.aspx.


Mik*_*one 5

它有点低技术,并且可能有更好的解决方案,但您可以将模式存储在SQL脚本中,可以运行该脚本来创建数据库.我认为您可以执行命令来生成此脚本,但遗憾的是我不知道该命令.

然后,将脚本与对其一起工作的代码一起提交到源代码控制中.当您需要更改架构以及代码时,可以检查脚本以及需要更改架构的代码.然后,脚本上的差异将指示架构更改的差异.

使用此脚本,您可以将其与DBUnit或某种构建脚本集成,因此它似乎可以适应您已经自动化的流程.


Dan*_*Dan 5

如果您使用的是C#,请查看一个非常有用的ORM工具Subsonic,但也会生成sql脚本来重新创建您的方案和/或数据.然后可以将这些脚本放入源代码管理中.

http://subsonicproject.com/


Fab*_*mes 5

我们使用一个非常简单但有效的解决方案。

对于新安装,我们在存储库中有一个metadata.sql文件,其中包含所有数据库模式,然后在构建过程中,我们使用此文件来生成数据库。

对于更新,我们将更新添加到经过硬编码的软件中。我们对它进行硬编码,因为我们不喜欢在问题真正成为问题之前就解决问题,而且到目前为止,这种事情尚未证明是问题。

因此,在我们的软件中,我们有以下内容:

RegisterUpgrade(1, 'ALTER TABLE XX ADD XY CHAR(1) NOT NULL;');

此代码将检查数据库是否为版本1(存储在自动创建的表中),如果版本已过时,则执行命令。

为了更新存储库中的metadata.sql,我们在本地运行此升级,然后提取完整的数据库元数据。

经常发生的唯一事情就是忘记提交metadata.sql,但这不是主要问题,因为它易于在构建过程中进行测试,并且唯一可能发生的事情是使用以下命令进行新安装:一个过时的数据库,并在首次使用时对其进行了升级。

同样,我们不支持降级,但是这是设计使然,如果更新中出现问题,我们将还原先前的版本并修复更新,然后再尝试。


tbr*_*fni 5

我在Visual Studio中将以下数据库项目结构用于多个项目,并且效果很好:

数据库

变更脚本

0.PreDeploy.sql

1.SchemaChanges.sql

2.DataChanges.sql

3.Permissions.sql

创建脚本

Sprocs

功能

观看次数

然后,我们的构建系统通过按以下顺序执行脚本,将数据库从一个版本更新到另一个版本:

1.PreDeploy.sql

2.SchemaChanges.sql

“创建脚本”文件夹的内容

2.DataChanges.sql

3.Permissions.sql

每个开发人员通过将他们的代码附加到每个文件的末尾来检查其更改是否存在特定的错误/功能。完成主要版本并在源代码管理中分支后,更改脚本文件夹中的.sql文件的内容将被删除。