【问题标题】:Why not always use GUIDs instead of Integer IDs?为什么不总是使用 GUID 而不是整数 ID?
【发布时间】:2020-10-13 20:00:38
【问题描述】:

使用 GUID 的缺点是什么? 为什么不总是默认使用它们?

【问题讨论】:

    标签: sql sql-server database-design


    【解决方案1】:

    整数加入的速度要快得多。这在处理数百万行时尤其重要。

    对于两个,GUID 比整数占用更多空间。同样,在处理数百万行时非常重要。

    对于三个,GUID 有时采用不同的格式,这可能会导致应用程序出现问题等。整数是整数,贯穿始终。

    可以在hereJeff's blog 上找到更深入的了解。

    【讨论】:

    • 我知道的游戏迟到了。仍然值得指出的是,GUID 保证为 16 个字节或错误。 SQL Server 中的整数是 4 字节,但并非所有整数都是。这因语言和平台而异。
    【解决方案2】:

    从程序员的角度来看,GUID 非常棒 - 它们保证(几乎)是唯一的,所以为什么不到处使用它们,对吧?

    如果从 DBA 的角度和数据库的角度来看,至少对于 SQL Server,有几点需要考虑:

    • GUID 作为主键(负责唯一标识表中的单行)可能没问题 - 毕竟它们是唯一的,对吧?
    • 不过,SQL Server 也有集群键的概念,它对表中的数据进行物理排序;如果您对此一无所知,并且没有明确执行任何操作,那么您的主键将成为您的集群键。

    Kimberly Tripp - 世界知名的 SQL Server 索引和性能专家 - 有很多博客文章说明为什么将 GUID 作为集群键是一个非常糟糕的主意 - 查看她的 blog on indexes

    最值得注意的是,她对集群键的最佳实践是:

    • 静态
    • 独一无二的
    • 不断增加

    GUID 通常是静态且唯一的 - 但它们既不窄(16 字节对 INT 的 4 字节)也不在不断增加。由于它们的性质,它们是独一无二的且(伪)随机的。

    窄部分很重要,因为集群键将添加到表中每个非聚集索引的每个索引页中 - 如果您有其中的几个,并且表中有几百万行,这会浪费大量空间 - 不仅在您的磁盘上,而且在您的 SQL Server 的 RAM 中。

    不断增加的部分很重要,因为 GUID 的随机性会导致索引中出现大量碎片,从而对您的整体性能产生负面影响。即使是 SQL Server 2005 及更高版本的 newsequentialid() 并没有真正创建顺序 GUID - 它们是顺序的一段时间,然后再次跳转,导致碎片(少于完全随机的 GUID,但仍然如此)。

    总而言之,如果您真的关心您的 SQL Server 性能,using GUIDs as a clustering key 是一个非常糟糕的主意 - 使用 INT IDENTITY() 代替,可能使用 GUID 作为主(非集群)键,如果你真的必须这样做。

    马克

    【讨论】:

    • 我同意你永远不应该使用 GUID 作为主键。但是,GUID 是必不可少的,应该在实体对象(在同一域中)跨多个实例传播时使用。
    【解决方案3】:
    1. GUID 是 int 的四倍,是 bigint 的两倍。

    2. 如果您尝试对表进行故障排除,则很难查看 GUID。

    【讨论】:

      【解决方案4】:

      GUIDS 可以简化提前生成密钥、离线或在集群中生成密钥的过程,而不会发生冲突。可能还有一点安全优势,所有密钥都不可猜测。

      缺点是阅读/键入更困难,而且在您的许多表格上,您以后可能会意识到需要返回并生成对人类友好的密钥。他们还将您的记录均匀地分布在一个表中,这可能会使查询几乎同时插入的多条记录与在您的记录按插入时间顺序插入的位置具有自动编号键相比更慢。

      【讨论】:

        【解决方案5】:

        这个答案并不排除使用 INT 作为主键的想法。它主要是为了指出 guid 何时有用。

        这是一篇很棒的(简短的)文章:
        http://www.codinghorror.com/blog/2007/03/primary-keys-ids-versus-guids.html

        解释...
        我对可能需要导出或与另一个数据库实例共享的任何(常见)数据库实体类型使用 guid。这样,我就有了一个 DNA 标记(即 guid),可用于区分同一“物理”实体的“相似”对象。

        例如,假设两个数据库实例有一个名为 PROJECT 的表。如果两个项目具有相同的名称或编号,则很难区分哪个是哪个。使用 GUID,尽管您可以轻松区分 2 个项目以及它们来自何处……即使它们之间有许多相似的值。这似乎不可能……但实际上可以而且确实会发生。

        【讨论】:

          【解决方案6】:

          与整数相比,GUID 又大又慢 - 所以在需要时使用它们,在不需要时避开它们,就这么简单!

          【讨论】:

            【解决方案7】:

            使用 GUID 作为主键/聚集键对性能的最大影响是在大型表中插入记录。重新索引可能是一项繁重的任务,因为您的密钥会落在中间的某个位置

            【讨论】:

              【解决方案8】:

              使用 GUID 作为主键最终会导致数据库崩溃,因为驱动器变得过于碎片化。这是一种称为抖动的情况。

              【讨论】:

                猜你喜欢
                • 2013-12-07
                • 2014-12-12
                • 1970-01-01
                • 2014-07-23
                • 1970-01-01
                • 2016-02-18
                • 2014-09-27
                • 2016-02-18
                • 1970-01-01
                相关资源
                最近更新 更多