【问题标题】:Huge Integer keys in SQL ServerSQL Server 中的大整数键
【发布时间】:2020-08-01 14:48:26
【问题描述】:

我需要创建一个带有 256 位哈希数的键的表。快速搜索和检索至关重要,所以我想知道使用什么数据结构作为键?

一个选项是 varchar[32],但我想搜索会很慢。存储的数据量将远高于数值解。

第二个选项是两个不同的十进制 [16] 整数并将它们组合成一个复合键,但我怀疑这是否会比选项 #1 具有更快的搜索性能。

我搜索了该主题,但没有找到解决方案;也许是第三种选择?任何提示表示赞赏。

【问题讨论】:

  • 如果它是一个哈希,那么它对主键没有好处!主键必须是唯一的,而哈希不是根据定义。您要解决的实际问题是什么?
  • 如果您的 256 位哈希值是自然键,请将其存储为正确的数据类型 binary(32) 并使其成为主键聚集索引以最大限度地提高性能。不过,请考虑@MitchWheat 关于碰撞的评论。另外,race your horses 只是一个猜测,并询问我们对性能的看法。
  • @MitchWheat,感谢您的提示,但老实说:256 位哈希上的冲突?当前的硬盘驱动器没有存储如此多的数据,以至于您和我可能会在我们的一生中看到这样的表发生冲突(如果真的如此,在这种情况下无论如何都无关紧要)。当然,小散列值是正确的。
  • @DanGuzman 感谢您的提示,二进制我没有想到,我将测试所有 3 个选项并测量性能。
  • @MitchWheat,考虑到生日悖论,为了有 50% 的概率找到碰撞,你“只”需要尝试 2^128 个不同的值。 crypto.stackexchange.com/questions/47809/…

标签: sql-server types integer


【解决方案1】:

如果可能,最好将表的PRIMARY KEY 作为代理键和数字。使用SMALLINT, ``INTBIGINT 并应用IDENTITY。使用这样的定义:

[RowID] INT IDENTITY(1,1)

将帮助您解决一些常见问题 - 最重要的是,当创建新记录时,它们将附加在最后一个索引页的末尾,因此插入时不会出现页面拆分/碎片。

可以添加其他列 - 您的哈希值,您可以在其上创建索引,以便更快地通过哈希进行搜索。

例如,我有一个 IP 地址表,其中包含应用程序中使用的所有地址(基本上是用户用于登录的地址)。

表格如下所示:

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[IPAddresses]
(
     [IPAddressID] BIGINT IDENTITY(10000,1) NOT NULL
    ,[IPAddress] VARBINARY(84) NOT NULL
    ,[IPAddressHash] VARBINARY(64) NULL
    ,CONSTRAINT [PK_IPAddresses] PRIMARY KEY
     (
        [IPAddressID] ASC
     )
    ,INDEX [IX_IPAddresses_IPAddressHash] 
    (
        [IPAddressHash] ASC
    )
)
GO

由于IPAddress 是个人数据,它应该被加密。因为我希望我的数据被规范化并且我不想有重复的记录,所以我需要在每次用户登录时检查地址是否存在 - 如果不存在,则创建一个。我正在使用以下例程执行此操作:

在这里,我传递地址并计算我正在搜索的哈希值。最初的版本是使用哈希来解密所有值并通过文本搜索,但是对于数百万个 IP,这非常慢,并且该例程不断执行。另一方面,我只在该表中执行插入操作,并且只附加记录 - 所以根本没有碎片。

所以,我的建议是:

  1. 使用带有标识的数字列作为主键
  2. 添加表格中的其余列
  3. 添加哈希列并按用于搜索的列构建哈希
  4. 在这个哈希列上创建索引
  5. 然后当您需要搜索记录时使用哈希,找到PK ID,然后使用该 ID 提取记录

【讨论】:

    猜你喜欢
    • 2023-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多