当前位置: 首页 > 面试题库 >

使用MD5哈希作为主键与使用int身份作为SQL Server中的主键的优缺点

崔涵亮
2023-03-14
问题内容

我有一个应用程序来处理文件并将其片段化为多个段,然后将结果保存到sql
server数据库中。有很多重复的文件(可能具有不同的文件路径),因此首先浏览所有这些文件并为每个文件计算Md5哈希,然后使用[Duplicated]列标记重复的文件。

然后每天我将运行该应用程序并将结果保存到[Result]表中。db模式如下:

    CREATE TABLE [dbo].[FilePath]
    (
        [FilePath] NVARCHAR(256) NOT NULL PRIMARY KEY,
        [FileMd5Hash] binay(16) NOT NULL,
        [Duplicated] BIT NOT NULL DEFAULT 0, 
        [LastRunBuild] NVARCHAR(30) NOT NULL DEFAULT 0
    )

    CREATE TABLE [dbo].[Result]
    (
        [Build] NVARCHAR(30) NOT NULL,
        [FileMd5Hash] binay(16) NOT NULL , 
        [SegmentId] INT NOT NULL,
        [SegmentContent] text NOT NULL 
        PRIMARY KEY ([FileMd5Hash], [Build], [SegmentId])
    )

而且我有要求在FileMd5Hash上加入这2个表。

由于[Result]的行数很大,因此我想添加一个int Identity列以将这些列连接到表中,如下所示:

    CREATE TABLE [dbo].[FilePath]
    (
        [FilePath] NVARCHAR(256) NOT NULL PRIMARY KEY,
        [FileMd5Hash] binay(16) NOT NULL,
        **[Id] INT NOT NULL IDENTITY,**
        [Duplicated] BIT NOT NULL DEFAULT 0, 
        [LastRunBuild] NVARCHAR(30) NOT NULL DEFAULT 0
    )

    CREATE TABLE [dbo].[Result]
    (
        [Build] NVARCHAR(30) NOT NULL,
        **[Id] INT NOT NULL,**  
        [SegmentId] INT NOT NULL,
        [SegmentContent] text NOT NULL 
        PRIMARY KEY ([FileMd5Hash], [Build], [SegmentId])
    )

那么这两种方式的优缺点是什么?


问题答案:

int键更易于实现,更易于使用和理解。它也更小(4字节对16字节),因此索引将适合每个IO页条目数的两倍,这意味着更好的性能。表行也将变小(好的,不会变小),因此,每页又可以容纳更多的行=更少的IO。

哈希值总是会产生冲突。尽管异常罕见,但正如生日问题所显示的那样,随着记录数量的增加,发生碰撞的可能性越来越大。与各种位长的散列发生冲突的机会达到50%所需的项目数如下:

Hash length (bits)   Item count for 50% chance of collision
                32   77000
                64   5.1 billion
               128   22 billion billion
               256   400 billion billion billion billion

还有一个问题是必须传递非ASCII字节-较难调试,通过电线发送等。

int对表使用顺序的主键。其他人都这样做。



 类似资料:
  • 问题内容: 如何使用复合主键作为外键?看来我的尝试无效。 问题答案: 该行: 是错的。您不能那样使用,这只是父表中PK约束的名称。要将复合主键用作外键,您必须向子表中添加相同数量(组成PK)的相同数据类型的列,然后在定义中使用这些列的组合:

  • 如何将复合主键用作外键?看来我的尝试没有成功。

  • 我在model和model之间有一个关系。这意味着每个用户都有0或1个总统设置。因此,表的主索引与外键相同。 这就是我想要添加外键的方式: 但是我得到以下错误: 我怎么才能修好它?我使用InnoDB引擎,所以我知道我可以设置索引键为外键。

  • 问题内容: 我将几个引用的表与整数主键一起使用。现在,我想将int更改为GUID,保留所有引用不变。最简单的方法是什么? 谢谢! 添加 我确实了解该过程,所以我需要更详细的建议,例如,如何填充新的GUID列。使用默认值newid()是正确的,但是对于已经存在的行呢? 问题答案: 在主表中为guid值创建一个新列。使用uniqueidentifier数据类型,并使其不为null,并使用newid()

  • 问题内容: 如何在Go for map中将键创建为数组。例如在ruby中,我可以这样实现: Golang的外观如何? 问题答案: 数组类型(不像片)在Go具有可比性,所以在它什么神奇:你可以定义它像任何其他地图:这里会和会。 该比较操作符 ==和=必须为键类型的操作数被完全定义!; 因此,键类型不能为函数,映射或切片。 输出: 在Go Playground上尝试一下。 要查询元素: 您还可以一步创

  • 如果您在一个表上的非空列上使用计数,而没有任何where部分,则优化器只需返回该表中的行数。 如果您要求对一个唯一的非空列(如主键)进行非重复计数,答案应该是相同的,但是这次mariadb代替了。 如果您在其他表上留下了联接,但仍然没有 where 部分,则结果仍应为该表中的行数。 Mariadb 不使用千次优化是有原因的吗?是否存在未过滤主键的 DISTINCT 计数可以给出任何其他结果,然后该