代码之家  ›  专栏  ›  技术社区  ›  mkchandler

数据库中ID字段的int与唯一标识符

  •  31
  • mkchandler  · 技术社区  · 16 年前

    我正在使用SQL Server 2005(在不久的将来可能是SQL Server 2008)为网站创建新的数据库。作为一名应用程序开发人员,我见过许多使用 integer (或) bigint 等)表示将用于关系的表的ID字段。但最近我也看到了使用 unique identifier ( GUID )用于ID字段。

    我的问题是一个是否比另一个有优势?威尔 整数 查询和加入等字段更快?

    更新: 为了清楚起见,这是针对表中的主键的。

    6 回复  |  直到 9 年前
        1
  •  50
  •   Jim G.    12 年前

    由于高随机性,guid作为聚集键存在问题。Paul Randal在上一期TechNet杂志Q&A专栏中讨论了这个问题: I'd like to use a GUID as the clustered index key, but the others are arguing that it can lead to performance issues with indexes. Is this true and, if so, can you explain why?

    现在请记住,讨论的重点是 群集的 索引。您说要将列用作“id”,这不清楚您是将其表示为聚集键还是仅表示主键。通常这两个重叠,所以我假设您希望将其用作聚集索引。我在上面提到的文章的链接中解释了为什么这是一个糟糕的选择。

    对于非聚集索引,guid仍然有一些问题,但并没有表中最左边的聚集键那么大。同样,guid的随机性引入了页面拆分和碎片化,只在非聚集索引级别(一个小得多的问题)。

    有许多关于guid用法的城市传说,根据它们的大小(16字节)来谴责它们,而不是int(4字节),如果使用了guid,将带来可怕的性能损失。这有点夸张。在一个设计合理的数据模型上,16号的密钥仍然是一个非常有效的密钥。虽然是真的,4倍大的整数导致更多的 低密度非叶页 在索引中,这不是大多数表真正关心的问题。B-树结构是一种自然平衡的树,并且 深度 树遍历的问题很少,因此基于guid键而不是int键来查找值在性能上类似。叶页遍历(即表扫描)不会查看非叶页,并且guid大小对页大小的影响通常非常小,因为记录本身明显大于guid引入的额外12个字节。所以我接受了基于“是16字节对4字节”的听说建议,其中包含了相当大的一粒盐。逐个分析单个案例,并确定大小影响是否会产生真正的差异:有多少 其他 列在表中(即叶页上的guid大小有多大的影响)以及有多少引用在使用它(即有多少引用 其他 表将增加,因为它们需要存储更大的外键)。

    我把所有这些细节都说出来是为了临时保护吉他,因为最近他们受到了很多坏消息,有些是不受欢迎的。它们有它们的优点,在任何分布式系统中都是不可或缺的(在您谈论数据移动时,无论是通过复制还是同步框架还是其他方式)。我看到过错误的决定是基于guid坏名声做出的,当他们被回避时没有适当的考虑。但这是真的, 如果必须使用guid作为聚集键,请确保解决随机性问题:使用顺序guid 如果可能的话。

    最后,回答你的问题: 如果你没有 具体的 使用guid的原因,使用ints。

        2
  •  8
  •   JBrooks    16 年前

    即使使用newsequentialid()函数,guid将占用更多的空间并比int慢。如果要进行复制或使用同步框架,则几乎必须使用guid。

        3
  •  6
  •   Philip Kelley    16 年前

    ints是4字节,bigints是8字节,guid是16字节。表示数据所需的空间越大,处理数据所需的资源就越多--磁盘空间、内存等。因此(a)它们的速度越慢,但(b)只有当卷是一个问题(数百万行,或在非常短的时间内处理数千个事务)时,这可能才重要。

    guid的优势在于它们(几乎)在全球范围内是独一无二的。使用正确的算法生成一个guid(而SQL Server XXXX将使用正确的算法),并且没有任何两个guid是相同的——无论您生成了多少台计算机,无论频率如何。(这在使用72年后不适用——我忘记了细节。)

    如果需要跨多个服务器生成唯一的标识符,guid可能很有用。如果您需要Mondo性能,并且低于20亿的值,Int可能很好。最后,也许最重要的是,如果您的数据有自然键,请坚持使用它们,并忘记代理值。

        4
  •  4
  •   Jack Marchetti    16 年前

    如果你是肯定的,绝对要有一个唯一的ID,然后是guid。也就是说,如果要合并、同步、复制,您可能应该使用一个guid。

    对于不太健壮的事物,int应该足够,这取决于表将增长到多大。

    在大多数情况下,正确的答案是,这取决于。

        5
  •  3
  •   gbn    16 年前

    使用它们进行复制等, 作为主键。

    Kimberly L Tripp article

    • 反对:空间,不严格单调,分页符,书签/脊等
    • 为了:呃…
        6
  •  2
  •   Alex_L    16 年前

    完全同意JBrooks。 我想说的是,当您的表很大,并且您使用带有联接的select,特别是对于派生表,使用guid可以显著降低性能。