怎样从数据库层面检測两表内容的一致性

一般来说呢。怎样检測两张表的内容是否一致,这种需求大多在从机上体现,以保证数据一致性。方法无非有两个,第一呢就是从数据库着手。第二呢就是从应用程序端着手。

我这里罗列了些怎样从数据库层面来解决此类问题的方法。
当然第一步就是检查记录数是否一致,否则不用想不论什么其它方法了。
这里我们用两张表t1_old,t1_new来演示。

表结构:
 CREATE TABLE t1_old (
  id int(11) NOT NULL,
  log_time timestamp DEFAULT NULL
) ;

 CREATE TABLE t1_new (
  id int(11) NOT NULL,
  log_time timestamp DEFAULT NULL
) ;

两表的记录数都为100条。
mysql> select count(*) from t1_old;
+----------+
| count(*) |
+----------+
|      100 |
+----------+
1 row in set (0.31 sec)

mysql> select count(*) from t1_new;
+----------+
| count(*) |
+----------+
|      100 |
+----------+
1 row in set (0.00 sec)

方法一:用加法然后去重。

因为Union 本身具备把上下两条连接的记录做唯一性排序,所以这样检測来的很easy。
mysql> select count(*) from (select * from t1_old union select * from t1_new) as T;
+----------+
| count(*) |
+----------+
|      100 |
+----------+
1 row in set (0.06 sec)
这里的记录数为100,初步证明两表内容一致。可是,这种方法有个BUG,在某些情形下不能简单表示结果集一致。

比方:

mysql> create table t1_old1 (id int);
Query OK, 0 rows affected (0.27 sec)

mysql> create table t1_new1(id int);
Query OK, 0 rows affected (0.09 sec)

mysql> insert into t1_old1 values (1),(2),(3),(5);
Query OK, 4 rows affected (0.15 sec)
Records: 4  Duplicates: 0  Warnings: 0

mysql> insert into t1_new1 values (2),(2),(3),(5);
Query OK, 4 rows affected (0.02 sec)
Records: 4  Duplicates: 0  Warnings: 0

mysql> select * from t1_old1;
+------+
| id   |
+------+
|    1 |
|    2 |
|    3 |
|    5 |
+------+
4 rows in set (0.00 sec)

mysql> select * from t1_new1;
+------+
| id   |
+------+
|    2 |
|    2 |
|    3 |
|    5 |
+------+
4 rows in set (0.00 sec)

mysql> select count(*) from (select * from t1_old1 union select * from t1_new1) as T;
+----------+
| count(*) |
+----------+
|        4 |
+----------+
1 row in set (0.00 sec)

mysql>
所以在这点上。这种方法等于是无效。

方法二: 用减法来归零。

因为MySQL 没有提供减法操作符。这里我们换做PostgreSQL来检測。

t_girl=# select count(*) from (select * from t1_old except select * from t1_new) as T;
 count
-------
     0
(1 row)

Time: 1.809 ms
这里检測出来结果是0。那么证明两表的内容一致。 那么我们能够针对第一种方法提到的第二种情况做检測:
t_girl=# select count(*) from (select * from t1_old1 except select * from t1_new1) as T;
 count
-------
     1
(1 row)

Time: 9.837 ms
OK,这里检測出来结果不正确,那么就直接给出不一致的结论。

第三种: 用全表JOIN,这个也是最烂的做法了,当然我这里指的是在表记录数超级多的情形下。

当然这点我也用PostgreSQL来演示
t_girl=# select count(*) from t1_old as a full outer join t1_new as b using (id,log_time) where a.id is null or b.id is null;
 count
-------
     0
(1 row)

Time: 5.002 ms
t_girl=#
结果为0,证明内容一致。


第四种: 用checksum校验。

比方在MySQL 里面。假设两张表的checksum值一致,那么内容也就一致。

mysql> checksum table t1_old;
+---------------+----------+
| Table         | Checksum |
+---------------+----------+
| t_girl.t1_old | 60614552 |
+---------------+----------+
1 row in set (0.00 sec)

mysql> checksum table t1_new;
+---------------+----------+
| Table         | Checksum |
+---------------+----------+
| t_girl.t1_new | 60614552 |
+---------------+----------+
1 row in set (0.00 sec)

可是这种方法也仅仅局限于两表结构一摸一样。 比方,我改动下表t1_old的字段类型,那么checksum的值也就不一样了。

mysql> alter table t1_old modify id bigint;
Query OK, 100 rows affected (0.23 sec)
Records: 100  Duplicates: 0  Warnings: 0

mysql> checksum table t1_old;
+---------------+------------+
| Table         | Checksum   |
+---------------+------------+
| t_girl.t1_old | 3211623989 |
+---------------+------------+
1 row in set (0.00 sec)

mysql> checksum table t1_new;
+---------------+----------+
| Table         | Checksum |
+---------------+----------+
| t_girl.t1_new | 60614552 |
+---------------+----------+
1 row in set (0.00 sec)

所以从上面几种数据库提供的方法来看,用减法来归零相对来说比較可靠,其它的方法比較适合在特定的情形下来检測。

时间: 2024-10-13 07:33:14

怎样从数据库层面检測两表内容的一致性的相关文章

[原创]如何从数据库层面检测两表内容的一致性

一般来说呢,如何检测两张表的内容是否一致,这样的需求大多在从机上体现,以保证数据一致性.方法无非有两个,第一呢就是从数据库着手,第二呢就是从应用程序端着手. 我这里罗列了些如何从数据库层面来解决此类问题的方法. 当然第一步就是检查记录数是否一致,否则不用想任何其他方法了. 这里我们用两张表t1_old,t1_new来演示. 表结构:  CREATE TABLE t1_old (   id int(11) NOT NULL,   log_time timestamp DEFAULT NULL ) 

如何从数据库层面检测两表内容的一致性

一般来说呢,如何检测两张表的内容是否一致,这样的需求大多在从机上体现,以保证数据一致性.方法无非有两个,第一呢就是从数据库着手,第二呢就是从应用程序端着手. 我这里罗列了些如何从数据库层面来解决此类问题的方法.当然第一步就是检查记录数是否一致,否则不用想任何其他方法了.这里我们用两张表t1_old,t1_new来演示. 表结构: CREATE TABLE t1_old ( id int(11) NOT NULL, log_time timestamp DEFAULT NULL ) ; CREAT

【VBA研究】工作表自己主动筛选模式检測

作者:iamlaosong 用VBA程序处理Excel数据文件.用户的数据文件有时处于自己主动筛选模式,往往导致数据处理不对.为此,须要检測工作表是否处于该模式,假设是,则去掉自己主动筛选.语句例如以下: If ActiveSheet.AutoFilterMode = True Then Selection.AutoFilter 这个语句一般仅仅用于去掉自己主动筛选,尽管Selection.AutoFilter也能够加上自己主动筛选,但筛选位置却可能在当前单元格处,所以要注意.加自己主动筛选前,

oracle表结构和表内容差异比对

oracle表结构和表内容差异比对 oracle中有三种集合操作,他们会把左边和右边的select 结果集进行集合操作. union 并集 intersect 交集 minus 差集 假设有如下两张表 STUDENT_A 和 STUDENT_B create table STUDENT_A ( id VARCHAR2(36) not null, name VARCHAR2(100), age NUMBER, sex VARCHAR2(2) ); insert into STUDENT_A (id

MVC5+EF6简单实例---以原有SQLServer数据库两表联合查询为例

工具:VS.net2013.EF6.MVC5.SQLServer2008 参考出处: http://www.cnblogs.com/slark/p/mvc-5-get-started-create-project.html http://www.cnblogs.com/miro/p/4288184.html http://www.cnblogs.com/dotnetmvc/p/3732029.html 一.准备工作 在SqlServer上创建数据库:Element 模拟两个表并插入数据:SysU

每天一个JavaScript实例-检測表单数据

<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>每天一个JavaScript实例-检測表单数据</title> <style> [role="alert"]{ background-color: #f

判断两个数据库中不一样的表和存储过程

---两表结构不一样SELECT a.a1,a.a2,a.a3,a.length from(SELECT a.a1,a.a2,a.a3,a.length, b.a1 AS b1,b.a2 AS b2,b.a3 AS b3,b.length AS b4  from (select o.name AS a1, c.name AS a2,t.name AS a3,c.length from dbf.sys.syscolumns cinner join dbf.sys.systypes t on c.x

YII 两表间和两模块间的数据库查询

这段时间在学YII,虽然Yii做网页挺方便,它的作用也不止这么简单,但对于刚弄的新手来说,要弄会它实在太难,想完成某个功能光想找文档就能让你"疯狂",,,好,废话不多说,下面讲下标题要实现的两个功能:(PS:不知是不是太简单而没人看得起还是怎么,想要实现在网上找文档找到吐都没找到..)我新建了post模块和group模块,有3张表(都在同一个数据库的),post表和posttype表放在post模块里,group表放在group模块里. 好,首先,实现post去查询postType里的

Cocos2d-x3.0游戏实例之《别救我》第七篇——物理世界的碰撞检測

事实上我也非常吃惊-居然写到第七篇了,我估计也就是四篇的内容,感觉非常奇妙,我也不会非常唠叨什么吖(小若:32个喷! ),怎么都到第七篇了. 笨木头花心贡献,啥?花心?不呢,是用心~ 转载请注明,原文地址: http://www.benmutou.com/blog/archives/920 文章来源:笨木头与游戏开发 碰撞监听 首先,确保我们创建物理对象的时候,给对象设置了碰撞条件(假设你是一步步按着教程来写的代码,那就是设置好了): body->setCategoryBitmask(1);