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

时间:2012-03-15 19:49:06

标签: sql-server database-design

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

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

6 个答案:

答案 0 :(得分: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 :(得分:20)

我个人使用INT IDENTITY来处理我的主要和群集密钥。

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

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

请参阅她关于索引的文章:

还可以看到Jimmy Nilsson的The Cost of GUIDs as Primary Key

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

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

答案 2 :(得分:4)

答案 3 :(得分:3)

GUID作为主键的一个大问题是它们会导致大量的表碎片,这可能是一个很大的性能问题(表越大,问题就越大)。即使作为非聚簇索引的键,它们也会导致索引碎片化。

您可以通过设置适当的填充因子来部分缓解问题 - 但这仍然是一个问题。

除了需要进行表扫描的其他窄行表外,大小差异并没有那么多。在这些情况下,每个数据库页面能够容纳更多行是一个性能优势。

使用GUID有充分的理由,但也有成本。我通常更喜欢INT IDENTITY用于主键,但是当它们是更好的解决方案时我不会避免使用GUID。

答案 4 :(得分:0)

  

使用GUID的主要优点是它们在所有空间和时间都是唯一的。

     

使用GUID作为键值的主要缺点是它们是   大。弹出的是16个字节,它们是SQL中最大的数据类型之一   服务器。构建在GUID上的索引将比大于和慢   构建在IDENTITY列上的索引,通常是整数(4个字节)。

因此,对于需要合并来自多个来源的数据的情况,它们是一个很好的解决方案

来源:http://www.sqlteam.com/article/uniqueidentifier-vs-identity

答案 5 :(得分:-1)

如果数据库表记录可以增长到百万条记录,我认为将它用作主键并不是一个好主意。