跟踪数据库模式更改的机制

baut 发布于 2018-02-07 database 最后更新 2018-02-07 01:08 1040 浏览

跟踪和/或自动化数据库模式更改的最佳方法是什么?我们的团队使用Subversion进行版本控制,并且已经能够以这种方式自动执行我们的一些任务(将构建到临时服务器,将测试代码部署到生产服务器),但是我们仍然在手动进行数据库更新。我希望找到或创建一个解决方案,使我们能够跨不同环境的服务器高效地工作,同时继续使用Subversion作为后端,通过它将代码和数据库更新推送到各种服务器。 许多流行的软件包包括检测数据库版本并应用必要更改的自动更新脚本。这是甚至在更大规模(跨多个项目,有时多个环境和语言)上做到这一点的最好方法吗?如果是的话,是否有任何现有的代码简化了流程,或者最好只是推出我们自己的解决方案?有没有人实现过类似的东西,并将其集成到Subversion post-commit挂钩中,或者这是一个坏主意? 虽然支持多种平台的解决方案是可取的,但我们绝对需要支持Linux/Apache/MySQL/PHP堆栈,因为大部分工作都在该平台上。

已邀请:

ddolor

赞同来自:

这是一个有点低技术,可能有更好的解决方案,但你可以将你的架构存储在一个SQL脚本,可以运行创建数据库。我想你可以执行一个命令来生成这个脚本,但是我不知道这个命令是不幸的。 然后,将脚本与代码一起提交到源代码控制中。当您需要随代码一起更改模式时,可以将脚本与需要更改模式的代码一起签入。然后,脚本上的差异将指示模式更改的差异。 有了这个脚本,你可以将它与DBUnit或某种构建脚本集成在一起,所以它看起来可以适应已经自动化的过程。

ut_sed

赞同来自:

在Rails的世界中,有一个迁移的概念,在这个脚本中,数据库的变化是在Ruby中进行的,而不是数据库特有的SQL风格。您的Ruby迁移代码最终被转换为您当前数据库特有的DDL;这使得切换数据库平台非常容易。 对于您对数据库所做的每一项更改,都会编写一个新的迁移。迁移通常有两种方法:应用更改的“向上”方法和取消更改的“向下”方法。单个命令使数据库保持最新状态,也可用于将数据库引导至特定的模式版本。在Rails中,迁移被保存在项目目录的自己的目录中,并像其他任何项目代码一样进入版本控制。 This Oracle guide to Rails migrations涵盖了很好的迁移。 使用其他语言的开发人员已经考虑过迁移,并已经实现了自己的语言特定版本。我知道 Ruckusing ,这是一个在Rails迁移之后建模的PHP迁移系统;这可能是你在找什么。

lenim

赞同来自:

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

datque

赞同来自:

我创建了以生成版本命名的文件夹,并将升级和降级脚本放在那里。例如,您可以有以下文件夹:1.0.0,1.0.1和1.0.2。每个脚本都包含允许您在不同版本之间升级或降级数据库的脚本。 如果客户或客户在1.0.1版本中遇到问题,并且正在使用1.0.2,则将数据库恢复到其版本不会成为问题。 在你的数据库中,创建一个名为“schema”的表,在这个表中放入当前版本的数据库。然后写一个程序,可以升级或降级你的数据库很容易。 就像Joey说的,如果你在Rails世界里,使用Migrations。 :)

wquod

赞同来自:

我的团队编写了所有数据库更改的脚本,并将这些脚本提交给SVN,以及每个应用程序版本。这允许数据库的增量更改,而不会丢失任何数据。 从一个版本到另一个版本,您只需要运行一组更改脚本,并且您的数据库是最新的,并且您仍然拥有所有数据。这可能不是最简单的方法,但它绝对有效。

dodit

赞同来自:

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

aeius

赞同来自:

我们使用一个非常简单但有效的解决方案。 对于新安装,我们在存储库中有一个metadata.sql文件,它包含所有数据库模式,然后在构建过程中我们使用这个文件来生成数据库。 对于更新,我们在硬编码的软件中添加更新。我们坚持硬编码,因为我们不喜欢在问题真正成为问题之前解决问题,迄今为止这种问题并没有被证明是一个问题。 所以在我们的软件中,我们有这样的东西: RegisterUpgrade(1, 'ALTER TABLE XX ADD XY CHAR(1) NOT NULL;'); 这段代码将检查数据库是否在版本1中(存储在自动创建的表中),如果数据库已过期,则执行该命令。 要更新存储库中的metadata.sql,我们在本地运行此升级,然后提取完整的数据库元数据。 唯一经常发生的事情就是忘记提交metadata.sql,但这不是一个大问题,因为它容易在构建过程中测试,而且唯一可能发生的事情就是使用一个过时的数据库,并在第一次使用时升级它。 此外,我们不支持降级,但它是通过设计,如果更新中断,我们恢复了以前的版本,并在重新尝试之前修复更新。

veos

赞同来自:

我已经在Visual Studio中使用了以下数据库项目结构来处理几个项目,并且工作得非常好: 数据库

Change Scripts
0.PreDeploy.sql 1.SchemaChanges.sql 2.DataChanges.sql 3.Permissions.sql
创建脚本
Sprocs Functions Views
然后,我们的构建系统通过按以下顺序执行脚本,将数据库从一个版本更新到下一个版本:
1.PreDeploy.sql 2.SchemaChanges.sql Contents of Create Scripts folder 2.DataChanges.sql 3.Permissions.sql
每个开发人员通过将他们的代码附加到每个文件的末尾来检查其特定错误/功能的变化。一旦主要版本完成并在源代码管理中分支,“更改脚本”文件夹中的.sql文件的内容将被删除。

siusto

赞同来自:

我们使用类似于bcwoord的东西来保持我们的数据库模式跨5个不同的安装(生产,分期和一些开发安装)同步,并在版本控制中备份,并且工作得很好。我会详细说明一下:


为了同步数据库结构,我们有一个脚本,update.php和一些编号为1.sql,2.sql,3.sql等的文件。脚本使用一个额外的表来存储当前的版本号数据库。 N.sql文件是手工制作的,从版本(N-1)到版本N的数据库。 它们可以用来添加表,添加列,将数据从旧的格式迁移到新的列格式,然后删除列,插入“主”数据行(如用户类型等)。基本上,它可以做任何事情,并使用适当的数据迁移脚本永远不会丢失数据。 更新脚本的工作原理是这样的:
  • Connect to the database.
  • Make a backup of the current database (because stuff will go wrong) [mysqldump].
  • Create bookkeeping table (called _meta) if it doesn't exist.
  • Read current VERSION from _meta table. Assume 0 if not found.
  • For all .sql files numbered higher than VERSION, execute them in order
  • If one of the files produced an error: roll back to the backup
  • Otherwise, update the version in the bookkeeping table to the highest .sql file executed.
一切都进入源代码管理,每个安装都有一个脚本,用一个脚本执行(使用适当的数据库密码调用update.php)来更新到最新版本。我们SVN通过自动调用数据库更新脚本的脚本来更新分段和生产环境,因此代码更新随附必要的数据库更新。 我们也可以使用相同的脚本从头重新创建整个数据库;我们只需删除并重新创建数据库,然后运行将完全重新填充数据库的脚本。我们也可以使用脚本来填充一个空的数据库进行自动化测试。
建立这个系统只需要几个小时,它在概念上是简单的,每个人都可以获得版本编号方案,并且具有向前推进和发展数据库设计的能力,而无需通信或手动执行修改在所有数据库上。 当从phpMyAdmin粘贴查询时,要小心!那些生成的查询通常包含数据库名称,您肯定不希望这样做,因为它会破坏您的脚本!像CREATE TABLE mydb.newtable(...)这样的东西,如果系统上的数据库没有被调用mydb将会失败。我们创建了一个预注释的SVN钩子,它将禁止包含mydb字符串的.sql文件,这是一个肯定的迹象,表明有人从phpMyAdmin复制/粘贴没有适当的检查。

iipsa

赞同来自:

对于我目前的PHP项目,我们使用rails migrations的思想,我们有一个migrations目录,其中我们保留文件标题“migration_XX.sql”,其中XX是迁移的编号。目前这些文件是在更新时手动创建的,但是它们的创建可以很容易修改。 然后我们有一个名为“Migration_watcher”的脚本,正如我们在pre-alpha中那样,当前在每个页面加载上运行,并检查是否有一个新的migration_XX.sql文件,其中XX大于当前的迁移版本。如果是这样,它会运行所有migration_XX.sql文件对数据库最大的数字,瞧!模式更改是自动的。 如果你需要恢复系统的能力,需要进行大量的调整,但是这很简单,并且对于我们这个相当小的团队来说工作得非常好。

set

赞同来自:

Scott Ambler撰写了一系列有关数据库重构的系列文章(共同撰写了一篇book),其中提出了基本上应用TDD原则和实践来维护模式的想法。您为数据库设置了一系列结构和种子数据单元测试。然后,在您更改任何内容之前,您可以修改/编写测试以反映该更改。 我们已经这样做了一段时间,似乎工作。我们编写代码来在单元测试套件中生成基本的列名和数据类型检查。我们可以随时重新运行这些测试,以验证SVN签出中的数据库是否与应用程序实际运行的活动数据库匹配。 事实证明,开发人员有时也会调整他们的沙盒数据库,而忽略在SVN中更新模式文件。然后代码依赖于尚未签入的数据库更改。这种错误可能非常难以确定,但测试套件将立即提取。如果您将其内置到一个更大的持续集成计划中,这将特别有用。

gipsam

赞同来自:

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

stotam

赞同来自:

我建议使用Ant(跨平台)作为“脚本”方面(因为它实际上可以通过jdbc与任何db通信)和Subversion的源代码库。 在进行更改之前,Ant会让您将数据库“备份”到本地文件。 1.通过Ant将现有的数据库模式备份到文件 2.通过Ant将版本控制到Subversion版本库 3.通过Ant发送新的SQL语句到数据库

funde

赞同来自:

这里的问题实际上使开发人员可以轻松地将自己的本地更改编写到源代码管理中,以便与团队共享。我已经遇到了这个问题很多年了,并且受到了Visual Studio for Database专业人员的功能的启发。如果你想要一个具有相同功能的开源工具,试试这个:http://dbsourcetools.codeplex.com/ 玩的开心,

  • Nathan。

faut

赞同来自:

有一个命令行mysql-diff工具,用于比较数据库模式,其中模式可以是磁盘上的实时数据库或SQL脚本。对于大多数模式迁移任务来说都是好事。

funde

赞同来自:

如果您仍然在寻找解决方案:我们正在提出一个名为neXtep designer的工具。这是一个数据库开发环境,您可以将整个数据库置于版本控制之下。你在一个版本控制库上工作,每一个变化都可以被跟踪。 当您需要发布更新时,您可以提交组件,产品将自动生成以前版本的SQL升级脚本。当然,你可以从任何2个版本生成这个SQL。 然后你有很多选择:你可以把这些脚本放到你的SVN中,并用你的应用代码,这样它就可以被现有的机制部署了。另一个选择是使用neXtep的传递机制:脚本被导出到一个被称为“传递包”(SQL脚本+ XML描述符)的东西中,安装程序可以理解这个包并将其部署到目标服务器,同时确保一致性,依赖性检查,注册安装的版本等 该产品是GPL,基于Eclipse,因此它可以在Linux,Mac和Windows上运行。它也支持Oracle,Mysql和Postgresql(DB2支持正在进行中)。看看维基,你会发现更详细的信息: http://www.nextep-softwares.com/wiki

eenim

赞同来自:

Toad for MySQL有一个称为模式比较的功能,允许您同步2个数据库。这是我迄今为止使用的最好的工具。

bipsam

赞同来自:

恕我直言迁移确实有一个巨大的问题: 从一个版本升级到另一个版本可以正常工作,但是如果你有数百个表格和长期的修改历史(如我们所做的那样),那么重新安装一个给定的版本可能会花费很长时间。 从基线到现在的版本(为数百个客户数据库)运行整个历史的三角洲可能需要很长时间。

znemo

赞同来自:

我喜欢Yii处理数据库迁移的方式。迁移基本上是一个实现CDbMigration的PHP脚本。 CDbMigration定义了包含迁移逻辑的up方法。也可以实施down方法来支持迁移的逆转。或者,可以使用safeUpsafeDown来确保迁移是在事务的上下文中完成的。 Yii的命令行工具yiic包含对创建和执行迁移的支持。迁移可以一个接一个或一个批次应用或反转。创建一个迁移的结果代码为实现CDbMigration的PHP类,基于用户指定的时间戳和迁移名称进行唯一命名。之前应用于数据库的所有迁移都存储在迁移表中。 有关更多信息,请参阅手册中的Database Migration文章。