何时您真正被迫在设计中使用UUID?

140
我真的看不出UUID的意义所在。UUID的碰撞概率虽然可以说是微乎其微,但微乎其微远远不等于不可能发生。
请问有人能举出一种不得不使用UUID的例子吗?从我看到的所有用途中,我都可以看到没有UUID的替代设计。当然,这个设计可能会稍微复杂一些,但至少它没有非零的失败概率。
对我来说,UUID就像全局变量一样。全局变量使得很多设计变得更简单,但这只是懒惰的设计方法。

26
每件事情都有失败的可能性,我建议关注更有可能发生的问题(也就是你能想到的几乎所有问题),而不是 UUID 碰撞。请注意,这里的“UUID”指通用唯一识别码。 - DanSingerman
16
“实际上,‘实质上为零’非常接近于不可能。” - mqp
21
不,事实上它离不可能无限远。 - Pyrolistical
35
当你开始使用“无限大”这样的词汇时,你已经离开了软件开发的领域。 计算机科学理论是完全不同的讨论,与编写实际软件有很大区别。 - Rex M
3
我会尽可能地关闭,主要是因为git的sha1让我相信哈希的好处。 - Pyrolistical
显示剩余4条评论
16个回答

3

关于UUID==懒设计

我不同意这是选择战斗的问题。如果重复的UUID在统计上是不可能的,并且数学已经被证明,那么为什么要担心呢?花时间在你的小型N UUID生成系统上进行设计是不切实际的,总有十几种其他方法可以改进你的系统。


1

对于那些认为UUID是糟糕设计的人,因为它们可能(在极小概率下)会发生冲突,而你的DB生成的键不会……你知道由于某些未预见的需求,人为错误导致DB生成的键发生冲突的几率远远高于UUID4冲突的几率。我们知道,如果重新创建数据库,它将重新开始ID为1,有多少人在确定永远不需要时不得不重新创建表格?当未知-未知的问题开始出现时,我会把我的钱放在UUID安全上的任何一天。


1
除非你必须使用要求UUID的其他人的API,否则总会有另一种解决方案。但这些替代方案能解决UUID解决的问题吗?你最终会添加更多的hack层,每一层都是为了解决不同的问题,而你本可以一次性解决所有问题吗?
是的,理论上UUID可能会发生碰撞。正如其他人所指出的那样,它的概率非常小,以至于根本不值得考虑。迄今为止从未发生过,很可能永远不会发生。忘掉它吧。
避免碰撞最“明显”的方法是让单个服务器在每次插入时生成唯一ID,这显然会导致严重的性能问题,并且根本无法解决离线生成问题。糟糕。
另一个“明显”的解决方案是中央机构提前分配唯一号码块,这基本上就是UUID V1通过使用生成机器的MAC地址(通过IEEE OUI)所做的。但是,重复的MAC地址确实会发生,因为每个中央机构最终都会出错,因此实际上这比UUID V4碰撞更有可能发生。糟糕。
最常用的反对使用UUID的理由是它们“太大了”,但是一个(显著)更小的方案必然无法解决最有趣的问题;UUID的大小是其在解决这些问题时有用的内在副作用。
也许你的问题不需要UUID所提供的功能,如果是这样,可以自由选择其他东西。但是,如果你的问题出乎意料地增长(大多数情况下会这样),你最终会转换为使用UUID,并且会后悔一开始没有使用它们。既然设计成功和设计失败同样容易,为什么要设计失败呢?

1
在我上一份工作中,我们从第三方获取了使用UUID唯一标识的对象。我建立了一个UUID->长整型查找表,并使用长整型作为主键,因为这样速度更快。

好的,第三方强制使用UUID是另一个问题,我不想深入讨论。假设您有控制权来使用UUID或不使用。 - Pyrolistical
1
一个“长整数”(128位)实际上就是UUID。它仅以字符串形式显示供人类使用。有时可能会以这种方式传输,但对于存储和索引来说,将其转换为整数形式肯定更快,正如您所发现的那样。 - Nicole

1

使用版本1算法,似乎在同一MAC地址下每毫秒生成少于10个UUID的约束条件下不可能发生碰撞。

从概念上讲,UUID的原始(版本1)生成方案是将UUID版本与生成UUID的计算机的MAC地址以及自西方采用公历以来的100纳秒间隔数连接起来。实际上,实际算法更加复杂。这种方案受到批评,因为它不足够“不透明”;它揭示了生成UUID的计算机的身份和生成时间。

如果我对其工作方式有误,请有人纠正我。


有很多版本,许多软件系统(例如Java)无法使用版本1,因为它没有纯Java的方式来访问MAC地址。 - Pyrolistical
关于Java无法获取MAC地址的说法并不完全正确。有一些解决方法。你可以通过配置文件手动设置生成器使用的MAC地址。你也可以调用ifconfig并解析输出。我编写的Ruby UUID生成器使用了这两种方法。 - Bob Aman
另外,正如我在答案中提到的那样,如果您无法获取版本1 UUID的MAC地址,则可以使用6个随机字节代替,根据RFC 4122第4.5节的规定。因此,即使您不想使用Java的这两种解决方法之一,您仍然可以生成有效的版本1 UUID。 - Bob Aman
MS GUIDs只是随机数字。它们不再有任何MAC部分,因为这使得反向工程服务器的MAC地址成为可能(这被证明非常危险)。 - Stefan Steiger

-11

UUID(通用唯一标识符)体现了与全局变量相关的所有糟糕编码实践,只会更糟,因为它们是超级全局变量,可以分布在不同的设备上。

最近遇到了这样一个问题,使用完全相同的打印机替换后,发现客户端软件都无法工作。


3
很高兴我们生活在一个仍然注重事实而不是随意观点的社会,否则我们 Stack Overflow 上的所有人都将失去工作。 :) - Makarand

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接