【问题标题】:GUID vs INT IDENTITY [duplicate]GUID 与 INT IDENTITY [重复]
【发布时间】:2010-10-24 04:15:56
【问题描述】:

可能重复:
How do you like your primary keys?

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

最后,您会在什么情况下将 INT 用作 PK 与 GUID?

【问题讨论】:

标签: database primary-key guid


【解决方案1】:

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

【讨论】:

  • 还没有读过this series,但我认为托尼·罗杰森(Tony Rogerson)认为使用 SSD 可以大大减少碎片问题
  • 博文中的论点,除非我看错了,否则主要是一个 INT / BIGINT 系统,其数据库使用集群主键(SQL Server)将更快,更节省空间。并非在所有数据库中都是如此。以 Postgres 为例。
【解决方案2】:

我们在非常复杂的企业软件中到处都有指南。运行顺畅。

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

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

【讨论】:

  • 企业软件中的 guid 集群怎么样?
  • 我完全同意这个回复,你对 SQL 这样的解释型语言如何工作的直觉可能是错误的;在你得到一个可以告诉你差异的可靠测试之前,不要优化。至于集群:它会创建争用和热页面,尤其是当您有多个用户都试图写入同一个页面时。随机键会将数据分散到多个页面并减少争用。
【解决方案3】:

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

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

我很想看看任何测量结果如何,例如SQL Server 实际上处理带有 IDENTITY PK 的大量插入表。

【讨论】:

  • 是的,当然。整数或任何单调递增的值将在插入和更新期间创建热页。如果您有几十个用户都插入和更新创建页面争用。集群可能会节省空间,但会为热门页面造成瓶颈。
【解决方案4】:

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

【讨论】:

    【解决方案5】:

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

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

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

    【讨论】:

    • 我见过的使用 int 的一个更好的理由是,额外的 4 个字节被乘以它们作为外键出现的每个索引和表。但是,我认为碎片问题会使密钥使用的实际空间相形见绌。
    【解决方案6】:

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

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

    【讨论】:

      【解决方案7】:

      回答您的问题: 最后,您会在什么情况下将 INT 用作 PK 与 GUID?

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

      【讨论】:

        【解决方案8】:

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

        【讨论】:

          【解决方案9】:

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

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

          【讨论】:

            【解决方案10】:

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

            【讨论】:

            • 如果记录的自然键不是数字怎么办;例如(host, timestamp) 用于日志消息记录,还是 (product_code) 用于产品记录?你会坚持添加一个除了有冗余键之外没有其他用途的数字字段吗?
            • 不,我不会,但是对于时间戳字段,您可以考虑将标识字段添加到表中并将其用作键而不是时间戳。因为它们都是由数据库生成的。如果它是产品代码,那么我将始终将其用于 ID,因为这是基于您的业务的特定产品,因此将其更改为 ID 毫无意义。这完全取决于您将存储的数据类型以及您将如何设计数据库。
            【解决方案11】:

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

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

            【讨论】:

            • 现在的 GUID 通常是随机生成的
            • @Marco 您能否提供一些支持这一点的文档参考?我从来没有听说过这个。
            • 这已经是老生常谈了。除其他外,只需查看维基百科en.wikipedia.org/wiki/Globally_unique_identifier 最值得注意的是算法部分
            【解决方案12】:

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

            【讨论】:

            • 你总是可以使用哈希来缓解这个问题hashids.org
            【解决方案13】:

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

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

            【讨论】:

            • 您在调试器中看到的必须是选择数据类型的最不实用的标准。那么你不妨使用字符串来加入你的表格。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2010-12-28
            • 2011-05-03
            • 1970-01-01
            • 2011-09-17
            • 1970-01-01
            • 2012-10-04
            相关资源
            最近更新 更多