【问题标题】:SQL Server - Generate unique ID to compare several columns altogetherSQL Server - 生成唯一 ID 以完全比较几列
【发布时间】:2018-06-20 14:20:05
【问题描述】:

在 SQL Server 中,是否可以使用特定数据作为输入值来生成 GUID。例如,

DECLARE @seed1 VARCHAR(10) = 'Test'
DECLARE @seed1 VARCHAR(10) = 'Testing'
SELECT NEWID(@seed1) -- will always return the same output value
SELECT NEWID(@seed2) -- will always return the same output value, and will be different to the example above

我知道这完全违背了 GUID 的观点,因为 ID 不会是唯一的。我正在寻找一种基于特定标准(@seed 值)检测重复记录的方法。

我尝试使用HASHBYTES 函数生成VARBINARY 字符串,但是使用VARBINARY 在表之间连接似乎非常慢。我希望找到一个更有效的类似替代方案。

编辑:详细了解我为什么要实现这一目标。

我正在寻找一种快速有效的方法来检测两个表上存在的重复信息。例如,我有名字、姓氏和电子邮件。当这些被连接起来时,应该可以用来检查这些记录是否存在于表A和表B中。

可以简单地加入这些字段并提供正确的结果,但是速度很慢。因此,我希望找到一种将数据转换为诸如 GUID 之类的东西的方法,这将使连接更加高效。

【问题讨论】:

  • 您似乎已经决定了做某事的方法,现在正在就如何做某件事寻求帮助。您能否添加一些代表您的情况和所需输出的虚拟数据?很可能有更简单的解决方案可供使用
  • 我正在寻找一种基于特定标准检测重复记录的方法,您能否扩展此要求?这可能是 XY 问题。
  • GUID 实际上是BINARY(16),并且加入的速度也差不多。在散列时,您的 VARBINARY 值最终可能会更大,但这可以通过采用子字符串来“解决”(以增加冲突概率为代价,但这对于正确的加密散列来说不是问题)。如果结果仍然太大/太慢,最好在查找表上使用IDENTITYSEQUENCE,缺点是需要在调用者之间同步,但这通常会被更好的方法所抵消加入 4 字节整数时获得的性能。
  • 现在您已经解释了为什么需要它,我想说 CHECKSUM 或 HASHBYTES 函数正是您所需要的;它们专为您所想的目的而设计。 (请注意,两个不同的项目总和为相同值的可能性很小,因此您可能应该保留原始匹配条件,但只要校验和值被索引并在您的查询中使用以及 , SQL Server 应该足够聪明,可以在进行精确比较之前使用该索引来过滤结果。)从概念上讲,您正在寻找的绝对是“散列”。
  • 如果您只是想加快连接速度,您甚至不需要较短的值是唯一的——只要它们足够唯一来加速索引就足够了搜索(WHERE hash1 = hash2 AND mycolumn1 = mycolumn2,第一部分将允许大部分加速)。即使CHECKSUM 也可以用于此目的,尽管它的碰撞率对于许多真实世界的数据来说是可怕的,你可以使用(比如)CONVERT(INT, SUBSTRING(HASHBYTES(...), 1, 4)) 做得更好。

标签: sql sql-server hash sql-server-2014 guid


【解决方案1】:

我认为您可以使用 CHECKSUM 函数来返回 int 类型。

【讨论】:

  • 我同意你的观点,但我会为 OP 展示一个示例。
  • checksum 为此目的太容易发生冲突。 Microsoft 自己建议不要为此使用checksum
  • 对于我所需要的,CHECKSUM 是理想的选择。我必须在加入时包含其他标准以避免潜在的冲突,但这仍然比加入两个 HASHBYTES 列要快。谢谢!
【解决方案2】:

您应该像这样使用hashbytes 而不是checksum

SELECT hashbytes('MD5', 'JOHN' + ',' + 'SMITH' + ',' + 'JSMITH@EXAMPLE.COM')

虽然只有很小的机会校验和可以产生具有 2 个完全不同的值的相同数字,但我在大约一百万的数据集上遇到过这种情况。正如 iamdave 所指出的(谢谢!),最好使用某种分隔符(在我的示例中为逗号),这样您就不会将 'JOH' + 'NSMITH''JOHN' + 'SMITH' 进行比较。

http://www.sqlservercentral.com/blogs/microsoft-business-intelligence-and-data-warehousing/2012/02/01/checksum-vs-hashbytes/

【讨论】:

  • 嗯,它不是那个小...SELECT CHECKSUM('--a--'), CHECKSUM('a')。除了这种奇怪之外,CHECKSUM 的碰撞率比你可以使用的任何其他东西都差。唯一的可取之处是,只要您的索引不是 UNIQUE(它不应该是,因为那只是自找麻烦),在性能开始显着下降之前,您可能会遭受大量冲突。
  • 值得注意的是,值之间应添加分隔符。 'John' + 'Smith' 将给出与 'Joh' + 'nSmith' 相同的 hashbytes 输出
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-20
  • 2022-09-23
  • 1970-01-01
  • 2014-11-28
  • 2012-02-22
  • 1970-01-01
相关资源
最近更新 更多