如何验证两个表是否具有完全相同的数据?

时间:2010-01-25 01:37:09

标签: mysql sql

基本上,我们有一个表(original table),它被备份到另一个表(backup table);因此这两个表具有完全相同的模式。

在开始时,两个表(original tablebackup table)包含完全相同的数据集。由于某种原因,经过一段时间后,我需要验证original table中的数据集是否已更改。

为了做到这一点,我必须将original table中的数据集与backup table进行比较。

假设original table具有以下架构:

create table LemmasMapping (
   lemma1 int,
   lemma2 int,
   index ix_lemma1 using btree (lemma1),
   index ix_lemma2 using btree (lemma2)
)

我如何实现数据集比较?

更新:该表没有主键。它只是存储两个ID之间的映射。

9 个答案:

答案 0 :(得分:32)

您可以使用CHECKSUM TABLE并比较结果。您甚至可以alter the table启用实时校验和,以便它们可以持续可用。

CHECKSUM TABLE original_table, backup_table;

它不要求表具有主键。

答案 1 :(得分:19)

SELECT * FROM Table1
UNION
SELECT * FROM Table2

如果您获得的记录大于两个表中的任何一个,则它们没有相同的数据。

答案 2 :(得分:16)

我会写三个查询。

  1. 内部联接以获取两个表中存在主键的行,但其中一个或多个列的值存在差异。这将获取原始的更改行。

  2. 左外连接用于获取原始表中的行,但不包括备份表中的行(即原始行中的行具有备份中不存在的主键)。这将返回插入原始行的行。

  3. 右外连接,用于拾取原始中不再存在的备份行。这将返回已从原始文件中删除的行。

  4. 您可以将三个查询合并在一起以返回单个结果集。如果你这样做,你需要添加一个列来指示它是什么类型的行(更新,插入或删除)。

    通过一些努力,您可以使用完全外部联接在一个查询中执行此操作。注意外连接,因为它们在不同的SQL引擎中表现不同。放在where子句中的谓词,而不是join子句有时可以将外连接转换为内连接。

答案 3 :(得分:1)

select count(*) 
from lemmas as original_table 
      full join backup_table using (lemma_id)
where backup_table.lemma_id is null
      or original_table.lemma_id is null
      or original_table.lemma != backup_table.lemma

null的完整联接/检查应该包括添加或删除以及更改。

  • backup.id为null = addition
  • original.id为null =删除
  • 既不是null =更改

答案 4 :(得分:1)

尝试以下方法比较两个表:

SELECT 'different' FROM DUAL WHERE EXISTS(
    SELECT * FROM (
        SELECT /*DISTINCT*/ +1 AS chk,a.c1,a.c2,a.c3 FROM a
        UNION ALL
        SELECT /*DISTINCT*/ +1 AS chk,b.c1,b.c2,b.c3 FROM b
    ) c
    GROUP BY c1,c2,c3
    HAVING SUM(chk)<>2
)
UNION SELECT 'equal' FROM DUAL
LIMIT 1;

答案 5 :(得分:0)

对于使用MS SQL Server的懒惰或更厌恶SQL的开发人员,我建议使用SQL Delta(www.sqldelta.com)进行此操作以及任何其他数据库差异类型的工作。它具有出色的GUI,快速准确,可以区分所有数据库对象,生成并运行必要的更改脚本,同步整个数据库。这是DBA的下一个最好的事情; - )

我认为RedGate提供了一个名为SQL Compare的类似工具。我相信最新版Visual Studio(2010)的一些版本也包含了一个非常相似的工具。

答案 6 :(得分:0)

请尝试使用以下方法确定两个表是否完全相同,当没有任何类型的主键且表中没有重复的行时,使用以下逻辑:

第1步 - 测试TABLEA上的重复行

如果SELECT DISTINCT * FROM TABLEA

具有相同的行数

SELECT * FROM TABLEA

然后转到下一步,否则您无法使用此方法...

第2步 - 测试TABLEB上的重复行

如果SELECT DISTINCT * FROM TABLEB

具有相同的行数

SELECT * FROM TABLEB

然后转到下一步,否则您无法使用此方法...

第3步 - 在每列上INNER JOIN TABLEA到TABLEB

如果以下查询的行数与步骤1和2中的行数相同,则表格相同:

SELECT
*

FROM
TABLEA

INNER JOIN TABLEA ON
TABLEA.column1 = TABLEB.column1
AND TABLEA.column2 = TABLEB.column2
AND TABLEA.column3 = TABLEB.column3 
--etc...for every column

请注意,此方法不一定会测试不同的数据类型,并且可能无法处理不可连接的数据类型(如VARBINARY)

欢迎反馈!

答案 7 :(得分:0)

1:表C1和C2的首次获取计数。 C1和C2应该相等。 C1和C2可以从以下查询中获取

 select count(*) from table1

如果C1和C2不相等,则表不相同。

2:查找表DC1和DC2的不同计数。 DC1和DC2应该相等。可以使用以下查询找到不同记录的数量:

select count(*) from (select distinct * from table1)

如果DC1和DC2不相等,则表不相同。

3:现在获得通过对2个表执行联合获得的记录数。使其成为U。使用以下查询获取2个表的并集中的记录数:

 SELECT count (*)
 FROM 
    (SELECT *
    FROM table1
    UNION
    SELECT *
    FROM table2)

如果两个表的不同计数等于通过执行两个表的并集获得的记录数,则可以说两个表中的数据相同。即 DC1 = U,DC2 = U

答案 8 :(得分:0)

但是,您也可以在 SQL Server 中使用“Except”关键字。

SELECT Col1, Col2, Col3, Col4, Col5 FROM Table_1
EXCEPT
SELECT Col1, Col2, Col3, Col4, Col5 FROM Table_2

如果查询返回任何行:它们不相同。

如果查询没有返回任何行:它们是相同的。