【问题标题】:Database Version Control for MySQLMySQL 的数据库版本控制
【发布时间】:2012-07-12 18:51:54
【问题描述】:

您使用什么方法对数据库进行版本控制?我已将我们所有的数据库表作为单独的 .sql 脚本提交到我们的存储库(mercurial)。这样,如果团队中的任何成员对员工表进行了更改,例如,当我更新我的存储库时,我将立即知道哪个特定表已被修改。

这样的方法在:What are the best practices for database scripts under code control 中有所描述。 目前,我正在编写一个 python 脚本来执行数据库文件夹中的所有 .sql 文件,但是,由于外键约束导致的依赖问题确保我们不能只以任何顺序运行 .sql 文件。

python 脚本将生成一个文件,其中包含执行 .sql 文件的顺序。它将按照它们在 tableorder.txt 文件中出现的顺序执行 .sql 文件。一个表在其外键表被执行之前不能被执行,例如:

tableorder.txt

table3.sql
table1.sql
table7.sql 等

通过解析“show create table”mysql 命令的结果,我已经从代码生成了每个表的依赖关系列表。依赖项列表可能如下所示:

tblstate: tblcountry //tblcountry.sql must be executed before tblstate.sql etc
tblemployee: tbldepartment, tblcountry

要生成 tableorder.txt 的内容,我需要一个如下所示的算法:

function print_table(table):
  foreach table in database:
    if table.dependencies.count == 0
      print to tableorder.txt
    if table.dependencies.count > 0
      print_table(dependency) //print dependency first
end function

如您所想,这涉及大量递归。我开始怀疑这是否值得努力?如果那里有什么工具?考虑到依赖关系,有什么工具(或算法)可以生成执行单独的 .sql 表和视图的顺序列表?对每个表/视图分别控制单独的 .sql 文件更好,还是更好地将整个数据库版本控制为单个 .sql 文件?我将不胜感激任何回应,因为这已经花费了很多天。谢谢。

【问题讨论】:

    标签: python mysql database controls version


    【解决方案1】:

    我理解这个问题,但你不能想用 git 来控制数据库的版本,就好像它是静态代码 "" 因为它不起作用,以同样的方式,为每个生成不同的文件不是很有用程序员,因为正如您所说的那样,它们发生了冲突,或者它们没有可追溯性,我开始了一个与您的项目类似的项目,但是在尝试控制程序员的版本和冲突时,这是一个更大的问题,到达的解决方案是生成一个维护以下顺序的项目

    • 输入网页登录名/密码
    • 管理用户和每个用户可以做什么的配置文件
    • 委员会区域 -> 常用和当前命令发送到数据库
    • 示例:alter table ALTER TABLE users ADD por2 varchar (255);

    提交会在控制系统本身中创建可追溯性,并将结构从初始结构发送到 git 以控制更改

    • 变更控制区:是提交本身加上变更后生成的结构的可视化

    • 服务器配置区:对服务器进行配置,并在其中添加gitlab或github存储库,以更直观的方式进行版本控制,对开发人员没有任何问题

    • 备份恢复区:发送备份并跟踪每个版本“数据库结构更改的结果”

    这是我发现的最好的处理方式,无需将工作交给特定的人。我希望它对您有所帮助,我相信 phyton 是我发现的最好的,因为它使用 Django,并且您从管理部分节省了很多编程.. 问候

    【讨论】:

      【解决方案2】:

      您可以使用sqitch。这是一个tutorial for MySql,但它实际上与数据库无关。

      更改是作为您选择的数据库引擎的本机脚本实现的...数据库更改可能会声明对其他更改的依赖——甚至是来自其他 Sqitch 项目的更改。这确保了正确的执行顺序,即使您已经无序地提交了对 VCS 的更改……更改部署是通过维护计划文件来管理的。因此,您无需为更改编号,尽管您可以根据需要进行编号。 Sqitch 并不关心你如何命名你的更改……在你标记和发布你的应用程序之前,你可以随意修改你的更改部署脚本。他们不会仅仅因为他们致力于您的 VCS 而被锁定。这允许您采用迭代方法来开发数据库模式。或者,更好的是,您可以进行测试驱动的数据库开发。

      【讨论】:

        【解决方案3】:

        我不使用 MySQL,而是使用 SQL Server,但是,这就是 我的数据库版本:

        (这很长,但最后我希望我放弃一个简单的模式转储作为处理数据库版本控制的主要方法的理由是显而易见的。)

        1. 我对架构进行了修改并将其应用到测试数据库

        2. 我生成增量更改脚本在所述脚本之后的架构转储。 (我使用 ApexSQL,但可能有一些特定于 MySQL 的工具可以提供帮助。)

          1. 增量更改脚本知道如何从当前架构版本转到目标架构版本:ALTER TABLE existing、CREATE TABLE new、DROP VIEW old ..多个操作可以在与 相同的 .SQL 文件中发生delta 很重要。

          2. 模式的转储是目标模式版本:CREATE TABLE a, CREATE VIEW b .. 这里没有“ALTER”或“DROP”,因为它只是目标模式的快照。每个数据库对象都有一个 .SQL 文件,因为 架构 很重要。

        3. 我使用 RoundhouseE 应用增量更改脚本。 (我确实使用 RoundhouseE“随时脚本”功能,因为它不能正确处理关系。)

        我了解到 如果没有全面的分步计划就无法可靠地完成应用数据库架构更改,并且类似地(如问题中所述),的顺序关系依赖很重要。仅存储“当前”或“结束”模式是不够的。在不知道 A->B->C 的情况下,无法追溯应用许多更改 A->C,并且某些更改 B 可能涉及迁移逻辑或更正。 SQL 模式更改脚本可以捕获这些更改并允许它们被“重放”。

        但是,同时仅保存增量脚本并不能提供目标架构的“简单视图”。这就是为什么我也转储所有架构以及更改脚本和版本both。理论上,视图转储可用于构建数据库,但由于关系依赖(问题中提到的那种),它可能需要一些工作,我不将其用作自动模式恢复方法的一部分:然而,保留 Hg 版本控制的模式转储部分可以快速识别更改并查看特定版本的目标模式。

        变化增量因此向前通过修订,而模式转储提供当前修订的视图。因为变更增量是增量的并且只进,重要的是要让处理这些变更的分支保持“干净”,这对于 Hg 来说很容易做到。

        在我的一个项目中,我目前正在进行第 70 次数据库更改 - 并且快乐且富有成效! - 切换到此设置后。 (这些是已部署的更改,而不仅仅是开发更改!)

        编码愉快。

        【讨论】:

          【解决方案4】:

          我不确定这如何回答您的问题,但我倾向于只使用 mysqldump(标准安装的一部分)。这为我提供了创建表并填充它们的 sql,从而有效地序列化数据库。示例:

          > mysqldump -u username -p yourdatabase > database_dump.sql
          

          从转储 sql 文件加载数据库:

          mysql -u 用户名 -p -e "source /path/to/database_dump.sql"

          为了进一步回答您的问题,我会单独对每个表进行版本控制,仅当有多个人在数据库上工作时,如果只有一个转储受版本控制,可能会发生冲突。我从来没有遇到过这样的项目(在项目的初始阶段之后,数据库往往是系统中波动性最小的部分之一),所以我只是将数据库转储作为一个整体而不是每个转储进行版本控制单独表。

          【讨论】:

            最近更新 更多