首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MySQL架构源代码管理

MySQL架构源代码管理
EN

Stack Overflow用户
提问于 2011-06-01 23:28:39
回答 4查看 1.3K关注 0票数 4

在我的公司,我们有几个开发人员都在内部处理项目,每个人都有自己的virtualbox设置。我们使用SVN来处理源代码,但偶尔会遇到需要更改数据库(MySQL)模式的问题,并且必须将此更改传播给所有其他开发人员。目前,我们有一个手动编写的日志文件,其中列出了您所做的更改,以及执行更改所需的SQL。

我希望有更好的解决方案--理想情况下是链接到SVN的解决方案,例如,如果您更新到修订版893,系统知道这需要数据库修订版183,并自动更新您的本地模式。我们关心的不是同步的数据,而是模式。

当然,一种解决方案是让所有开发人员运行一个单一的中央数据库;然而,这有一个缺点,即模式更改可能会破坏其他所有人的构建,直到他们完成一个svn。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-06-01 23:33:20

一种选择是YAML/JSON格式的数据字典。有一篇很好的文章here

票数 2
EN

Stack Overflow用户

发布于 2011-06-02 00:16:06

我会考虑看看像MyBatis Schema Migration tools这样的东西。这不完全是你所描述的,但我认为它以一种优雅的方式解决了你的问题,并且可以在不引入核心MyBatis的情况下使用。

就滚动您自己的模式而言,我总是做的是有一个基本模式文件,它将从头开始创建模式,以及一个增量文件,它将所有模式更改附加为增量,由版本号分隔(您可以尝试使用SVN编号,但我总是发现手动递增更容易)。然后有一个schema_version表,其中包含实时数据库的信息,规范模式文件将包含该信息,并具有一个脚本,该脚本将从增量脚本运行现有DB版本之后的所有更改。

所以你会有一个类似这样的模式:

代码语言:javascript
复制
-- Version: 1
CREATE TABLE user (
id bigint,
name varchar(20))

您可以使用该工具管理模式版本表,并看到类似以下内容:

代码语言:javascript
复制
> SELECT * FROM schema_version;
1,2011-05-05

然后,有几个人添加到模式中,并拥有一个如下所示的增量文件:

代码语言:javascript
复制
-- Version: 2
ALTER TABLE user ADD email varchar(20);
-- Version: 3
ALTER TABLE user ADD phone varchar(20);

和相应的新模式,并使用以下命令签入:

代码语言:javascript
复制
-- Version: 3
CREATE TABLE user (
id bigint,
name varchar(20),
email charchar(20),
phone varchar(20))

当您对具有初始模式(版本1)的数据库运行增量脚本时,它将从schema_version表中读取该值,并将大于该值的所有增量应用于您的模式。当您开始处理分支时,这会变得更加棘手,但这只是一个简单的起点。

票数 2
EN

Stack Overflow用户

发布于 2011-06-02 00:45:31

有几种我以前使用过或目前正在使用的方法:

连续版本号

大多数使用这种方法的程序都有一个单独的程序,该程序从数据库中获取一个版本号,然后执行与高于该版本号的数据库版本相关的任何语句,最后更新数据库中的版本号。

因此,如果版本是37,并且在升级应用程序中有与版本1到38相关联的语句,它将跳过1到37,并执行语句以将数据库带到版本38。

我见过的实现也允许每个版本的降级语句来撤消升级所做的事情,这允许将数据库从版本38恢复到版本37。

在我的情况下,我们在应用程序本身中升级了这个数据库,并且没有降级。因此,更改是受源代码控制的,因为它们是应用程序的一部分。

有向无环图

在最近的一个项目中,我提出了一种不同的方法。我使用作为有向无环图的节点的类来封装语句,以便为每个特定的特性/bugfix/等对数据库进行特定的升级。每个节点都有一个属性来声明它的唯一名称和它所依赖的任何节点的名称。这些属性还用于搜索所有升级节点的程序集。

缺省根节点被指定为任何没有依赖关系的节点的依赖关系节点,该节点包含用于创建migrationregister表的语句,该表列出了已经应用的节点的名称。将所有节点排序到一个顺序列表中后,将依次执行这些节点,跳过已应用的节点。

这些都包含在与主应用程序不同的单独应用程序中,并且它们在同一存储库中受源代码控制,因此,当开发人员完成对某个功能以及与其关联的数据库更改的工作时,它们将一起提交到相同的更改集中。如果您提取功能的更改,则也会提取数据库更改。此外,主应用程序只需要一个预期节点名称的列表。任何额外的或丢失的,它知道数据库不匹配。

我选择这种方法是因为项目通常由多个开发人员进行并行开发,每个开发人员有时在开发中有不止一件事情(分支开发,有时非常分支)。摆弄数据库版本号是相当痛苦的。如果每个人都从版本37开始,"Alice“从某个版本开始,并使用版本38,因此它将更改她的数据库,而"Bob”也开始必须更改数据库的工作,也使用版本38,最终会有人需要更改。因此,假设Bob完成并推送到服务器。现在,当Alice提取Bob的变更集时,她必须将语句的版本更改为39,并将她的数据库版本设置回37,以便Bob的更改将被执行,但随后她的更改将再次执行。

但是,当Alice拉出Bob的变更集时,所发生的一切只是有一个新的迁移节点和要检查的节点名列表中的另一行,事情就能正常工作。

我们使用Mercurial (分布式)而不是SVN (客户端-服务器),这就是为什么这种方法对我们如此有效的部分原因。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6203712

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档