我曾经在许多数据库系统上工作过,如果所有的数据库键都是GUID / UUID值,那么在数据库之间移动条目就会容易得多。我考虑过几次采用这种方法,但总有一些不确定性,特别是在性能和无法通过电话读出的url方面。
有人在数据库中大量使用guid吗?这样做会有什么好处,可能的陷阱是什么?
我曾经在许多数据库系统上工作过,如果所有的数据库键都是GUID / UUID值,那么在数据库之间移动条目就会容易得多。我考虑过几次采用这种方法,但总有一些不确定性,特别是在性能和无法通过电话读出的url方面。
有人在数据库中大量使用guid吗?这样做会有什么好处,可能的陷阱是什么?
当前回答
guid在将来可能会给您带来很多麻烦,如果它们被用作“唯一符”,让重复的数据进入您的表。如果您想使用guid,请考虑在其他列上仍然保持unique -约束。
其他回答
有一件事没有真正解决,即使用随机(UUIDv4) id作为主键将损害主键索引的性能。无论表是否围绕键聚集,都会发生这种情况。
RDBMs通常确保主键的唯一性,并确保在一种名为BTree的结构中按键进行查找,这是一种具有较大分支因子的搜索树(二叉搜索树的分支因子为2)。现在,一个连续整数ID将导致插入只发生在树的一侧,而大多数叶节点不受影响。添加随机uuid将导致插入拆分整个索引中的叶节点。
同样地,如果存储的数据主要是临时的,通常情况下需要访问最新的数据,并根据最新的数据进行连接。对于随机uuid,模式将无法从中受益,并将访问更多的索引行,因此需要内存中更多的索引页。如果最需要最近的数据,那么使用顺序id,热索引页将需要更少的RAM。
到目前为止还没有提到的一件事是:uuid使分析数据变得更加困难
至少对于web应用程序来说,通过url中的id访问资源是很常见的,比如stackoverflow.com/questions/45399。如果id是整数,则两者都是
提供有关问题数目的资料(即2008年9月5日,第45,399个问题被问到) 提供了一个迭代问题的杠杆点(当我将其增加1时会发生什么?我打开下一个问题)
从第一点开始,我可以结合问题的时间戳和数字来分析问题被问到的频率,以及它如何随时间变化。这在像Stack Overflow这样的网站上不太重要,因为它有公开的信息,但是,根据上下文,这可能会暴露敏感信息。
例如,我是一家为客户提供权限门控门户的公司。地址是portal.com/profile/{customerId}。如果id是一个整数,您可以通过定期查询lastKnownCustomerCount + 1来分析客户数量,而不管是否能够看到他们的信息,并检查结果是否为404 - NotFound(客户不存在)或403 - Forbidden(客户确实存在,但您没有访问权限)。
uuid的非连续性质缓解了这些问题。这并不是为了防止侧写,但这是一个开始。
如果您还将该列用作聚集索引(一种相对常见的做法),那么使用GUIDS作为主键需要考虑的另一个小问题是。你会在插入时受到打击,因为guid的本质不是按顺序开始的,因此当你插入时,它们会出现页面分割等。只是需要考虑的问题,如果系统将有高IO…
优点:
可以离线生成。 使复制变得简单(与int's相反,这使得它非常困难) ORM通常是这样的 跨应用程序惟一。所以我们可以在我们的应用程序(也guid)中使用CMS (guid)中的PK,并且知道我们永远不会发生冲突。
缺点:
更大的空间使用,但空间是便宜的 无法按ID排序以获取插入顺序。 可以在URL中看起来很丑,但真的,WTF是你在URL中放一个真实的DB键!?(这一点在下面的评论中有争议) 手动调试比较难,但也没那么难。
就我个人而言,我在任何一个相当大的系统中使用它们进行大多数PK,但我在一个到处都被复制的系统上接受了“训练”,所以我们必须使用它们。YMMV。
我认为重复数据的事情是垃圾-你可以得到重复的数据,无论你做什么。在我工作的任何地方,代理键通常都不受欢迎。我们确实使用类似于wordpress的系统:
行的唯一ID (GUID/其他)。用户永远不可见。 public ID从某些字段生成一次(例如title-让它成为the-title-of- article)
更新: 所以这一个得到了很多+1,我想我应该指出GUID PK的一个大缺点:聚集索引。
如果您有很多记录,并且在GUID上有一个聚集索引,那么您的插入性能将非常糟糕,因为您将插入到项目列表中的随机位置(这是重点),而不是在末尾(这是快速的)。
因此,如果你需要插入性能,也许可以使用auto-inc INT,如果你想与其他人共享它,则生成一个GUID(例如,在URL中向用户显示它)。
@Matt谢泼德:
假设你有一桌子的顾客。当然,您不希望一个客户在表中存在多次,否则整个销售和物流部门将会发生许多混乱(特别是当关于客户的多行包含不同的信息时)。
因此,您有一个唯一标识客户的客户标识符,并确保客户(在发票中)知道该标识符,以便客户和客户服务人员在需要沟通时有一个共同的参考。为了保证没有重复的客户记录,可以通过客户标识符上的主键或通过客户标识符列上的NOT NULL + UNIQUE约束向表中添加唯一性约束。
接下来,出于某种原因(我想不出是什么原因),要求您向客户表添加一个GUID列,并将其作为主键。如果客户标识符列现在没有惟一性保证,那么您将在整个组织中引起未来的麻烦,因为guid将始终是惟一的。
Some "architect" might tell you that "oh, but we handle the real customer uniqueness constraint in our app tier!". Right. Fashion regarding that general purpose programming languages and (especially) middle tier frameworks changes all the time, and will generally never out-live your database. And there is a very good chance that you will at some point need to access the database without going through the present application. == Trouble. (But fortunately, you and the "architect" are long gone, so you will not be there to clean up the mess.) In other words: Do maintain obvious constraints in the database (and in other tiers, as well, if you have the time).
换句话说:向表中添加GUID列可能有很好的理由,但请不要因此降低了在真实(==非GUID)信息中保持一致性的目标。