【问题标题】:Deciding on a primary key according to value size in SQL Server根据 SQL Server 中的值大小确定主键
【发布时间】:2015-02-28 11:57:46
【问题描述】:

我想问一个优化 SQL Server 性能的问题。假设我有一个实体——比如Item——我必须为它分配一个主键。它有列,其中两个预计是唯一的,其中一个预计比另一个大几十个字符。

我应该如何决定主键?

其中一个应该是 PK,如果是,是哪一个,或两者兼而有之,或者我应该创建一个身份号码作为 PK?这对我来说很重要,因为实体“Item”会与其他一些实体有关系,我认为 PK 的复杂性会影响 SQL Server 查询的性能。

【问题讨论】:

    标签: sql sql-server entity-framework primary-key identity


    【解决方案1】:

    就我个人而言,我会使用 IDENTITY 主键,该主键对提到的唯一键和索引都有唯一约束以进行附加查找。

    您必须记住,默认情况下 SQL Server 创建主键作为聚集索引,这会影响它在磁盘上的存储方式。如果新的ITEMS 是随机出现的,则差异可能会在任一主键上产生大量碎片。

    此外,除非打开级联和外键,否则您必须手动维护数据的关系完整性(除非您使用 IDENTITY

    【讨论】:

      【解决方案2】:

      嗯,主键实际上只用于唯一标识每一行 - 所以对它的唯一要求是:它必须是唯一的 strong> 并且通常也不应该包含NULL

      其他任何东西很可能与 SQL Server 中的 集群键 更相关 - 数据在磁盘上物理排序的列(或列集)。默认情况下,主键也是 SQL Server 中的集群键。

      群集键是 SQL Server 中最重要的选择,因为它具有深远的性能影响。 良好的聚类键是

      • 独一无二的
      • 稳定
      • 如果可能的话,不断增加

      它必须是唯一的,以便它可以添加到每个非聚集索引中以查找实际数据表 - 如果您选择一个非唯一列(或一组列),SQL Server 将添加一个 4 -byte 为您“唯一”。

      它应该尽可能窄,因为它存储在很多地方。尝试为INT 坚持使用 4 个字节或为BIGINT 坚持使用 8 字节 - 避免使用长且可变长度的 VARCHAR 列,因为它们都太宽了,而且可变长度也会带来额外的开销。因此,列集也很少是一个好的选择。

      集群键应该稳定 - 值不应该随时间变化 - 因为每次值变化时,可能会有很多索引条目(在聚集索引本身,以及每个非聚集索引中) , 也)需要更新,这会导致很多不必要的开销。

      如果它不断增加(如INT IDENTITY),您还可以避免大多数页面拆分 - 如果您使用随机值(如 GUID)作为你的集群键。

      简而言之:INT IDENTITY 是理想的选择 - GUID、可变长度字符串或列组合通常不是一个好的选择。

      【讨论】:

      • 我不会重新触发古老的论点,只需指出它。 blog.codinghorror.com/primary-keys-ids-versus-guids - 你几乎可以保证 SO 数据库有 guid,而且它是一个大数据库。
      • @jenson-button-event:在这种情况下,您必须阅读 Kim Tripp 的 GUIDs as PRIMARY KEYs and clustering keys - 我非常确定 SO数据库确实 not 将 GUID 作为其 PK .....
      • @jenson-button-event:如果您针对data.stackexchange.com/stackoverflow/query/new 的 SO 数据库编写自己的在线查询 - 您会看到他们正在使用 INT 作为他们的主键 - 任何理智的(SQL Server)数据库开发人员都会这样做!
      • 你在争论聚集索引,而不是主键
      • 据我了解,使用INT IDENTITY或更长的唯一数据如GUID作为PK是一个有争议的问题。然而,由于其较小的尺寸、作为集群键的高效使用和常见用法,使用身份听起来我更合理。
      【解决方案3】:

      选择您将用于识别查询中的记录并连接到其他表的记录。大小是相对的,而考虑因素通常不是问题,因为 PK 将被索引,并且其他唯一列也可以使用唯一索引。

      uniqueidentifier 数据类型,例如是一个 36 字符长的字符串表示形式,在大多数情况下作为主键表现良好。

      【讨论】:

      • 但是所有索引都指向主键。所以如果你的 PK 是 64 字节,那么每个索引的每个叶子都是 64 字节。
      • 基础设施不应成为软件设计的约束。这就是为什么我家的墙壁里藏着一些 DBA。
      • 查看 Kimberly Tripp 的 Disk space is cheap .... - that's not the point!。磁盘空间不是最重要的一点 - 过多的碎片,因此使用基于 GUID 的聚集索引的过多页面拆分以及通常较差的性能更是一个问题
      • 我并不是要煽动性,但在现实世界中,基础设施一种约束;数据库设计不是软件设计。在现实世界中,企业可能有也可能没有 DBA 来解决由数据库设计方法引入的问题,其中每个 PK 都是唯一标识符(而不是一个小的有意义的密钥) 事先一些深思熟虑和理解会阻止这些事情的发生。我敢肯定你已经破解了一些代码,尽管“这是错误的,现在它嵌入得太深了,我无法修复它”。我每天都会遇到这种情况!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-16
      • 2023-03-23
      • 2011-07-13
      • 2015-10-14
      相关资源
      最近更新 更多