唯一标识符(guid)作为数据库设计中的主键

TOM*_*ANG 18 sql-server database-design

我们的数据驻留在SQL Server 2008数据库中,表之间会有很多查询和连接.我们在团队内部有这个论点,有些人认为使用整数身份对性能更好,有些人则主张使用guid(唯一标识符).

使用GUID作为主键,性能是否真的遭受了严重影响?

ric*_*ent 31

128位GUID(uniqueidentifier)键当然比32位int键大4倍.但是,有一些关键优势:

  • 合并内容时没有"IDENTITY INSERT"问题
  • 如果使用COMB值而不是NEWSEQUENTIALID(),则会获得"免费"INSERT时间戳.SELECT如果您想要一些花哨的CAST()电话,您甚至可以根据日期/时间范围从主键.
  • 它们是全球独一无二的,偶尔会变得非常方便.
  • 由于不需要跟踪高水位线,因此BL层可以分配值而不是SQL Server,从而消除SELECT scope_identity()了插入后获取主键的步骤.
  • 如果你甚至可能拥有超过20亿条记录,那么你需要使用bigint(64位)代替int.一旦你这样做,uniqueidentifier只是一倍大bigint.
  • 使用GUID可以更安全地在URL等中公开密钥,而不会让自己暴露于"猜测ID"攻击.
  • 在SQL Server如何从磁盘加载页面以及处理器现在主要是64位的方式之间,仅仅因为数字是128位而不是32位并不意味着比较需要4倍的时间.我看到的最后一个测试显示GUID几乎一样快.
  • 索引大小取决于有多少列都包括在内.尽管GUID本身较大,但与索引中的其他列相比,额外的8或12个字节可能无关紧要.

最后,通过使用整数来挤出一些小的性能优势可能不值得失去GUID的优点.根据经验进行测试并自行决定.

就个人而言,我仍然使用两者,具体取决于具体情况,但在我的情况下,决定因素从来没有真正归结为性能.

  • 提及梳子的+1我已经读过,这也大大减少了索引碎片. (3认同)
  • 组合(即顺序 GUID)可能会减少碎片,但在高 I/O 系统上,似乎 RANDOM 非顺序 GUID 实际上可以提高性能,特别是对于插入。原因是页面拆分比尝试在最后一个数据页面上插入所有内容所引起的争用成本更低,就像顺序 ID 一样。参见:http://blog.kejser.org/2011/10/05/boosting-insert-speed-by-generate-scalable-keys/ 这真的取决于底层系统。 (2认同)
  • Guid as PK 在插入时表现不佳,如果它们是聚集的,并且 PK 默认是聚集索引,这意味着引擎无法保持表(物理)有序并导致表拆分和重新排序。在 url 中公开 ID 没有任何好处,如果它们是字符串、整数、guid 或其他任何东西,都没有区别。向导不会混淆它。 (2认同)

mar*_*c_s 20

我个人INT IDENTITY用于大多数主键和群集键.

您需要将作为逻辑构造的主键分开- 它唯一地标识您的行,它必须是唯一且稳定的NOT NULL.GUID也适用于主键 - 因为它保证是唯一的.如果使用SQL Server复制,GUID作为主键是一个不错的选择,因为在这种情况下,无论如何都需要唯一标识的GUID列.

SQL Server中的聚类键是一个物理构造,用于数据的物理排序,并且更难以正确.通常,SQL Server上的索引女王Kimberly Tripp也需要一个好的集群密钥,以便尽可能地缩小,稳定,理想地不断增加(所有这些INT IDENTITY都是).

在这里查看她关于索引的文章:

并且还将Jimmy Nilsson的GUID成本视为主要关键

对于聚类键,GUID是一个非常糟糕的选择,因为它很宽,完全随机,因此导致错误的索引碎片和糟糕的性能.此外,群集密钥行也存储在每个非群集(附加)索引的每个条目中,因此您确实希望保持较小 - GUID为16字节,而INT为4字节,并且有几个非聚集索引和几百万行,这是一个巨大的差异.

在SQL Server中,您的主键默认情况下是您的群集密钥 - 但它不一定是.您可以轻松地将GUID用作非群集主键,并将其INT IDENTITY作为群集密钥 - 只需要了解一点.

  • @TOMMYWANG:常规 GUID 与 INT 一样快 **NOWHERE NEAR** - 参见 [磁盘空间便宜......这不是重点!](http://www.sqlskills.com/BLOGS/KIMBERLY/post /Disk-space-is-cheap.aspx) 由 Kim Tripp 编写,对 INT 与 GUID 进行了一些测试 (2认同)