3

我已经阅读了很多关于我们是否应该将主键作为标识列的文章,但我仍然感到困惑。

使列具有标识的优点,因为它可以在连接中提供更好的性能并提供数据一致性。但是有一个与身份相关的主要缺点,即当 INSERT 语句失败时,IDENTITY 值仍然会增加 如果事务回滚,则新的 IDENTITY 列值不会回滚,因此我们最终会出现排序间隙。我可以使用 GUID(通过使用 NEWSEQUENTIALID),但它会降低性能。

4

4 回答 4

8

差距应该无关紧要:身份列是内部的,不用于最终用户的使用或识别。

由于 16 字节宽度,GUID 会降低性能,甚至是顺序性能。

在对数据建模并计算出自然键是什么之后,应该选择一个标识列以尊重物理实现。也就是说,选择的自然键是逻辑键,但您选择代理键(身份),因为您知道引擎是如何工作的。

或者您使用 ORM 并让客户端尾巴摇晃数据库狗......

于 2009-11-12T08:07:20.593 回答
4

出于所有实际目的,整数是主键的理想选择,而自动增量是生成它们的完美方式。只要您的 PK 是无意义的(代理),它就会受到保护,不受客户创造力的影响,并很好地服务于其主要目的(识别表格中的一行)。索引被打包,连接速度很快,并且很容易对表进行分区。
如果您碰巧需要 GUID,那也没关系;但是,首先考虑自增整数。

于 2009-11-12T13:00:14.103 回答
1

我想说这取决于您的需求。我们只使用 Guids 作为主键(默认设置为 NewID),因为我们开发了一个包含许多 Sql Server 实例的分布式系统,因此我们必须确保每个 Sql Server 生成唯一的主键值。但是当使用 Guid 列作为 PK 时,请确保不要将其用作聚集索引(感谢 marc_s 的链接)

Guid 类型的优点:

  • 您可以在不同步的情况下在不同位置创建唯一值

坏处:

  • 它是一种大型数据类型(16 字节),需要更多空间
  • 它会创建索引碎片(至少在使用 newid() 函数时)

数据一致性对于独立于数据类型的主键来说不是问题,因为主键在定义上必须是唯一的!

我不相信身份列具有更好的连接性能。毕竟,性能是正确索引的问题。主键是约束而不是索引。

您是否需要没有间隙的 typ int 主键?这通常不应该是一个问题。

于 2009-11-12T08:13:28.023 回答
0

“是的,它完全杀死了性能。我从一个使用 GUID 作为 PK/CK 并且每天有 99.5% 索引碎片的旧系统到使用 INT IDENTITY - 巨大的差异。几乎不再有任何索引碎片,性能明显更好。GUID因为 SQL Server 表上的聚类索引是 BAD BAD BAD - 句号。”

可能是真的,但我认为没有任何逻辑推理可以据此得出结论,GUID PER SE 也是 BAD BAD BAD。

也许您应该考虑对此类数据使用其他类型的索引。如果您的 dbms 没有为您提供多种类型的索引之间的选择,那么也许您应该考虑让自己获得更好的 dbms。

于 2009-11-12T18:47:06.773 回答