怎么对比两个mysql数据库_[实战]如何对比两个数据库之间的变化

目录

前言

相信很多撸友都曾经接到过下面这样一个工作:

要求对比两个不同版本数据库之间的变化,并对统计该变化对已有系统的影响。

并根据影响,请检索所有现行系统相关的存储过程,作出相应的修改。

或许最终的目的不一定是要统计什么,但前面的准备工作却是一样。也虽然我们确实可以用类似SQL Compare这样的商业软件搞定,但最终会发现被软件绑手绑脚,无法施展开想要的工作。那么就有了下面这么一小段学习的历程。

本文指针对小弟工作中遇到的问题展开,如果有不足之处欢迎补充。

用于查询所有字段的sql语句

SELECT

obj.[name] AS TabName,

col.colorder AS ColOrder,

col.[name] AS ColName,

COLUMNPROPERTY( col.id,col.name, 'IsIdentity' ) AS ColIsIdentity,

(CASE

WHEN (SELECT count(*) FROM sysobjects WHERE ([name] in

(SELECT name FROM sysindexes WHERE (id=col.id) AND (indid in

(SELECT indid FROM sysindexkeys WHERE (id=col.id) AND (colid in

(SELECT colid FROM syscolumns WHERE (id=col.id) AND ([name]=col.[name]))

))))) AND xtype = 'PK') > 0 THEN 1

ELSE 0

END) AS ColIsPK,

t.[name] AS ColType,

col.[length] AS ColLen,

COLUMNPROPERTY(col.id,col.name,'PRECISION' ) AS ColPrecosion,

ISNULL(COLUMNPROPERTY(col.id, col.name, 'Scale' ),0) AS ColScale,

col.isnullable AS IsNullable,

ISNULL(com.text,'') AS ColDefaultValue,

ISNULL(ext.[value],'' ) AS ColDiscription

-- INTO {the database as you like}

FROM syscolumns col

INNER JOIN sysobjects obj ON col.id=obj.id AND obj.xtype='U' AND obj.[name]<>'dtproperties'

LEFT JOIN systypes t ON col.xtype=t.xusertype

LEFT JOIN syscomments com ON col.cdefault=com.id

LEFT JOIN sys.extended_properties ext ON col.id=ext.major_id AND col.colid=ext.minor_id

ORDER BY TabName,ColOrder

用于查询存储过程里是否包含某一关键字的sql语句

select B.name AS OBJECT_NAME, B.TYPE

from sys.all_sql_modules a inner join sys.all_objects b on a.object_id = b.object_id and b.type IN('P', 'F')

where charindex( lower('KEY_WORD'), lower(definition) ) > 0 --and charindex( lower('retrieve'), lower(definition) ) = 0

ORDER BY 1

用于查询Schedule Job里的step是否包含某一关键字的sql语句

select j.name, js.step_name

from msdb..sysjobs j inner join msdb..sysjobsteps js on j.job_id = js.job_id

where j.enabled =1

and charindex('KEY_WORD', js.command) >0

友情提示

本文重点全在上面三段脚本,已经看明白了的那么就请笑一笑忽略下文吧:) 微喷,微喷。

具体实现

有了上面这个基础代码,那么我们就能来搞搞阵了。

Step-1

思路是这样的,既然我们能查询到两个数据库的结构(利用上面这个代码),那么就能利用查询出来的列表来做一下比较了;又由于我们用到的这个第三方库大概有12k+的字段,所以我先把查询出来的列表分别存到两个表PROD1812跟UAT41812里面(单表双表请随意,单表多个字段标识下库名)。

cbb083d42efaaf5856d687f410633174.png

命名上我分别加了p_跟u_开头,个人喜好吧。下面这个工具叫SQL Complete(Lite),一个很小的免费工具,虽然ssms有提供类似功能,但提示效果总感觉不如这个快捷。当然,还有其他更好以及收费工具。

677b7bd2277f7947f02969e757778e71.png

还有就是上面有些信息我自己认为是没必要作为比较的,所以拿掉了。

Step-2

还是先贴代码

SELECT * FROM Prod1812 p

FULL OUTER JOIN UAT41812 u ON p.p_TabName=u.u_TabName AND p.p_ColName=u.u_ColName

WHERE

p.p_ColName IS NULL OR --左边p是空的时候,表示右边u的是新的字段或者重命名过的字段

u.u_ColName IS NULL OR --右边u是空的时候,表示左边p的字段被删除了或者被重命名了

p.p_ColType<>u.u_ColType OR --类型被修改了

p.p_ColLen<>u.u_ColLen OR --长度被修改了

p.p_ColScale<>u.u_ColScale --小数点长度(精度)被修改了

这里说的是什么呢?

首先注意下这里的FULL OUTER JOIN,请暴力地理解为当使用p.p_TabName=u.u_TabName AND p.p_ColName=u.u_ColName这个条件地时候,左边是NULL也要,右边是NULL也要的意思。这里也不需要用到CROSS JOIN。

然后是WHERE里面地条件,可以根据实际情况筛选(还有默认值啊之类的)。

由于我们的系统只是查询这个第三方的数据库,所以本次只需要检查跟SELECT相关的就可以了,类似默认值之类的不在检查列表之内。

4ed00b14462b946c9872a846491edfb0.png

我把上面跑出来的结果继续存进一个表Change1812里,对,空间不用钱,但数据库很累,所以跑一次就记下来。

Step-3

写邮件吹牛逼汇报进度。

对得到的数据放进Excel稍加格式上的处理之后就能出到下面这个效果了,各位技术员朋友们,做到这里赶紧写一封邮件跟老板们汇报下进度吧,不然要吃大亏啦,别问我怎么知道的。搞技术的时候总喜欢埋头苦干,直到出最后结果的时候才汇报,其实那个时候已经太晚了。这次第三方库升级,检查到这一步的时候,发现一共有700+个修改,往大了说,很有可能使毁灭性的升级,往小了说,也有可能压根就没用到几个,毕竟12k+的字段,700+也就是6%不到,何况还可能有重复的。一定要吧把这些count出来的数字列出来,详细的数据只是作为辅助证明自己不只是简单的吹牛逼而已。切记切记。

2332ec485ea0ed687f1facac04bf179c.png

Step-4

继续埋头苦干,这里要用到前面的第二段sql语句了。

目的是为了检索出本地库究竟有多少用到Change1812表里那些那些已经标记被修改了了的字段,得出结果后存进Impact181表里,如果本地库大的话这里其实要跑很久的,简易在Staging里跑,不要在Prod里跑。就不贴详细代码了,核心都在那里了。

43d82a9a3b7301bd6e7110858a1440d6.png

礼物

嗯,其实第三段sql语句是没用到的,当成礼物送给愿意看到最后面的朋友们。:P

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值