我过去曾经在许多数据库系统上工作过,如果所有数据库键都是GUID / UUID值,那么在数据库之间移动条目将变得更加容易。我已经考虑过几次这样做,但总会有一些不确定性,特别是在性能和无法通过电话读出的URL方面。
有没有人在数据库中广泛使用GUID?采用这种方式会带来什么优势,可能存在哪些缺陷?
我过去曾经在许多数据库系统上工作过,如果所有数据库键都是GUID / UUID值,那么在数据库之间移动条目将变得更加容易。我已经考虑过几次这样做,但总会有一些不确定性,特别是在性能和无法通过电话读出的URL方面。
有没有人在数据库中广泛使用GUID?采用这种方式会带来什么优势,可能存在哪些缺陷?
优点:
缺点:
个人而言,在任何规模较大的系统中,我都会将它们用于大多数主键,但我被一个到处复制的系统“训练”了,所以我们必须拥有它们。你的情况可能会有所不同。
我认为重复数据的问题是荒谬的 - 无论你如何做,都可能会出现重复数据。在我工作的任何地方,使用代理键通常是不被赞同的。但我们确实使用类似 WordPress 的系统:
更新: 这篇文章得到了很多 +1,我认为我应该指出 GUID 主键的一个重大缺点:聚集索引。
如果你有很多记录,并且在 GUID 上有一个聚集索引,你的插入性能会非常差,因为你会将插入的记录随机放在项目列表中的不同位置(这就是关键),而不是放在末尾(这很快)。
因此,如果你需要插入性能,也许可以使用自动增量 INT,并在需要与他人共享时生成 GUID(例如,在 URL 中向用户显示它)。
example.com/35/old-and-busted
变成了example.com/35/new-hotness
,你的应用程序可以检查标题并使用301重定向用户。 - Xeoncross为什么没有人提到性能问题?当你有多个基于这些不好处理的GUID的连接时,性能会变得非常差,我曾经遇到过这个问题 :(
@Matt Sheppard:
假设你有一个客户表。肯定不希望同一客户在表中出现多次,否则会在销售和物流部门产生很多混乱(特别是如果关于该客户的多行内容包含不同的信息)。
因此,你需要一个唯一标识符来唯一地识别每个客户,并确保该标识符已知于客户(在发票中),以便客户和客户服务人员在需要沟通时有一个共同的参考。为了保证没有重复的客户记录,可以通过在客户标识符上添加主键或通过在客户标识符列上添加 NOT NULL + UNIQUE 约束来向表中添加唯一性约束。
接下来,由于某种原因(我无法想象),要求你向客户表中添加一个 GUID 列并将其设置为主键。如果现在客户标识符列没有唯一性保证,那么你将在整个组织中引发未来的问题,因为 GUID 始终是唯一的。
某些“架构师”可能会告诉你,“哦,但我们在应用程序层处理了真正的客户唯一性约束!”。对于这种通用编程语言和(尤其是)中间层框架的流行趋势经常发生变化,并且通常不会超过你的数据库的寿命。而且很有可能在某个时刻,你需要访问数据库而不经过当前应用程序。==麻烦。(但幸运的是,你和“架构师”早已离开,所以你不必为清理混乱付出代价。)换句话说:请在数据库(以及其他层次,如果你有时间)中维护明显的约束。
换句话说:向表中添加 GUID 列可能有很好的理由,但请不要因此降低你对真正(==非 GUID)信息一致性的追求。
如果GUID作为“唯一标识符”用于防止重复数据进入表中,可能会在未来给您带来很多麻烦。如果您想使用GUID,请考虑仍然在其他列上维护唯一约束。
如果您将GUID用作主键并且还将该列用作聚集索引(这是相对常见的做法),则需要考虑的另一个小问题是插入时会受到影响。由于GUID的本质不是按顺序排列的,因此在插入时可能会出现页面分裂等情况。如果系统将具有高IO,则需要考虑这一点...
GUID作为主键的代价(SQL Server 2000)
Myths, GUID vs. Autoincrement(MySQL 5)
这是您需要的内容。
UUID的优点
GUID的缺点
有一件事情并没有得到很好的解决,那就是使用随机(UUIDv4)作为主键会对主键索引的性能造成负面影响。无论您的表是否围绕该键集群。
RDBMs通常确保主键的唯一性,并通过一个称为BTree的结构确保按键查找,这是具有大分支因子的搜索树(二叉搜索树的分支因子为2)。现在,顺序整数ID将导致插入仅在树的一侧发生,使大多数叶节点保持不变。添加随机UUID将导致插入在整个索引中分裂叶节点。
同样,如果存储的数据主要是时间性的,则通常情况下需要访问并联接最近的数据。对于随机UUID,模式将无法从中受益,并且会命中更多的索引行,从而需要更多的索引页面在内存中。对于顺序ID,如果最近的数据是最需要的,则热门索引页面需要更少的RAM。
优点: