我正在使用 SQL Server 2005(在不久的将来可能是 SQL Server 2008)为网站创建一个新数据库。作为一名应用程序开发人员,我见过许多使用integer
(或bigint
等)作为将用于关系的表的 ID 字段的数据库。但最近我也看到了使用unique identifier
( GUID
) 作为 ID 字段的数据库。
我的问题是一个是否比另一个有优势?integer
字段查询和加入等会更快吗?
更新:为了清楚起见,这是针对表中的主键。
我正在使用 SQL Server 2005(在不久的将来可能是 SQL Server 2008)为网站创建一个新数据库。作为一名应用程序开发人员,我见过许多使用integer
(或bigint
等)作为将用于关系的表的 ID 字段的数据库。但最近我也看到了使用unique identifier
( GUID
) 作为 ID 字段的数据库。
我的问题是一个是否比另一个有优势?integer
字段查询和加入等会更快吗?
更新:为了清楚起见,这是针对表中的主键。
由于高随机性,GUID 作为集群键存在问题。Paul Randal 在上一期 Technet 杂志问答专栏中解决了这个问题:我想使用 GUID 作为聚集索引键,但其他人认为它会导致索引的性能问题。这是真的吗?如果是,你能解释一下原因吗?
现在请记住,讨论专门针对聚集索引。您说您想将该列用作“ID”,但不清楚您是指它作为聚集键还是主键。通常这两个重叠,所以我假设您想将它用作聚集索引。我在上面提到的文章的链接中解释了为什么这是一个糟糕的选择的原因。
对于非聚集索引,GUID 仍然存在一些问题,但不如它们是表的最左侧聚集键时那么大。同样,GUID 的随机性引入了页面拆分和碎片,仅在非聚集索引级别(一个小得多的问题)。
围绕 GUID 的使用有许多都市传说,它们根据它们的大小(16 字节)与 int(4 字节)相比来谴责它们,并承诺如果使用它们会带来可怕的性能厄运。这有点夸张。在正确设计的数据模型上,大小为 16 的键仍然可以是非常高性能的键。虽然确实是 int 的 4 倍会导致索引中的非叶页密度更低,但这对于绝大多数表来说并不是一个真正的问题。b-tree 结构是一个自然平衡良好的树和深度树遍历很少成为问题,因此基于 GUID 键而不是 INT 键寻找值在性能上是相似的。叶页遍历(即表扫描)不查看非叶页,GUID 大小对页大小的影响通常很小,因为记录本身明显大于引入的额外 12 个字节通过 GUID。因此,我会接受基于“是 16 字节与 4 字节”的传闻建议,并带有相当大的盐粒。逐个分析并确定大小影响是否真正产生影响:表中有多少其他列(即叶页上的 GUID 大小有多少影响)以及有多少引用正在使用它(即。由于需要存储更大的外键,因此会增加多少其他表)。
我在对 GUID 的一种临时辩护中提到了所有这些细节,因为它们最近受到了很多负面新闻,有些是不值得的。它们有其优点,并且在任何分布式系统中都是必不可少的(当您谈论数据移动时,无论是通过复制还是同步框架或其他方式)。我已经看到当他们在没有适当考虑的情况下被回避时,基于 GUID 的坏名声做出了错误的决定。但确实如此,如果您必须使用 GUID 作为集群键,请确保解决随机性问题:尽可能使用顺序 guid。
最后,回答您的问题:如果您没有使用 GUID 的特定理由,请使用 INT。
GUID 将占用更多空间并且比 int 慢 - 即使您使用 newsequentialid() 函数。如果您要进行复制或使用同步框架,您几乎必须使用 guid。
INT 为 4 个字节,BIGINT 为 8 个字节,GUIDS 为 16 个字节。表示数据所需的空间越多,处理它所需的资源就越多——磁盘空间、内存等。所以(a)它们速度较慢,但(b)这可能仅在容量问题(数百万行,或在非常非常短的时间内完成数千笔交易。)
GUID 的优点是它们(几乎)是全球唯一的。使用正确的算法生成一个 guid(并且 SQL Server xxxx 将使用正确的算法),并且没有两个 guid 是相同的——无论您有多少台计算机生成它们,无论多么频繁。(这在使用 72 年后不适用——我忘记了细节。)
如果您需要跨多个服务器生成唯一标识符,GUID 可能很有用。如果您需要 mondo 性能和低于 20 亿的值,int 可能没问题。最后也是最重要的一点,如果您的数据有自然键,请坚持使用它们并忘记代理值。
如果你肯定,绝对必须有一个唯一的 ID,然后是 GUID。这意味着如果您要合并、同步、复制,您可能应该使用 GUID。
对于不太健壮的东西,一个 int 应该就足够了,具体取决于表的大小。
在大多数情况下,正确的答案是,这取决于。
完全同意 JBrooks。我想说的是,当您的表很大时,并且您使用带有 JOINS 的选择,尤其是派生表时,使用 GUID 会显着降低性能。