我过去曾在许多数据库系统上工作过,如果所有数据库键都是GUID / UUID值,那么在数据库之间移动条目会容易得多。我曾考虑过几次走这条路,但总是有一些不确定性,尤其是在性能和无法通过电话读取的 URL 方面。
有没有人在数据库中广泛使用 GUID?这样做我会得到什么好处,可能的陷阱是什么?
我过去曾在许多数据库系统上工作过,如果所有数据库键都是GUID / UUID值,那么在数据库之间移动条目会容易得多。我曾考虑过几次走这条路,但总是有一些不确定性,尤其是在性能和无法通过电话读取的 URL 方面。
有没有人在数据库中广泛使用 GUID?这样做我会得到什么好处,可能的陷阱是什么?
好处:
缺点:
就个人而言,我将它们用于任何规模相当大的系统中的大多数 PK,但我在一个在整个地方都复制的系统上接受了“培训”,所以我们必须拥有它们。YMMV。
我认为重复数据的事情是垃圾 - 你可以得到重复的数据,但是你这样做。代理键通常在我工作过的地方不受欢迎。我们确实使用类似 WordPress 的系统:
更新: 所以这个得到了很多 +1,我想我应该指出 GUID PK 的一个很大的缺点:聚集索引。
如果您有很多记录,并且 GUID 上有一个聚集索引,那么您的插入性能将会很差,因为您在项目列表中的随机位置插入(这就是重点),而不是在最后(这很快)
因此,如果您需要插入性能,可以使用 auto-inc INT,如果您想与其他人共享它,则生成一个 GUID(即,在 URL 中将其显示给用户)
为什么没有人提到性能?当您有多个连接时,所有这些都基于这些讨厌的 GUID,性能将通过地板,一直在那里:(
主要优点是您可以在不连接到数据库的情况下创建唯一 ID。并且 id 是全球唯一的,因此您可以轻松组合来自不同数据库的数据。这些似乎是很小的优势,但在过去为我节省了很多工作。
主要缺点是需要更多的存储空间(在现代系统上不是问题),并且 id 并不是真正人类可读的。这可能是调试时的问题。
存在一些性能问题,例如索引碎片。但这些很容易解决(jimmy nillson 的梳理指南:http: //www.informit.com/articles/article.aspx? p=25862 )
编辑合并了我对这个问题的两个答案
@Matt Sheppard 我认为他的意思是您可以复制具有不同 GUID 的行作为主键。这是任何类型的代理键的问题,而不仅仅是 GUID。就像他说的那样,通过向非键列添加有意义的唯一约束很容易解决。另一种方法是使用自然键,而那些有真正的问题..
@马特谢泼德:
假设您有一张客户表。当然,您不希望客户在表中出现多次,否则整个销售和物流部门会发生很多混乱(特别是如果关于客户的多行包含不同的信息)。
因此,您有一个唯一标识客户的客户标识符,并确保客户知道该标识符(在发票中),以便客户和客户服务人员在需要沟通时有一个共同的参考。为了保证没有重复的客户记录,您可以通过客户标识符上的主键或通过客户标识符列上的 NOT NULL + UNIQUE 约束向表中添加唯一性约束。
接下来,由于某种原因(我想不出),您被要求向客户表添加一个 GUID 列并将其作为主键。如果现在客户标识符列没有唯一性保证,那么您将在整个组织中寻找未来的麻烦,因为 GUID 将始终是唯一的。
一些“架构师”可能会告诉您“哦,但我们在应用层处理真正的客户唯一性约束!”。对。关于通用编程语言和(尤其是)中间层框架的时尚一直在变化,并且通常永远不会超过您的数据库。而且很有可能您在某些时候需要在不通过当前应用程序的情况下访问数据库。== 麻烦。(但幸运的是,你和“架构师”早已不在,所以你不会在那里收拾烂摊子。)换句话说:一定要在数据库中保持明显的约束(如果你有的话,在其他层也一样)时间)。
换句话说:将 GUID 列添加到表中可能有充分的理由,但请不要相信这会降低您在真实(==非 GUID)信息中保持一致性的野心。
如果 GUID 被用作“uniqifiers”,那么 GUID 将来可能会给您带来很多麻烦,让重复的数据进入您的表中。如果您想使用 GUID,请考虑在其他列上仍然保持 UNIQUE-constraints。
如果您还将该列用作聚集索引(一种相对常见的做法),那么使用 GUIDS 作为主键时要考虑的另一个小问题。由于 guid 的性质无论如何都不是按顺序开始的,因此您将在插入时受到打击,因此在您插入时它们将是页面拆分等。如果系统将具有高 IO,则需要考虑一些事情......
GUID 作为主键的成本(SQL Server 2000)
神话,GUID 与自动增量(MySQL 5)
这真的是你想要的。
UUID 优点
GUID 缺点
有一件事没有真正解决,即使用随机(UUIDv4)ID 作为主键会损害主键索引的性能。无论您的表是否围绕键聚集,都会发生这种情况。
RDBMs通常保证主键的唯一性,通过一个键来保证查找,在一个叫做BTree的结构中,它是一个分支因子很大的搜索树(二叉搜索树的分支因子为2)。现在,一个连续的整数 ID 将导致插入仅发生在树的一侧,而大部分叶节点保持不变。添加随机 UUID 将导致插入在整个索引中拆分叶节点。
同样,如果存储的数据大部分是临时的,则通常需要访问和连接最新的数据。对于随机 UUID,模式不会从中受益,并且会命中更多索引行,从而需要内存中的更多索引页。如果最需要最近的数据,则使用顺序 ID,热索引页将需要更少的 RAM。
好处:
到目前为止没有提到的一件事:UUID 使分析数据变得更加困难
至少对于 Web 应用程序,通常使用 url 中的 id 访问资源,例如stackoverflow.com/questions/45399
. 如果 id 是一个整数,这两者
从第一点开始,我可以将问题中的时间戳和数字结合起来,以分析提出问题的频率以及随时间变化的情况。这在像 Stack Overflow 这样具有公开信息的网站上并不重要,但是,根据上下文,这可能会暴露敏感信息。
例如,我是一家为客户提供权限门控门户的公司。地址是portal.com/profile/{customerId}
。如果 id 是一个整数,你可以通过定期查询来分析客户的数量,无论是否能够看到他们的信息lastKnownCustomerCount + 1
,并检查结果是404 - NotFound
(客户不存在)还是403 - Forbidden
(客户确实存在,但你没有访问查看)。
UUID 的非顺序性质缓解了这些问题。这并不是为了防止分析,但它是一个开始。