Pyr*_*cal 116 architecture uuid
我真的没有看到UUID的观点.我知道碰撞的可能性实际上是零,但实际上零甚至几乎不可能.
有人可以举个例子,除了使用UUID之外别无选择吗?从我见过的所有用途中,我可以看到没有UUID的替代设计.当然设计可能稍微复杂一点,但至少它没有非零概率的失败.
UUID闻起来像全球变量.全局变量有许多方法可以实现更简单的设计,但它只是懒惰的设计.
Bob*_*man 588
我为Ruby编写了UUID生成器/解析器,所以我认为自己在这个问题上有了相当的了解.有四个主要的UUID版本:
版本4 UUID基本上只是从加密安全随机数生成器中提取的16字节随机性,有些比特用于识别UUID版本和变体.这些都不太可能发生冲突,但是如果使用PRNG,或者你碰巧真的,真的,真的,真的,真的是运气不好,就会发生这种情况.
版本5和版本3 UUID分别使用SHA1和MD5散列函数,将命名空间与一段已经唯一的数据组合以生成UUID.例如,这将允许您从URL生成UUID.只有当底层哈希函数也有冲突时,才可能发生冲突.
版本1 UUID是最常见的.他们使用网卡的MAC地址(除非欺骗,应该是唯一的),加上时间戳,再加上通常的比特,以生成UUID.在没有MAC地址的机器的情况下,使用加密安全随机数生成器生成6个节点字节.如果顺序生成两个UUID足够快以使时间戳与先前的UUID匹配,则时间戳增加1.除非发生以下情况之一,否则不应发生冲突:MAC地址是欺骗性的; 运行两个不同UUID生成应用程序的一台机器在同一时刻生成UUID; 没有网卡或没有用户级访问MAC地址的两台机器被赋予相同的随机节点序列,并在同一时刻生成UUID; 我们用完字节来表示时间戳并将翻转回零.
实际上,这些事件都不会在单个应用程序的ID空间中偶然发生.除非您在互联网范围内接受ID,或者在恶意个人可能在ID冲突的情况下做坏事的不受信任的环境,否则您不应该担心.至关重要的是要理解,如果您碰巧生成与我相同的版本4 UUID,在大多数情况下,它并不重要.我在与您完全不同的ID空间中生成了ID.我的应用程序永远不会知道碰撞,因此碰撞无关紧要.坦率地说,在没有恶意攻击者的单个应用程序空间中,即使在版本4 UUID上,即使你每秒生成相当多的UUID,地球上所有生命的灭绝也会在你发生碰撞之前很久就会发生.
此外,2 ^ 64*16是256艾字节.同样,在单个应用程序空间中有50%的机会发生ID冲突之前,您需要存储256 EB的ID.
Mic*_*urr 67
UUID给你买的非常难以做到的事情就是获得一个唯一的标识符,而不必咨询或协调中央机构.在没有某种托管基础设施的情况下能够获得这样的事情的一般问题是UUID解决的问题.
我已经读过,根据生日悖论,一旦生成2 ^ 64个UUID,UUID发生碰撞的可能性为50%.现在2 ^ 64是一个相当大的数字,但是50%的碰撞几率似乎风险太大(例如,在碰撞机率为5%之前需要存在多少UUID - 即使这看起来有太大的概率) .
该分析的问题有两个方面:
UUID并非完全随机 - UUID的主要组件是基于时间和/或位置的.因此,为了在碰撞中有任何真正的机会,冲突的UUID需要在不同的UUID生成器的同时生成.我会说,虽然有可能同时生成几个UUID,但是还有足够的其他gunk(包括位置信息或随机位)来使这个非常小的UUID集之间的冲突几乎不可能.
严格地说,UUID只需要在可以与之比较的其他UUID集中是唯一的.如果您要生成UUID以用作数据库密钥,那么在邪恶的备用Universe中的其他位置使用相同的UUID来标识COM接口并不重要.就像在Alpha-Centauri上有一个名叫"Michael Burr"的人(或其他东西)一样,它不会引起混淆.
Rex*_*x M 16
强调"合理地"或者,正如你所说,"有效地":足够好就是现实世界的运作方式.覆盖"实际上独特"和"真正独特"之间差距所涉及的计算工作量是巨大的.唯一性是一种收益递减的曲线.在该曲线的某个点上,在"足够独特"仍然可以承受的位置之间存在一条线,然后我们曲线非常陡峭.增加更多唯一性的成本变得非常大.无限的独特性具有无限的成本.
相对而言,UUID/GUID是一种计算上快速简便的生成ID的方法,可以合理地假设该ID 是普遍唯一的.这在需要集成来自先前未连接系统的数据的许多系统中非常重要.例如:如果您有一个在两个不同平台上运行的内容管理系统,但在某些时候需要将内容从一个系统导入另一个系统.您不希望更改ID,因此系统A中的数据之间的引用保持不变,但您不希望与系统B中创建的数据发生任何冲突.UUID解决了这个问题.
Joh*_*zen 15
创建UUID绝不是绝对必要的.然而,有一个标准是方便的,其中离线用户可以各自生成具有非常低的碰撞概率的东西的密钥.
这有助于数据库复制解决等...
在线用户很容易为没有开销或可能发生冲突的事情生成唯一的密钥,但这不是UUID的用途.
无论如何,从维基百科中得到一个关于碰撞概率的词:
为了正确看待这些数字,人们每年被陨石击中的风险估计为170亿的一次机会,相当于一年内创造数十万亿UUID并且有一个重复的可能性.换句话说,只有在接下来的100年中每秒产生10亿UUID之后,创建一个副本的概率大约为50%.
use*_*714 12
你的身体中的每个粒子都会同时穿过你所坐的椅子,并且你会突然发现自己坐在地板上的概率非零.
你担心吗?
Joh*_*lan 11
一个典型的例子是在两个数据库之间进行复制时.
DB(A)插入一个int ID为10的记录,同时DB(B)创建一个ID为10的记录.这是一个冲突.
使用UUID,这不会发生,因为它们不匹配.(几乎可以确定)
我有一个避免UUID的计划.地方设置一台服务器,并将它让每一位了一个软件想要一个通用唯一标识符时,他们联系该服务器,并将其一只手出来.简单!
除非有一些真正的实际问题,即使我们忽视了彻头彻尾的恶意.特别是,该服务器可能会失败或无法访问部分互联网.处理服务器故障需要复制,而且很难做到正确(请参阅Paxos算法的文献,了解为什么建立共识很尴尬)并且速度也很慢.此外,如果所有服务器都无法从网络的特定部分访问,则连接到该子网的任何客户端都无法执行任何操作,因为它们都将等待新的ID.
所以...使用一个简单的概率算法来生成它们,这些算法在地球的生命周期中不太可能失败,或者(资金和)构建一个主要的基础设施,它将成为部署PITA并经常出现故障.我知道我要去哪一个.
我没有得到所有关于碰撞可能性的讨论。我不在乎碰撞。不过我关心性能。
https://dba.stackexchange.com/a/119129/33649
UUID 是非常大的表的性能灾难。(200K 行不是“非常大”。)
当 CHARCTER SET 为 utf8 时,您的 #3 真的很糟糕——CHAR(36) 占用 108 个字节!
UUID (GUID) 非常“随机”。在大表上将它们用作 UNIQUE 或 PRIMARY 键是非常低效的。这是因为每次插入新的 UUID 或按 UUID 选择时都必须在表/索引之间跳转。当表/索引太大而无法放入缓存时(请参阅 innodb_buffer_pool_size,它必须小于 RAM,通常为 70%),“下一个”UUID 可能不会被缓存,因此磁盘命中速度较慢。当表/索引是缓存的 20 倍时,只有 1/20 (5%) 的命中被缓存——您受 I/O 限制。
所以,不要使用 UUID,除非
你有“小”表,或者你真的需要它们,因为从不同的地方生成唯一的 id(并且还没有想出另一种方法来做到这一点)。有关 UUID 的更多信息:http : //mysql.rjweb.org/doc.php/uuid(它包括在标准 36 字符 UUID 和 BINARY(16) 之间转换的函数。)
在同一个表中同时拥有 UNIQUE AUTO_INCREMENT 和 UNIQUE UUID 是一种浪费。
发生 INSERT 时,必须检查所有唯一/主键是否重复。任何一个唯一键都足以满足 InnoDB 对 PRIMARY KEY 的要求。BINARY(16)(16 字节)有点庞大(反对将其作为 PK 的论点),但还不错。当您有辅助键时,体积很重要。InnoDB 默默地将 PK 附加到每个辅助键的末尾。这里的主要教训是尽量减少辅助键的数量,特别是对于非常大的表。作为比较:INT UNSIGNED 是 4 个字节,范围为 4 亿。BIGINT 是 8 个字节。
| 归档时间: |
|
| 查看次数: |
36582 次 |
| 最近记录: |