比较两个MySQL数据库

368

我目前正在使用MySQL数据库开发一个应用程序。

数据库结构仍在变动,开发过程中会有所更改(我会更改本地副本,而不是测试服务器上的副本)。

是否有一种方法可以比较这两个数据库实例,以查看是否有任何更改?

当前只需丢弃先前的测试服务器数据库就好了,但随着测试数据的输入,情况可能会变得有些棘手。
在生产环境中,同样的问题更加突出...

有没有一种简便的方法来逐步修改生产数据库,最好是自动生成修改脚本?


答案中提到的工具:


4
我相信RedGate的工具仅适用于SQL Server。 - Dave R.
4
Red Gate现在也有MySQL版本,目前处于扩展早期访问阶段,因此是免费的:http://www.red-gate.com/products/MySQL_Compare/index.htm。 - David Atkinson
2
这是一个真正的问题。每当我从开发机器部署到生产机器,总会出现故障。感谢您发布这篇信息丰富的文章。 - Herr
1
Redgate的MySQL工具现在每个用户售价为70美元。即使以这个价格,我也会进行评估并在此处发布评论。 - Jeremy McGee
一个非常好的替代Windows、Linux或Mac的工具是MySQL自己开发的mysqldbcompare。请参见我在这里的答案以获取更多信息:http://stackoverflow.com/a/26192873/1365289!我花了很长时间才找到它,但这个工具值得一试! - Jasdeep Khalsa
显示剩余4条评论
21个回答

210

如果你正在处理小型数据库,我发现在两个数据库上运行 mysqldump 命令时,使用 --skip-comments--skip-extended-insert 选项生成 SQL 脚本,然后在 SQL 脚本上运行 diff 命令效果相当不错。

通过跳过注释,避免了无意义的差异,例如你运行 mysqldump 命令的时间。使用 --skip-extended-insert 命令确保每一行都插入自己的插入语句中。这消除了一个新的或修改的记录可能会导致所有未来插入语句中出现连锁反应的情况。使用这些选项生成没有注释的更大的转储文件,因此在生产环境中可能不适用,但对于开发来说应该没问题。下面是我使用的命令示例:

mysqldump --skip-comments --skip-extended-insert -u root -p dbName1>file1.sql
mysqldump --skip-comments --skip-extended-insert -u root -p dbName2>file2.sql
diff file1.sql file2.sql

12
命令行熟练度加倍加赞!!! - dogenpunk
5
如果要比较数据,请改用这个命令;其中还会包含一些有关字符集等MySQL4+的注释。mysqldump --opt --compact --skip-extended-insert -u 用户名 -p 数据库名 表名 > 文件名.sql - zanlok
41
“-d”或“--no-data”可能对那些需要生产使用但只关心模式的人很有用。 - lsl
7
更好的工具是使用由MySQL开发的mysqldbcompare实用程序,您可以在Windows、Linux或Mac上使用它 - 它还可以输出针对数据和模式更改的SQL语句,并执行比简单命令行diff更多的测试。 - Jasdeep Khalsa
4
尝试使用“vimdiff”进行色彩差异漂亮展示。 - gitaarik
显示剩余8条评论

98

Toad for MySQL拥有数据和架构比较功能,甚至可以创建同步脚本。最重要的是,它是免费软件。


2
所有提到的工具看起来都不错。我现在会随意选择Toad,直到我能进行更多的研究。 - Vincent Ramdhanie
64
我对这个工具非常兴奋,直到意识到它只在Windows上运行,而不是Linux。只能重新寻找其他工具了... - jdias
2
非常出色的工作。它完成了我需要它做的一切,突出显示更改记录的单元格使得查看更改变得轻松简单。 - thames
4
使用--run-all-tests --difftype sql --disable-binary-logging选项的mysqldbcompare几乎可以完成相同的任务(除了输出混合了注释和字符串中的特殊字符未转义)。 - schemacs
4
你能告诉我 Linux 的替代品是什么吗? - Visruth
显示剩余8条评论

20

我使用一款叫做Navicat的软件来完成以下任务:

  • 将线上数据库同步到我的测试数据库。
  • 展示这两个数据库之间的差异。

这款软件需要付费,仅支持Windows和Mac系统,并且它的用户界面有点奇特,但是我很喜欢它。


它可以在Linux上运行。我现在在另一个桌面上打开它。结构同步功能可以将模式更改从开发->测试->生产环境推送,这一点就足以抵消许可费用了。 - Colonel Sponsz
2
很好的发现,我甚至不知道它有这些功能。到目前为止,这是Mac上最好的东西。 - O.O
似乎它只比较存在服务器上的数据库,而不是本地SQL文件。 - AlxVallejo
@seanyboy,为什么你喜欢这种古怪的用户界面? - Pacerier

17

SQLyog(商业版)中有一个模式同步工具,可以生成用于同步两个数据库的SQL语句。

enter image description here


1
是的,这对我来说是目前最好的解决方案,提供了精细的SQL同步查询,以便您随时随地更新它。 - Anupam
过于昂贵和笨重,不适合事后修补。 - zanlok
1
非常慢,而且出于某种原因,即使不需要,它也会频繁地删除和重新创建许多外键。没有办法跟踪进度。 - Artem Goutsoul

13

当然有很多方法,但在我的情况下,我更喜欢使用dump和diff命令。因此,这是一个基于Jared评论的脚本:

#!/bin/sh

echo "Usage: dbdiff [user1:pass1@dbname1] [user2:pass2@dbname2] [ignore_table1:ignore_table2...]"

dump () {
  up=${1%%@*}; user=${up%%:*}; pass=${up##*:}; dbname=${1##*@};
  mysqldump --opt --compact --skip-extended-insert -u $user -p$pass $dbname $table > $2
}

rm -f /tmp/db.diff

# Compare
up=${1%%@*}; user=${up%%:*}; pass=${up##*:}; dbname=${1##*@};
for table in `mysql -u $user -p$pass $dbname -N -e "show tables" --batch`; do
  if [ "`echo $3 | grep $table`" = "" ]; then
    echo "Comparing '$table'..."
    dump $1 /tmp/file1.sql
    dump $2 /tmp/file2.sql
    diff -up /tmp/file1.sql /tmp/file2.sql >> /tmp/db.diff
  else
    echo "Ignored '$table'..."
  fi
done
less /tmp/db.diff
rm -f /tmp/file1.sql /tmp/file2.sql

欢迎提供反馈 :)


13

从特性比较列表中可以看出,MySQL Workbench在其社区版中提供了模式比较和模式同步功能。


7
非常好用!而且是免费的,谢谢。对于那些找不到它的人(比如我),它在这里:数据库 -> 反向工程 -> 在 MySQL 模型或 EER 图中 -> 数据库 -> 与任何来源同步。 - bentzy
它的工作效果很好。但是你只能比较同名的数据库。我有多个(多租户客户端)数据库,我想从同一主机上的“主”版本进行同步。因此,在同步之前,我必须将主数据库重命名为与每个客户端数据库匹配。否则很不错! - scipilot
更多关于此的信息可以在这个链接上找到。 - Steven Ryssaert

12

dbSolo是一款收费软件,但它可能是您在寻找的功能。

http://www.dbsolo.com/help/compare.html

它可以与Oracle、Microsoft SQL Server、Sybase、DB2、Solid、PostgreSQL、H2和MySQL配合使用。

alt text


11
如果您只需要比较模式(而不是数据),并且可以访问Perl,则可能可以使用mysqldiff。我已经使用过它,因为它允许您比较本地数据库和远程数据库(通过SSH),因此您不需要麻烦转储任何数据。

http://adamspiers.org/computing/mysqldiff/

它将尝试生成SQL查询以同步两个数据库,但我不信任它(或任何工具,实际上)。据我所知,没有100%可靠的方法来逆向工程需要将一个数据库模式转换为另一个数据库模式的更改,特别是当进行了多个更改时。例如,如果只更改列的类型,则自动化工具可以轻松猜测如何重新创建该列。但是,如果您还移动列,重命名它并添加或删除其他列,则任何软件包最好的做法就是猜测可能发生了什么。并且您可能会丢失数据。我建议跟踪您对开发服务器所做的任何模式更改,然后在实时服务器上手动运行这些语句(或将其整合到升级脚本或迁移中)。这更加繁琐,但它将保护您的数据安全。并且当您开始允许最终用户访问您的站点时,您真的会不断地进行重大数据库更改吗?

不要忘记同时提供 --hostN--userN,否则它会悄无声息地失败。 - Markus Hedlund
我在使用Oracle的mysqldbcompare工具时遇到了一些问题,它会在索引上生成错误,并更改等效的字段。而mysqldiff工具则完美地运行,并节省了很多时间。 - Robert K

7

+1 正是我所需要的。 - Juan Garcia

6

检查:http://schemasync.org/

schemasync工具对我很有用,它是一个命令行工具,在Linux命令行中易于使用。


1
如果您在Mac上安装时遇到问题,我只能通过使用Homebrew安装MySQL和Python来解决,而MacPorts则无法解决。 - Bijou Trouvaille

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接