MySQL PRIMARY KEYs:UUID/GUID vs BIGINT(时间戳+随机)

LaV*_*che 17 mysql sql database performance database-design

tl; dr:如果我不想处理UUID,将{unixtimestamp} {randomdigits}(例如1308022796123456)的行ID分配为BIGINT是一个好主意吗?

只是想知道是否有人对跨多个服务器分配给数据库记录的ID/PRIMARY KEY的任何性能或其他技术考虑/限制有所了解.

我的PHP + MySQL应用程序在多个服务器上运行,数据需要能够合并.所以我已经超越了识别行的标准顺序/ auto_increment整数方法.

我对解决方案的研究使我了解了使用UUID/GUID的概念.但是,需要更改我的代码以处理在MySQL中将UUID字符串转换为二进制值似乎有点痛苦/工作.出于存储和性能原因,我不想将UUID存储为VARCHAR.

存储在二进制列中的UUID的另一个可能的烦恼是,当查看PhpMyAdmin中的数据时,行ID并不明显 - 尽管我可能错了 - 但直接数字看起来总体上要简单得多,并且在任何情况下都是通用的一种不需要转换的数据库系统.

作为一个中间点,我提出了将ID列设置为BIGINT,并使用当前unix时间戳后跟6个随机数字来分配ID的想法.所以我可以说我的随机数是123456,我今天生成的ID将会出现:1308022796123456

对于我在同一秒内创建的行冲突的可能性为1000万.我没有快速做任何类型的大规模行创建.

我用随机生成的UUID读到的一个问题是它们对索引不好,因为值不是连续的(它们遍布整个地方).MySQL中的UUID()函数通过从当前时间戳生成UUID的第一部分来解决此问题.因此,我复制了在我的BIGINT开头使用unix时间戳的想法.我的索引会慢吗?

我的BIGINT想法的优点:

  • 给我UUID的多服务器/合并优势
  • 需要对我的应用程序代码进行很少的更改(所有内容都已编程为处理ID的整数)
  • UUID的一半存储空间(8字节对16字节)

缺点:

  • ??? - 如果您能想到,请告诉我.

一些跟进问题与此相关:

  1. 我应该在末尾使用多于或少于6个随机数字?它会对索引性能产生影响吗?

  2. 这些方法之一是任何"randomer"吗?:让PHP生成6位数并将它们连接在一起-VS-让PHP生成1 - 999999范围内的数字,然后zerofilling以确保6位数.

谢谢你的任何提示.抱歉,文字墙.

Col*_*lin 14

我在职业生涯中遇到过这个问题.我们使用时间戳+随机数,并在我们的应用程序扩展时遇到严重问题(更多客户端,更多服务器,更多请求).当然,我们(愚蠢地)只使用了4位数,然后改为6位,但你会惊讶于错误仍然发生的频率.

在足够长的时间内,您可以确保获得重复的密钥错误.我们的应用程序是关键任务,因此即使是最小的机会也不可能导致固有的随机行为是不可接受的.我们开始使用UUID来避免这个问题,并仔细管理他们的创建.

使用UUID,您的索引大小将增加,而较大的索引将导致较差的性能(可能不明显,但更差).然而,MySQL支持本机UUID类型(永远不会使用varchar作为主键!!),并且即使与bigint相比也可以非常有效地处理索引,搜索等.对索引的最大性能影响几乎总是索引的行数,而不是索引项的大小(除非你想索引长篇文章或像这样荒谬的东西).

要回答你的问题:如果你不打算大幅度扩展你的应用程序/服务,那么Bigint(附带随机数字)就可以了.如果您的代码可以在没有太多更改的情况下处理更改,并且如果发生重复键错误,您的应用程序将不会爆炸,请使用它.否则,咬一口,寻求更实质的选择.

您可以随时实施更大的更改,例如切换到完全不同的后端(我们现在面临......:P)

  • 据我所知,MySQL没有UUID的列类型,只有一个生成值的函数.您存储UUID的列类型是什么?我遇到的大多数论坛帖都推荐BINARY(16)或BINARY(36).出于好奇,您要迁移到哪个数据库?为什么? (6认同)