MySQL的数据库版本控制

时间:2012-07-12 22:33:00

标签: python mysql database controls version

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

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

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文件?我会感谢任何回应,因为这已经花了这么多天。感谢。

4 个答案:

答案 0 :(得分:4)

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

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

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

  2. 我在所述脚本之后生成增量更改脚本模式的转储。 (我使用ApexSQL,但可能有特定于MySQL的工具来帮助。)

    1. delta更改脚本知道如何从当前模式版本到目标模式:ALTER TABLE existing,CREATE TABLE new,DROP VIEW old ..多个操作可以在与相同的.SQL文件中发生delta 非常重要。

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

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

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

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

    更改增量因此向前移动通过修订,而架构转储在当前版本提供视图。因为更改增量是增量的并且仅向前,所以保持处理这些更改的分支“干净”非常重要,这很容易用Hg。

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

    快乐的编码。

答案 1 :(得分:1)

我不确定这回答你的问题有多好,但我倾向于使用mysqldump(标准安装的一部分)。这给了我sql来创建表并填充它们,有效地序列化数据库。例如:

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

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

  

mysql -u username -p -e“source /path/to/database_dump.sql”

为了进一步回答你的问题,我会分别对每个表进行版本控制,只有当有多个人在数据库上工作时,只有一个转储被版本控制才可能发生冲突。我从来没有遇到过这种情况的项目(在项目的初始阶段之后数据库往往是系统中最不易变化的部分之一),所以我只是版本控制数据库转储作为一个整体而不是每个单独表。

答案 2 :(得分:1)

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

  

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

答案 3 :(得分:0)

我了解问题所在,但您无法考虑使用git来控制数据库版本,就好像它是静态代码“”一样,因为它无法以相同的方式工作,并且为每个数据库生成不同的文件不是很有用程序员,因为正如您所说的那样,或者它们没有可追溯性,我启动了一个项目,与您的项目类似,但是当试图控制版本和程序员之间的冲突时,这是一个更大的问题。到达的解决方案是生成一个维护以下顺序的项目

  • 输入Web登录名/密码
  • 用户管理和每个用户可以执行的操作的个人资料
  • 委员会区域->通用命令和当前命令发送到数据库
  • 示例:alter table ALTER TABLE用户添加por2 varchar(255);

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

  • 变更控制区域:它是提交本身以及变更后生成的结构的可视化视图

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

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

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