大表的TSQL校验和

时间:2018-08-10 16:19:22

标签: sql-server tsql compare sql-server-2014 large-data

这是我的问题的修改后的描述:

我遇到的一种情况是我一直试图解决,但遇到了困难,并希望有不同的想法。

场景:数据文件在发生时从多个商店(交易)传输到总部。对于每个商店,表的大小都不错。在总部,同一张桌子包含来自所有商店的相同信息,因此非常庞大。 HO和商店之间没有任何直接连接,因此数据通过文件传输。

我正试图找到一种方法来确保每个商店的数据都能安全地传递到总公司的桌子上。为此,我尝试对存储区和HO之间的字段进行校验和的checksum_AGG。但是性能很差。我还尝试了特定数字列的总和,并在主机上对特定商店进行了相同的操作以进行比较,但性能似乎也很差。

我已经验证了索引的碎片,一切都很好。

理想情况下,我希望逐行传输商店中的所有数据,并将其与HO进行比较,但这是不可想象的,因为它会变得很大。

我正在寻找可以探索的想法,看看性能是否可以接受。这个想法是要在商店的每个日期(商店/日期)获取某种类型的表校验和,并在HO处执行相同的操作...然后比较这两个值...这意味着我只需要将每个商店和日期的校验和值传输到HO。

任何想法都值得赞赏。

谢谢

1 个答案:

答案 0 :(得分:1)

为了比较行,我使用HASHBYTES。对于整个表,您可以使用HASHBYTES行哈希。

您需要这样的东西:

HASHBYTES('SHA2_512', CONCAT([ColA], [ColB], ..., ColZ]);

一些重要说明:

  1. 您正在使用SQL Server 2014,正如文档中所述,不允许使用MAX值作为输入:

      

    对于SQL Server 2014(12.x)和更早版本,允许的输入值限制为8000个字节。

    因此,您可能会为行添加多个散列(在零件上组合不同的列),或者如果您使用max个长度类型,则将无法使用此技术。

  2. 您需要确定如何处理NULL值和空字符串(如果存在)。

    例如,以下散列是相同的,但是我们的假想列之一是NULL,而另一列是empty string

    SELECT HASHBYTES('SHA2_512', CONCAT(1, '', NULL, '')); --0x4DFF4EA340F0A823F15D3F4F01AB62EAE0E5DA579CCB851F8DB9DFE84C58B2B37B89903A740E1EE172DA793A6E79D560E5F7F9BD058A12A280433ED6FA46510A
    SELECT HASHBYTES('SHA2_512', CONCAT(1, '', '', ''));  --0x4DFF4EA340F0A823F15D3F4F01AB62EAE0E5DA579CCB851F8DB9DFE84C58B2B37B89903A740E1EE172DA793A6E79D560E5F7F9BD058A12A280433ED6FA46510A
    

    如果不小心,事情可能会发疯。例如,我有这样的情况(不同的列值,相同的哈希):

    SELECT HASHBYTES('SHA2_512', CONCAT(1, '', NULL, 2));  --0x5AADB45520DCD8726B2822A7A78BB53D794F557199D5D4ABDEDD2C55A4BD6CA73607605C558DE3DB80C8E86C3196484566163ED1327E82E8B6757D1932113CB8
    SELECT HASHBYTES('SHA2_512', CONCAT(1, '', 2, NULL));  --0x5AADB45520DCD8726B2822A7A78BB53D794F557199D5D4ABDEDD2C55A4BD6CA73607605C558DE3DB80C8E86C3196484566163ED1327E82E8B6757D1932113CB8
    

    这就是为什么最终在每个值之间使用分隔符。我正在使用CHAR(26),但是只要您确定数据中没有使用特殊的chars,就可以使用任何非特殊的this。因此,最终的代码是:

    HASHBYTES('SHA2_512', CONCAT([ColA], CHAR(26), [ColB], CHAR(26), ..., CHAR(26), ColZ]);
    

基本上,您可以寻找根据整个结果集的CLR计算的hash函数-实施起来会更加困难,但是如果您熟悉.net可以查看创建SQL CLR函数和官方docsenter image description here示例。


可能很难设置,但是我正在使用Data Checksum来创建单元测试。基本上,这种类型的测试是内置的,因此在环境准备就绪后,您可以使用它:

tSQLt

不好的是,您需要先计算校验和(例如,使用源数据),然后更改SQL以查询新数据。不要以为它会非常适合您的需求。

关于单元测试,您可以检查这个框架{{3}}-我绝对不是一个狂热者,但是可能会有一些例程对结果集执行checksum