代码之家  ›  专栏  ›  技术社区  ›  markus

从MySQL模式的版本控制开始,不要过度杀戮。好的解决方案?

  •  7
  • markus  · 技术社区  · 15 年前

    我已经意识到我必须开始对数据库模式和更改进行版本控制。因此,我阅读了关于这个主题的现有文章,但我不确定如何继续。

    我基本上是一个一人公司,不久前我甚至没有在代码中使用版本控制。我在Windows环境中,使用Aptana(IDE)和SVN(使用Tortoise)。我在PHP/MySQL项目上工作。

    什么是有效和充分(没有过度杀伤力)的方法来版本化我的数据库模式?

    我在一些项目中确实有一两个自由职业者,但我不希望有太多的分支和合并。所以基本上我想跟踪代码修订的并发模式。

    [编辑] 瞬时解 :目前,我决定只要在提交标记(稳定版本)时进行模式转储,再加上一个包含必要初始数据的转储。在目前阶段,这对我来说似乎已经足够了。

    [edit2]另外,我现在还使用了第三个名为increments.sql的文件,其中我将所有更改与日期等放在一起,以便于在一个文件中跟踪更改历史记录。我不时地将更改集成到其他两个文件中,并清空增量。sql[/edit]

    11 回复  |  直到 10 年前
        1
  •  7
  •   Manos Dilaverakis    14 年前

    对于小公司来说,简单的方法是:将数据库转储到SQL并将其添加到存储库中。然后,每次更改内容时,都将更改添加到转储文件中。

    然后您可以使用diff查看版本之间的更改,更不用说有注释来解释您的更改。这也将使您实际上对MySQL升级免疫。

    我看到的一个缺点是,您必须记住手动将SQL添加到转储文件中。你可以训练自己时刻记住,但是如果你和别人一起工作的话要小心。错过一个更新可能是一个痛苦的稍后。

    这可以通过创建一些精心编写的脚本来缓解,以便在提交给颠覆者时为您完成这项工作,但对于一个人的节目来说,这有点过分。

    编辑: 在这个答案之后的一年里,我必须为一个小团队实现MySQL的版本控制方案。手动添加每个更改被视为一个麻烦的解决方案,就像在注释中提到的那样,所以我们继续转储数据库并将该文件添加到版本控制中。

    我们发现,测试数据最终会出现在转储文件中,这使得我们很难确定发生了什么变化。这可以通过只转储模式来解决,但是对于我们的项目来说,这是不可能的,因为我们的应用程序依赖于数据库中的某些数据来运行。最后,我们返回手动添加对数据库转储的更改。

    这不仅是最简单的解决方案,而且还解决了MySQL某些版本在导出/导入时存在的某些问题。通常,我们必须转储开发数据库,删除任何测试数据、日志条目等,删除/更改某些适用的名称,然后才能创建生产数据库。通过手动添加更改,我们可以精确地控制生产中的最终结果,一次一点,这样最终一切都准备就绪,并尽可能无痛地转移到生产环境中。

        2
  •  2
  •   vartec    15 年前

    如何对通过执行此操作生成的文件进行版本控制:

    mysqldump --no-data database > database.sql
    
        3
  •  2
  •   Robin    15 年前

    在我工作的地方,我们为应用程序的每个新版本都提供了一个安装脚本,其中包含升级所需运行的SQL。这对于6个devs来说已经足够好了,并且有一些维护版本的分支。我们正在考虑换成自动补丁 http://autopatch.sourceforge.net/ 它处理如何确定要应用于正在升级的任何数据库的修补程序。看起来在使用自动补丁处理分支时可能会有一些小的复杂问题,但听起来这并不是问题所在。

        4
  •  2
  •   stefs    15 年前

    我想,像这样的批处理文件应该可以完成这项工作(不是很难做到的)。

    mysqldump --no-data -ufoo -pbar dbname > path/to/app/schema.sql
    svn commit path/to/app/schema.sql

    只需在更改模式后运行批处理文件,或者让cron/scheduler执行(但我不知道…我认为,如果只是时间戳发生了变化,即使内容相同,也会提交工作。不知道这会不会是个问题。)

        5
  •  2
  •   Gabriel Solomon    15 年前

    主IDeea是在项目基路径中有一个具有此结构的文件夹。

    /__DB
    —-/changesets
    ——–/1123
    —-/data
    —-/tables
    

    现在,你有三个文件夹,这就是你的工作对象: 桌子 保留表创建查询。我建议使用命名表。

    数据 保留表插入数据查询。我建议使用相同的命名表名。 注意:并非所有表都需要数据文件,您将只添加在Project安装时需要此初始数据的表。

    变化集 这是您将要使用的主文件夹。 这将保存对初始结构所做的更改集。这实际上保存了带有变更集的文件夹。 例如,我添加了一个文件夹1123,其中包含在版本1123中所做的修改(编号来自代码源代码管理),并且可能包含一个或多个SQL文件。

    我喜欢将它们分组到名为xx_tablename.sql的表中-xx是一个数字,它告诉运行它们的顺序,因为有时需要以特定的顺序运行修改。

    注: 修改表时,还可以将这些修改添加到表和数据文件中,因为这些文件将用于执行新安装。

    这是主要的思想。

    有关详细信息,您可以查看此 blog post

        6
  •  1
  •   Mitch    14 年前

    看一看 SchemaSync .它将生成一段时间内迁移和版本数据库架构所需的补丁和恢复脚本(.sql文件)。它是MySQL的命令行实用程序,与语言和框架无关。

        7
  •  1
  •   Maxim Antonov    14 年前

    几个月前,我在工具中搜索MySQL模式的版本。我发现了很多有用的工具,比如理论迁移、RoR迁移、Java中的一些工具和Python。

    但没有人满足我的要求。

    我的要求:

    1. 无要求,不含php和mysql
    2. 没有模式配置文件,比如条令中的schema.yml
    3. 能够从连接中读取当前模式并创建新的迁移脚本,这比在应用程序的其他安装中表示相同的模式要好。

    我开始编写我的迁移工具,今天我有了测试版。

    如果你对这个话题感兴趣,请试一试。 请给我以后的请求和错误报告。

    源代码:bitback.org/idler/mmp/src 英文概述:bitback.org/idler/mmp/wiki/home 俄语概述:antonoff.info/development/mysql-migration-with-php-project

        8
  •  1
  •   Gary    14 年前

    我们的解决方案是mysql工作台。我们定期将现有数据库反向工程到具有适当版本号的模型中。然后可以根据需要轻松地在版本之间执行差异。另外,我们得到了很好的EER图等。

        9
  •  1
  •   Pasi Savolainen    14 年前

    在我们公司,我们是这样做的:

    我们将所有tables/db对象放在它们自己的文件中,比如 tbl_Foo.sql . 文件包含几个用分隔符分隔的“部分”

    -- part: create
    

    哪里 create 只是给定零件的描述性标识,文件如下:

    -- part: create
    IF not exists ...
    CREATE TABLE tbl_Foo ...
    -- part: addtimestamp
    IF not exists ...
    BEGIN
       ALTER TABLE ...
    END
    

    然后我们有一个XML文件,它引用了我们在将数据库更新到新模式时要执行的每个单独部分。 看起来很像这样:

    <playlist>
       <classes>
         <class name="table" desc="Table creation" />
         <class name="schema" desc="Table optimization" />
       </classes>
       <dbschema>
          <steps db="a_database">
             <step file="tbl_Foo.sql" part="create" class="table" />
             <step file="tbl_Bar.sql" part="create" class="table" />
          </steps>
          <steps db="a_database">
             <step file="tbl_Foo.sql" part="addtimestamp" class="schema" />
          </steps>
       </dbschema>          
    </playlist>
    

    这个 <classes/> 部分用于GUI,以及 <dbschema/> 具有 <steps/> 是分区更改。这个 <step/> :s按顺序执行。我们还有其他一些实体,比如 sqlclr 做一些不同的事情,比如部署二进制文件,但基本上就是这样。

    当然,我们有一个组件,它获取播放列表文件和一个资源/文件系统对象,该对象交叉引用播放列表并取出所需的部分,然后作为数据库上的管理员运行它们。

    由于.sql中的“parts”是为在任何版本的db上执行而编写的,所以我们可以在每个以前/以前版本的db上运行所有parts,并将其修改为当前版本。 当然,在某些情况下,SQL Server会“早期”解析列名称,我们必须稍后修改部分以使其成为 exec_sql S,但这种情况并不经常发生。

        10
  •  1
  •   markus    10 年前

    我认为这个问题应该有一个现代的答案,所以我自己来回答。当我在2009年写这个问题的时候,我不认为 Phinx 已经存在,而拉拉维尔肯定没有。

    今天,这个问题的答案非常清楚:编写增量数据库迁移脚本,每个脚本都有一个 up 和A down 方法并在安装或更新应用程序时运行所有这些脚本或其中的增量。很明显,将迁移脚本添加到VCS中。

    如前所述,目前PHP世界中有许多优秀的工具可以帮助您轻松地管理迁移。Laravel内置了DB迁移,包括各自的shell命令。其他每个人都有一个与phinx类似的强大框架无关的解决方案。

    工匠迁移(laravel)和phinx的工作原理相同。对于数据库中的每个更改,创建一个新的迁移,使用普通的SQL或内置的查询生成器编写上下方法并运行 artisan migrate RESP phinx migrate 在控制台。

        11
  •  0
  •   Jason    15 年前

    我做一些类似于manos的事情,除了我有一个“master”文件(master.sql),我定期更新(每2个月更新一次)。然后,对于每个更改,我构建一个名为.sql文件的版本。这样,我就可以从master.sql开始,添加名为.sql文件的每个版本,直到达到当前版本,并且可以使用名为.sql文件的版本更新客户端,从而使事情变得简单。