MySQL如何对比两个表数据的异同可以用语句快速过滤select * from 人员表 where 姓名 not in (select 姓名 from 出勤表)
mysql如何实现两个表的数据差异查询查询两张表数据不一致的记录 , 可以用求差集(非交集)的办法来解决 。
SQL语言求"差集"的办法相对于求"交集"的办法要少很多,一般可用not exists(非存在子句)或 左(右)连接后所产生空字段值来筛选两表的差集 。
下面举个例子供参考
选出a表中与b表中id不一致的记录
selecta.* from a where not exists (select 1 from b where b.id=c.id);
说明:上述语句只比对id一个字段,我们可以根据需要比对多个字段 。not exists在比对字段有可利用的索引时,其运行效率是非常高,但是如果没有索引的情况下运行在大数据表时,其运行效率极差,这时应避免使用它,这时我们可改用左(右)连接来求差集 。
下面是用左连接来求差集的例子:
1
select a.* from a left join b on a.id=b.id where b.id is null;
用左(右)连接来求差集,由于需要实施两表连接会导致笛卡尔效应其输出集的记录行可能会增多,若果不是一对一或一对多 , 我们应该将多对多的情况处理成多对一后才进行连接,否则输出的记录集可能不正确 。
求差集的两种方法,有索引可利用时,not exists的效率要高于left join,反之left join效率更好 。
技术分享 | 两个单机 MySQL 该如何校验数据一致性业务有两个 MySQL 集群是通过 MQ 进行同步的,昨晚 MQ 出现异常,报了很多主键冲突,想请 dba 帮忙校验一下两个集群的数据是否一致 。
当接到这个需求的时候并没当回事,隐约有点印象 pt-table-checksum 能通过 dsn 实现 MySQL 的数据校验 , 所以当时就应承下来了 。不曾想 , 啪啪打脸,回想起来真是草率了 。
本文参考的是 pt-table-checksum 的校验逻辑,基于数据块去遍历每个表,然后比对 checksum 的值判断该块是否一致,本文主要是想聊聊我在实现数据校验脚本过程中遇到的问题以及解决思路,希望对大家有帮助 。
利用线上的配置文件搭建一套主从环境 。
这个用例将通过 dsn 方式连接从库 。
这个用例将通过 dsn 方式连接从库 , 但是会将从库的复制链路 stop 掉,并清空复制信息 。
熟悉 pt-table-checksum 的朋友应该都知道,该工具是基于主键(非空唯一键)进行扫描数据行,其实这个逻辑针对整型单列主键实现起来很简单 , 但是如果是联合主键且是字符型,好像就没那么简单了,有兴趣的可以思考一下 。下面我先说一下大致的逻辑:
第一步:判断 _min_rowid 是否为空 , 为空就取该表的第一行,并记作 _min_rowid。
第二步:根据 _min_rowid 作为条件进行扫描该表 , 取下一个数据块的数据,记录数据块的最后一行数据的主键值,记录 checksum 的值,并记下 _min_rowid。
第三步:判断_min_rowid是否为空 , 非空重复第二步 , 为空退出检查 。
通过上述三个步骤可以看到,如果是单列整型的主键,实现起来很简单,但是问题来了,业务的表的主键五花八门,有的是联合主键,有的是字符型的联合主键,还有整型 字符型的联合主键,那么上述的实现方式显然是有问题的 。所以实现起来需要多考虑几个问题:
鉴于存在上述两个问题,可以参考如下实现逻辑:
假如有这么一个联合主键字段 primary key(a,b,c) 都是整型,该如何编写遍历 sql 呢?起初我的想法很简单 , 具体如下:
至此在编写校验脚本过程遇到的两个问题就算告一段落了,剩下的就是各种逻辑处理了,不过多赘述,有兴趣的可以自行阅读脚本文件 。
本着最低程度影响业务,所以取消加锁逻辑 。但是又要保证该数据块的数据一致性,如果这个数据块是个热数据,当前正在变更 , 那么校验的时候难免会不一致 。所以只能通过多次校验实现,默认是校验20次,其中有一次校验结果是一致,就认为是一致的,如果前5次校验过程中,这个数据块的数据没有变化,也视为不一致(可能是因为延迟 , 也可能是真的不一致) 。
pt-table-checksum 不校验表结构,改写时添加表结构的校验 。
可以基于表的并行校验,可由用户指定并行数,但是脚本有个安全机制,如果用户指定的并行数大于当前 cpu 空闲核心数,就会按当前(空闲核心数-1)作为并行数 。
添加网络监控,由用户指定网络上限百分比,当网卡流量超过这个百分比就暂停任务,等待网卡流量低于阈值才会继续任务 。这个主要是出于对于中间件(mycat)的场景或者分布式数据库(tidb)的场景 。
支持定时任务功能,用户可以使用这个功能规避业务高峰,仅在业务低峰进行数据校验 。
不仅限于主从节点的校验,只要目标对象支持 MySQL 的标准 SQL 语法就能做数据校验 。
校验逻辑是通过 SQL 采集目标节点的数据库,如果目标数据库系统当前存在异常,无疑是雪上加霜,将会触发未知问题,所以添加超时机制,单次取数据块的阈值是5s,超过5秒就放弃等待重试 。测试发现 , 有时候即便触发超时了,但是 SQL 任务还是会在目标数据库的 processlist 中能看到,所以又添加了一个 kill 机制,超时后会触发一个 kill processlist id 的动作 。另外为了避免 kill 错,在每个 SQL 对象添加了一个32位的 md5 值,每次 kill 的时候会校验这个 md5 值 。
本工具借鉴 pt-table-checksum 工具思路改写,可以检查随意两个 mysql(支持 mysql sql 语法的数据库)节点的数据一致性 。
基于主键以一个块遍历数据表,比对checksum的值,块的大小可通过参数指定 。(1)获取该表的第一个数据块的查询SQL 。(2)将两个目标节点的数据块的checksum的值,记录到临时文件,file1 file2 。(3)比对file1 file2是否一致 。
第一步:先开启一个 screen 监控网络
第二步:新开启一个screen执行校验任务
(1)info.log 文件
(2)list目录
(3)md5 目录
(4)pri 目录
(5)res 目录
这是 table 目录下记录某个数据块不一致的一个例子
这是 diff 目录下记录某个数据行不一致的一个例子
(6)skip.log 文件
本工具是参考了 pt-table-checksum 工具的一些思路并结合自身经验进行改写,尚有很多不足之处,仅做学习交流之用,如有线上环境使用需求,请在测试环境充分测试 。
如何比较mysql数据库的表结构和表内容的差异先把每个库mysql两个表怎么比对的表结构导出到文件mysql两个表怎么比对,然后比较这两个文件 。
mysqldump --skip-comments --skip-extended-insert -u root -p database1file1.sql
mysqldump --skip-comments --skip-extended-insert -u root -p database2file2.sql
diff file1.sql file2.sql
其实还有一些比较工具mysql两个表怎么比对,推荐一个
mysql-comparison-tools
【mysql两个表怎么比对 mysql如何将两个表的数据连起来】mysql两个表怎么比对的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于mysql如何将两个表的数据连起来、mysql两个表怎么比对的信息别忘了在本站进行查找喔 。
推荐阅读
- 电脑u盘四合一系统怎么用,u盘怎么安装四个pe
- 汕头网站搭建服务平台,汕头网站建设平台
- redis自动删除,redis数据自动删除
- php操作数据库实训 php操作数据库实验心得
- oracle中如何彻底删除表中某些记录,oracle中如何彻底删除表中某些记录内容
- 手机壁纸潮湿怎么处理,手机壁纸潮湿怎么处理好
- 区块链和特斯拉哪个好,一句话解释区块链和比特币
- mysql中怎么查看用户 mysql怎么查看用户属性
- java的倒序的代码,java中倒序