4

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

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

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

表顺序.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

4 回答 4

4

我不使用 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 模式更改脚本可以捕获这些更改并允许它们被“重放”。

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

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

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

快乐编码。

于 2012-07-12T22:56:09.773 回答
2

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

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

于 2015-11-25T19:55:39.903 回答
1

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

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

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

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

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

于 2012-07-12T22:44:05.710 回答
0

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

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

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

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

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

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

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

于 2020-12-03T17:00:45.587 回答