Sql server 如何使用校验和之类的哈希字节?

Sql server 如何使用校验和之类的哈希字节?,sql-server,hash,checksum,Sql Server,Hash,Checksum,在SQL server中,我们可以使用“校验和”在整行上轻松生成哈希: 有没有一种方法可以使用hashbytes函数做同样的事情? 比如: select hashbytes('md5', *), * from mytable 如果不反对写出列,您可以简单地连接列并散列: SELECT HASHBYTES('md5', ISNULL(CONVERT(VARBINARY(MAX), column1), 0x) + ISNULL(CONVERT(VARBINARY(MAX

在SQL server中,我们可以使用“校验和”在整行上轻松生成哈希:

有没有一种方法可以使用hashbytes函数做同样的事情? 比如:

select 
hashbytes('md5', *), *    
from mytable

如果不反对写出列,您可以简单地连接列并散列:

SELECT HASHBYTES('md5', 
    ISNULL(CONVERT(VARBINARY(MAX), column1), 0x) +
    ISNULL(CONVERT(VARBINARY(MAX), column2), 0x) + 
    ...
)
从SQL Server 2012开始,我们可以使用
CONCAT
(感谢@MWillemse的提示)更简洁地实现同样的目标:

请注意,如果列“相同”,这可能会导致冲突:哈希
AA、BB、CC
产生与
AAB、BBC、C
或甚至
AABBCC、NULL、NULL
相同的结果。如果这是一个问题,那么您必须设计自己的哈希方案,以最大限度地降低这种可能性(例如,通过在哈希中包含列名)。此外,这是一个二进制校验和:散列
a,B,C
a,B,C
不同。同样,如果这是一个问题,您必须在对数据进行散列之前对其进行调整(
UPPER


最后,MD5不再被认为是加密安全的,因此仅将其用于校验和索引之类的事情,在这种情况下,您需要的冲突概率比使用
校验和
更少。如果您需要一行的加密签名,这太简单了。

恐怕不容易。在大多数情况下,你不应该真的想要。但如果必须这样做,那么为每一行生成一个XML文档并对XML文档进行散列可能是最简单的方法:

SELECT  HASHBYTES('MD5', X.value)
FROM    Data
CROSS APPLY (
    SELECT value = 
        CAST((SELECT Data.* FROM   (SELECT 1) AS X (y) FOR XML AUTO) AS VARCHAR(MAX))
) AS X

EDIT:我做了一些测试,应用
转换(…AS VARCHAR(MAX))
正如我在上面更新的语句中所做的那样,性能提高了约15%。更重要的是,它可以防止宽表上的截断错误。即使在此修复之后,您自己连接列的速度仍将提高约15%。使用CONCAT()(可从MSSQL 2012获得)函数可以简化live,因为您可以省去对每个列应用ISNULL和CAST函数。

聪明,而且它还内置了防止列内容重叠的保护功能。不过,它的性能是否令人满意则是另一回事。在列之间添加一个分隔符可能是值得的,例如“| ~”+1用于使用CONCAT
SELECT HASHBYTES('md5', CONCAT(column1, column2, ...))
SELECT  HASHBYTES('MD5', X.value)
FROM    Data
CROSS APPLY (
    SELECT value = 
        CAST((SELECT Data.* FROM   (SELECT 1) AS X (y) FOR XML AUTO) AS VARCHAR(MAX))
) AS X