SQLSERVER中如何快速比较两张表的不一样
2016-06-06 20:08
330 查看
一般来说,如何检测两张表的内容是否一致,体现在复制的时候发布端和订阅端的两端的数据上面
我这里罗列了一些如何从数据库层面来解决此类问题的方法
第一步当然就是检查记录数是否一致,否则不用想其他方法了~
这里我们用两张表t1_old,t1_new来演示
方法介绍
方法一:老老实实看表结构和表记录数,弊端是根本看不到两张表的数据是否一致,只是看到表结构和记录数是否一致
方法二:加法去重 union 运算符排除重复的,但是有bug,在某些情形下不能简单表示结果集一致,相当于无效
由于Union 本身具备把上下两条连接的记录做唯一性排序,所以这样检测起来比较简单
两表数据
查询出来的结果是4
方法三:EXCEPT 减法归零
这里检测出来结果不对,那么就直接给出不一致的结论
方法四:用全表INNER JOIN,这个也是最烂的做法,当然这里指的是在表记录数超级多的情况下
[b]方法五:借助SQLSERVER自带的tablediff工具,当初微软制作这个工具的目的就是用于比较复制中发布表和订阅表的数据一致
identical是相等的意思
方法六:借助发布端的验证订阅功能,验证订阅端跟发布端的数据是否一致
方法七:用checksum校验,比较两张表里的内容的checksum值是否一致
但是这种方法也只局限于两表结构一摸一样
我把[t1_new]表的数据复制到一张新的表以便进行比较
总结
从上面几种数据库提供的方法来看,用EXCEPT减法来归零相对来说比较可靠,其他的方法比较适合在特定的情形下来检测
如有不对的地方,欢迎大家拍砖o(∩_∩)o
[b]本文版权归作者所有,未经作者同意不得转载。[/b]
我这里罗列了一些如何从数据库层面来解决此类问题的方法
第一步当然就是检查记录数是否一致,否则不用想其他方法了~
这里我们用两张表t1_old,t1_new来演示
方法介绍
方法一:老老实实看表结构和表记录数,弊端是根本看不到两张表的数据是否一致,只是看到表结构和记录数是否一致
--表结构: CREATE TABLE t1_old ( id int NOT NULL, log_time DATETIME DEFAULT '' ) ; CREATE TABLE t1_new ( id int NOT NULL, log_time DATETIME DEFAULT '' ) ; --两表的记录数都为100条。 select count(*) from t1_old; select count(*) from t1_new;
方法二:加法去重 union 运算符排除重复的,但是有bug,在某些情形下不能简单表示结果集一致,相当于无效
由于Union 本身具备把上下两条连接的记录做唯一性排序,所以这样检测起来比较简单
SELECT COUNT(*) FROM ( SELECT * FROM [t1_old] UNION SELECT * FROM [t1_new] ) AS T; INSERT INTO [dbo].[t1_new] ( [id],[log_time] ) VALUES(1,''),(3,''),(4,'') INSERT INTO [dbo].[t1_old] ( [id],[log_time] ) VALUES(1,''),(2,''),(3,'') SELECT * FROM [dbo].[t1_new] SELECT * FROM [dbo].[t1_old] SELECT COUNT(*) FROM ( SELECT * FROM [t1_new] UNION SELECT * FROM [t1_old] ) AS T;
两表数据
查询出来的结果是4
方法三:EXCEPT 减法归零
SELECT COUNT(*) FROM ( SELECT * FROM [dbo].[t1_new] EXCEPT SELECT * FROM [dbo].[t1_old] ) AS T; SELECT COUNT(*) FROM ( SELECT * FROM [dbo].[t1_old] EXCEPT SELECT * FROM [dbo].[t1_new] ) AS T; SELECT * FROM [dbo].[t1_new] SELECT * FROM [dbo].[t1_old]
这里检测出来结果不对,那么就直接给出不一致的结论
方法四:用全表INNER JOIN,这个也是最烂的做法,当然这里指的是在表记录数超级多的情况下
DECLARE @t1_newcount BIGINT DECLARE @count BIGINT SELECT @t1_newcount = COUNT(*) FROM t1_new; SELECT @count = COUNT(*) FROM [t1_old] AS a INNER JOIN [t1_new] AS b ON .[id] = [a].[id] AND [b].[log_time] = [a].[log_time] --如果表中还有其他字段的自行添加 PRINT @count PRINT @t1_newcount IF ( @count = @t1_newcount ) BEGIN SELECT 'equal' END ELSE BEGIN SELECT 'not equal' END
[b]方法五:借助SQLSERVER自带的tablediff工具,当初微软制作这个工具的目的就是用于比较复制中发布表和订阅表的数据一致
identical是相等的意思
方法六:借助发布端的验证订阅功能,验证订阅端跟发布端的数据是否一致
方法七:用checksum校验,比较两张表里的内容的checksum值是否一致
但是这种方法也只局限于两表结构一摸一样
我把[t1_new]表的数据复制到一张新的表以便进行比较
SELECT * FROM [dbo].[t1_new] SELECT * FROM [dbo].[t1_newreplica] SELECT SUM(CHECKSUM(*)) AS checksumvalue FROM [dbo].[t1_old] SELECT SUM(CHECKSUM(*)) AS checksumvalue FROM [dbo].[t1_new] SELECT SUM(CHECKSUM(*)) AS checksumvalue FROM [dbo].[t1_newreplica]
总结
从上面几种数据库提供的方法来看,用EXCEPT减法来归零相对来说比较可靠,其他的方法比较适合在特定的情形下来检测
如有不对的地方,欢迎大家拍砖o(∩_∩)o
[b]本文版权归作者所有,未经作者同意不得转载。[/b]
相关文章推荐
- jdbc链接数据库操作
- memcached全面剖析–3. memcached的删除机制和发展方向
- memcached全面剖析–2. 理解memcached的内存存储
- memcached完全剖析–1. memcached的基础
- 彻底搞懂Oracle的左外连接和右外连接(以数据说话)
- memcached全面剖析--2.理解memcached的内存存储
- mysql大于等于号
- 一份word让你掌握mysql数据库,史上最全
- 分页查询(二)——用sql与linq查询
- sqlcmd命令导入大容量的SQL本地文件至SQL server 2008
- SQL server 2008数据库的备份与还原(转)
- 数据库还原失败System.Data.SqlClient.SqlError: 无法执行 BACKUP LOG,因为当前没有数据库备份
- 简单理解Memcached的Slab Allocation
- Memcached 及 Redis 架构分析和比较
- 数据库技术分享
- MySQL备份锁
- Ubuntu 安装mysql和简单操作
- JDBC结合MySql完成增删改查
- NoSQL之Redis---SortSet类型命令
- 存储过程测试流程--以MySQL为例