39

可能重复:
你喜欢你的主键吗?

我知道使用 GUID 的好处,以及使用和 INT 作为数据库中的 PK 的好处。考虑到 GUID 本质上是 128 位 INT,而普通 INT 是 32 位,因此 INT 可以节省空间(尽管这一点在大多数现代系统中通常没有实际意义)。

最后,在什么情况下,您会认为自己使用 INT 作为 PK 还是使用 GUID?

4

13 回答 13

26

Kimberley Tripp (SQLSkills.com) 有一篇关于使用 GUID 作为主键的文章。由于不必要的开销,她建议不要这样做。

于 2009-05-06T12:23:58.707 回答
23

回答您的问题:最后,在什么情况下您会认为自己使用 INT 作为 PK 还是使用 GUID?

如果我的系统有一个在线/离线版本,您可以在离线版本中保存数据并且该数据在一天同步期间传输回服务器,我将使用 GUID。这样,您可以确定您的数据库中不会有两次相同的密钥。

于 2009-05-06T12:31:11.717 回答
22

我们在非常复杂的企业软件中到处都有指南。工作顺利。

我相信 Guid 在语义上更适合用作标识符。在您遇到该问题之前,不必要地担心性能也是没有意义的。当心过早的优化。

任何类型的数据库迁移也有一个优势。使用Guids,您将不会发生碰撞。如果您尝试合并多个使用 int 表示身份的 DB,则必须替换它们的值。如果在 url 中使用了这些旧值,那么在 SEO 命中后它们现在会有所不同。

于 2009-05-06T12:40:25.717 回答
20

除了在需要同步多个数据库实例时是一个糟糕的选择之外,INT 还有一个我没有提到的缺点:插入总是发生在索引树的一端。当您有一个有大量移动的表时,这会增加锁争用(因为相同的索引页面必须通过并发插入来修改,而 GUID 将被插入整个索引)。如果使用 B* 树或类似的数据结构,则可能还必须更频繁地重新平衡索引。

当然,在进行手动查询和报告构建时,int 更容易使用,并且空间消耗可能会因 FK 的使用而增加。

我很想看看 SQL Server 实际处理带有 IDENTITY PK 的插入繁重的表的任何测量结果。

于 2009-05-06T12:38:02.947 回答
14

INT 可以节省空间(尽管这一点在大多数现代系统中通常没有实际意义)。

不是这样。乍一看似乎如此,但请注意,每个表的主键将在整个数据库的索引中重复多次,并在其他表中作为外键重复。并且它将参与几乎所有包含其表的查询 - 当它是用于连接的外键时非常密集。

此外,请记住,现代 CPU 非常非常快,但 RAM 速度却跟不上。缓存行为因此变得越来越重要。获得良好缓存行为的最佳方法是拥有更小的数据集。因此,4 和 16 字节之间看似无关的差异很可能会导致速度上的明显差异。不一定总是 - 但这是需要考虑的事情。

于 2009-05-06T12:32:36.050 回答
8

在比较主键与外键关系等值时,INT 会更快。如果表的索引正确并且表很小,您可能不会看到减速太多,但您必须尝试一下才能确定。INT 也更容易阅读,也更容易与他人交流。说“你能看一下记录 1234 吗?”要简单得多。而不是“你能看一下记录 031E9502-E283-4F87-9049-CE0E5C76B658 吗?”

于 2009-05-06T12:25:22.493 回答
6

如果您计划在某个阶段合并数据库,即多站点复制类型设置,Guid 将节省很多痛苦。但除此之外,我发现 Int 更容易。

于 2009-05-06T12:35:47.523 回答
5

如果数据存在于单个数据库中(就像我们通常编写的应用程序的大多数数据一样),那么我使用IDENTITY. 它很容易,旨在以这种方式使用,不会分散聚集索引并且绰绰有余。您将用完 20 亿条记录(如果使用负值,则大约 40 亿条记录),但是如果您在一张表中有这么多记录,那么您无论如何都会敬酒,然后您就会遇到数据仓库问题。

如果数据存在于多个独立的数据库中或与第三方服务的接口中,那么我将使用GUID可能已经生成的数据。一个很好的例子是数据库中的 UserProfiles 表,它通过objectGUID分配给他们的 Active Directory 将 Active Directory 中的用户映射到应用程序中的用户配置文件。

于 2009-05-06T12:31:17.080 回答
4

一些操作系统不再基于独特的硬件功能(CPUID、MAC)生成 GUID,因为它使跟踪用户变得容易(隐私问题)。这意味着 GUID 的唯一性通常不再像许多人想象的那样普遍。

如果你使用数据库的一些自动识别功能,理论上数据库可以绝对确保没有重复。

于 2009-05-06T12:28:00.537 回答
2

我一直认为 PK 应该是可能的数字。不要忘记将 GUID 作为 PK 可能意味着它们也在其他表中用作外键,因此分页和索引等会更大。

于 2009-05-06T12:28:09.740 回答
1

我认为数据库也很重要。从 MySQL 的角度来看 - 通常,数据类型越小,性能越快。

它似乎也适用于 int vs GUID - http://kccoder.com/mysql/uuid-vs-int-insert-performance/

于 2009-05-06T12:29:18.897 回答
1

仅当此键绑定到相似值时,我才会将 GUID 用作 PK。例如,用户 id(WinNT 中的用户用 GUID 描述)或用户组 id。另一个例子。如果你开发分布式文件管理系统,世界各地不同系统的不同部分都可以创建一些文件。在这种情况下,我会使用 GUID,因为它保证在分布式系统的不同部分创建的 2 个文档不会具有相同的 ID。

于 2009-05-06T12:29:22.500 回答
0

INT 在调试时肯定更容易阅读,而且更小。

但是,我会使用 GUID 或类似的东西作为产品的许可证密钥。你知道它会是独一无二的,而且你知道它不会是连续的。

于 2009-05-06T12:20:54.283 回答