【发布时间】:2011-09-14 09:38:03
【问题描述】:
tl;dr:如果我不想处理 UUID,那么将 {unixtimestamp}{randomdigits}(例如 1308022796123456)的行 ID 分配为 BIGINT 是个好主意吗?
只是想知道是否有人对分配给跨多个服务器的数据库记录的 ID/PRIMARY KEY 的任何性能或其他技术考虑/限制有所了解。
我的 PHP+MySQL 应用程序运行在多台服务器上,并且需要能够合并数据。所以我已经超出了识别行的标准顺序/自动增量整数方法。
我对解决方案的研究使我想到了使用 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 字节 vs 16 字节)
缺点:
- ??? - 如果你能想到任何,请告诉我。
随之而来的一些后续问题:
我应该在末尾使用多于还是少于 6 个随机数字?它会对索引性能产生影响吗?
这些方法之一是否“随机”?:让 PHP 生成 6 位数字并将它们连接在一起 -VS- 让 PHP 生成 1 - 999999 范围内的数字,然后填充零以确保 6 位数字。
感谢您的任何提示。对文字墙感到抱歉。
【问题讨论】:
-
我的问题here 提出了类似的建议,可能会让您对所涉及的考虑因素有一些进一步的了解。
-
您应该查看birthday problem 以了解对于给定数量的生成值,您需要多少随机位才能将冲突机会保持在给定阈值以下。举一个例子,16 位(正确!)随机性,如果你创建 12 个值,你(已经)有大约 0.001% 的机会发生至少一次碰撞。换句话说,如果你想生成许多值,如果你想期望唯一性,你需要相当多位。
-
使用 GUID 作为唯一索引,但 also calculate a 64-bit (BIGINT) hash of the GUID, store that in a separate NOT UNIQUE column, and index it。要检索,请查询与 both 列的匹配项 - 64 位索引应该可以提高效率。
标签: mysql sql database performance database-design