我可以使用字段哈希而不是直接字段比较来简化记录的比较吗?

时间:2012-02-08 20:21:13

标签: sql-server ssis

我在4个数据源之间进行整合:

InternalDeviceRepository
ExternalDeviceRepository
NightlyDeviceDeltas
MidDayDeviceDeltas

从其他三个来源更改流入 InternalDeviceRepository 。 最终所有来源都被转换为

的定义
FIELDS
=============
IdentityField
Contract
ContractLevel
StartDate
EndDate
ContractStatus
Location

IdentityField是PrimaryKey,只有匹配时,Contract Key才是辅助密钥,否则需要创建新记录。

目前,我比较了SQL语句中WHERE子句中的所有字段,以及SSIS包中的许多位置。这会创建一些看起来不干净的SQL和SSIS包。

我一直在考虑计算ContractLevel,StartDate,EndDate,ContractStatus和Location的哈希值,并将其添加到每个输入表中。这将允许我使用单个值进行比较,而不是每次使用5个单独的值。

我以前从未这样做过,也没看过它。是否应该使用它,或者是一种更清洁的方式来做它?

1 个答案:

答案 0 :(得分:1)

这是一种有效的方法。考虑引入一个带有哈希和索引的计算字段。

您可以使用CHECKSUM函数或编写自己的哈希函数,如下所示:

CREATE FUNCTION dbo.GetMyLongHash(@data VARBINARY(MAX))
RETURNS VARBINARY(MAX)
WITH RETURNS NULL ON NULL INPUT
AS
BEGIN
    DECLARE @res VARBINARY(MAX) = 0x
    DECLARE @position INT = 1, @len INT = DATALENGTH(@data)

    WHILE 1 = 1
    BEGIN
        SET @res = @res + HASHBYTES('MD5', SUBSTRING(@data, @position, 8000))
        SET @position = @position+8000
        IF @Position > @len 
          BREAK
    END
    WHILE DATALENGTH(@res) > 16 SET @res= dbo.GetMyLongHash(@res)
    RETURN @res
END

它将为您提供16字节值 - 您可以将所有16个字节作为Guid,或者只将前8个字节作为bigint并进行比较。

以您的方式调整函数 - 接受字符串作为参数甚至所有字段而不是varbinary

<强> BUT

  • 小心字符串大小写,日期时间格式
  • 如果使用CHECKSUM - 还要检查其他字段,校验和会生成dublicates
  • 避免在相对较大的表上使用4字节哈希结果