使用 MySQL 生成非顺序、仅限整数的 UUID 的最快方法?
Posted
技术标签:
【中文标题】使用 MySQL 生成非顺序、仅限整数的 UUID 的最快方法?【英文标题】:Fastest way to generate a non-sequential, integers-only UUID with MySQL? 【发布时间】:2022-01-22 10:13:42 【问题描述】:我正在尝试使用 mysql 生成 非顺序、仅整数 UUID,并尽可能获得最佳性能。
我知道 MySQL 已经提供了多种方法来生成可靠的 UUID:
UUID v4:非常独特,但 slow 并存储为 UUID 类型 UUID v1:类似,但可以是连续的,稍微提高索引性能 UUID_SHORT(): 最佳性能,更短,存储在 64 位 BIG INT 上,但连续但是,这些解决方案都没有提供非顺序(它将公开显示,我不希望用户能够跟踪增长/增量)和仅整数 UUID (用于性能)。
使用 RAND() 是不可能的,因为冲突太高,即使对于
除了将 UUID_V1 转换为十进制之外,还有什么聪明的解决方案吗?
【问题讨论】:
RAND() 不是碰撞安全的。 我认为他的意思是有可能随机生成 2 个相同 id 的机会,尽管机会很小。如果一切都失败了,您可以生成一个普通的 GUID,删除-
字符,然后使用 CONV
将其从基数 16 转换为基数 10。这将为您提供 20 位数字。
@Simulant 即使 uuid 也不能保证避免碰撞。这是可以接受的,因为碰撞的可能性是如此之小,以至于人们认为它“永远不会”发生。
@Bruno 为 1M 记录使用 2^32 个 uuid,您保证会发生冲突。在大约 70K 行中,有 50% 的变化是两个将具有相同的 uuid。请参阅Birthday problem 了解为什么会这样。至少需要 64 位的 uuid,128 位会更好。
您是否想要nnnnnnnn-nnnn-nnnn-nnnn-nnnnnnnnnnn
形式的字符串,其中n
是数字(不是字母十六进制字符)?还是nnnnnnnnnnnnnnnnnnnnnnnnnnnnnnn
好吗?
【参考方案1】:
您的问题首先是数学问题,然后是编程问题。
我会考虑简单的:M = (M + N) % (2^32)
来获得 M
的“下一个”值。
其中 N 是一个大的正奇整数。
M 是要使用的“下一个”数字。 (它可以用你喜欢的任何东西初始化)。
它将生成 2^32 个不同的数字,然后重复。
2^32 可以是 2 的任意幂。实际上,关键是 2^32 和 N 没有任何共同因子(1
除外)。
小心%
;您使用的语言可能使用 32 位有符号数字。或者可能是 64 位的。在当今的大多数语言中,2^16 都可以使用。但它会将您限制为 65536 个值。
% 2^P
也可以使用位掩码来完成。
Rand() 仅在 2^30 个值后重复,但 RAND() * 99999
可能在前 99999 次迭代中有一些重复。有些随机数生成器持续时间更长。
1M 值大约是 20 位。所以 2^20 有效。或使用& 0xFFFFF
屏蔽。
如果您还转换为十六进制,则所有代码都可以是 5 个字符。 TO_BASE64()
会将其压缩为 4 个字符。
【讨论】:
以上是关于使用 MySQL 生成非顺序、仅限整数的 UUID 的最快方法?的主要内容,如果未能解决你的问题,请参考以下文章