What's your opinion on using UUIDs as database row identifiers, particularly in web apps?为了简化和(假定)速度,我一直首选使用长整数作为数据库中的主键。但是,当对对象实例使用REST或类似Rails的URL方案时,我将得到这样的URL:
然后假设存在ID为782、781,...,2和1的用户。假设所讨论的Web应用足够安全,可以防止人们输入其他数字来查看未经授权的其他用户,简单的顺序分配的代理密钥也会"泄漏"实例总数(比该实例旧),在这种情况下为用户,这可能是特权信息。 (例如,我是stackoverflow中的用户#726。) UUID / GUID会是更好的解决方案吗?然后,我可以像这样设置URL:
并非十分简洁,但所显示的用户隐含信息较少。当然,它带有"模糊不清的安全性",这不能代替适当的安全性,但似乎至少更安全一些。 对于Web可寻址对象实例,实现UUID的成本和复杂性是否值得这样做?我认为我仍然想使用整数列作为数据库PK,只是为了加快连接速度。 还有UUID的数据库内表示形式的问题。我知道MySQL将它们存储为36个字符的字符串。 Postgres似乎具有更有效的内部表示形式(128位?),但我自己没有尝试过。有人对此有经验吗? 更新:对于那些询问仅使用URL中的用户名(例如http://example.com/user/yukondude)的用户来说,这对于名称唯一的对象实例非常适用,但无数的网络又如何呢?只能通过数字识别的应用程序对象?订单,交易,发票,重复的图像名称,stackoverflow问题,...
关于您的问题,我不能说。但是uuid对于n层应用程序非常有用。 PK生成可以分散:每个客户生成自己的pk,而不会发生冲突。
确保您的数据库支持有效的存储数据类型(16字节,128位)。 我在Firebird中广泛使用了它们,并推荐使用。 对于它的价值,我已经看到了一个很长的存储过程(9+秒),只需将GUID主键切换为整数,就可以将运行时间降至几百毫秒。并不是说显示GUID是一个坏主意,但是正如其他人指出的那样,按照定义,加入它们并为它们建立索引不会像使用整数那样快。 我可以回答您,在SQL Server中,如果您使用uniqueidentifier(GUID)数据类型并使用NEWID()函数创建值,由于页面拆分,您将得到可怕的碎片。原因是使用NEWID()时,生成的值不是连续的。 SQL 2005添加了NEWSEQUANTIAL()函数来解决这一问题 仍然使用GUID和int的一种方法是在表中有一个guid和一个int,以便该guid映射到int。 guid在外部使用,但在数据库内部使用int 例如
1和2将用于Web应用程序的联接和向导中。该表将非常狭窄,并且应该可以快速查询 为什么将主键与URI耦合? 为什么不让URI密钥对人类可读(或根据您的需要是不可猜测的)以及基于主索引整数的,那么您就可以兼得两者。许多博客软件都这样做,其中条目的公开ID由"子弹"标识,而数字ID隐藏在系统内部。 这里增加的好处是您现在有了一个非常不错的URL结构,这对SEO很有用。显然,对于事务而言,这不是一件好事,但是对于诸如stackoverflow之类的事情而言,这很重要(请参见URL顶部...)。获得独特性并不难。如果您真的很担心,可以将表子的哈希存储在表中的某个位置,并在插入之前进行查找。 编辑:Stackoverflow不太使用我描述的系统,请参见下面的盖伊评论。 我们将GUID用作所有表的主键,因为它是MS SQL Server复制的RowGUID的两倍。当客户突然在世界其他地方开设办事处时,这非常容易。
您可以使用与行号相关但不连续的整数。例如,您可以采用顺序ID的32位,并采用固定方案对其进行重新排列(例如,位1变为位6,位2变为位15,依此类推。)。 而不是像这样的URL:
为什么不拥有:
哪一个对人类更友好,并且不会泄漏出很少的信息? 它还取决于您对应用程序关心的内容。对于n层应用程序,GUID / UUID易于实现,并且更易于在不同数据库之间移植。为了产生Integer键,某些数据库本机支持序列对象,而某些则需要自定义构造序列表。 整数键(我没有数字)可能为查询和索引性能以及空间使用情况提供了优势。使用数字键也可以更直接地进行DB查询,减少复制/粘贴的次数,因为它们更容易记住。 我认为GUID不会给您带来很多好处。用户讨厌冗长,难以理解的URL。 创建一个较短的ID,您可以将其映射到URL,或强制执行唯一的用户名约定(http://example.com/user/brianly)。 37Signals的家伙可能会嘲笑您担心Web应用程序之类的问题。 顺便说一句,您可以强制数据库从基础值开始创建整数ID。 我已经在真实的Web应用程序中尝试过。 我的观点是,最好使用整数并具有简短的可理解网址。 作为开发人员,看到连续的整数并知道一些有关总记录数的信息正在泄漏,这让您感到有些恐惧,但是说实话-大多数人可能不在乎,而且这些信息对我的业务从未真正重要。 在我看来,冗长的UUID网址看起来更像是普通用户无法使用的网址。 我使用的学生管理系统使用整数形式的UUID。他们有一个保存下一个唯一ID的表。 尽管从体系结构的角度来看这可能是个好主意,但它使日常工作变得困难。有时需要进行批量插入,而拥有UUID则非常困难,通常需要编写游标而不是简单的SELECT INTO语句。 YouTube使用11个具有base64编码的字符,可提供11 ^ 64的可能性,并且通常可以很容易地编写它们。我不知道这是否会提供比完整的UUID更好的性能。转换为基数为64的UUID大小是我认为的两倍。 可以在此处找到更多信息:https://www.youtube.com/watch?v=gocwRvLhDf8 我认为这是引起准宗教辩论的问题之一,谈论起来几乎是徒劳的。我只是说用你喜欢的。在99%的系统中,无论您使用哪种类型的密钥,因此使用一种类型的密钥(而不是另一种类型)的好处(在其他文章中都有说明)都不会成为问题。 我认为在您的情况下使用GUID是更好的选择。它占用更多空间,但是更安全。 只要您使用具有高效存储的数据库系统,如今无论如何,HDD还是便宜的。 我知道GUID有时可能会很麻烦,并带有一些查询开销,但是从安全角度来看,它们是一个救星。 通过模糊性来考虑安全性,它们很适合在形成模糊的URI并使用Table,Record和Column定义的安全性来构建归一化的DB时,GUID不会出错,请尝试使用基于整数的id来实现。 |