10

如果表中有这么多条目,那么 2^32 不足以满足给定时间段(日、周、月……)内的 auto_increment ID 怎么办?
如果 MySQL 提供的最大数据类型不够用怎么办?

我想知道我应该如何解决这样一种情况:我的表中添加了这么多需要唯一 ID 的条目,但我在一个时期内填写了我的数据类型?

我怎样才能在 MySQL(或任何其他系统)内实现无限数量的唯一 ID 或至少成倍增加?

理想情况下,我希望像

> SELECT * FROM table;

+---+------+
| a |  b   |
+---+------+
| 1 |  1   |
| 1 |  2   |
| 1 |  3   |
|...| .... |
|...| .... |
| 1 | 2^32 |
| 2 |  1   |
| 2 |  2   |
+---+------+

这成倍地增加了条目的数量。

你如何应对这种情况?
请记住 - 要求是任何条目都有唯一的 ID。

4

10 回答 10

17

你不觉得一个BIGINT UNSIGNED就足够了吗?这是 0 - 18.446.744.073.709.551.615 的范围,或一年每天有 50.539.024.859.478.223 条目(365 天/年),每小时 2.105.792.702.478.259 条目,每分钟 35.096.545.041.304 条目或每秒 584.942.417.355。

假设每秒写入 600 次(没有任何读取),您可以以全速写入 974.904.028 年的条目。这应该足够了。

于 2009-03-31T22:20:36.937 回答
12

您可以使用 BIGINT 作为主键。默认情况下,这是一个 64 位数字。

编辑#2:显然我之前所说的关于改变 BIGINT 字节长度的内容是不正确的。BIGINT固定8 字节限制。

于 2009-03-31T20:49:33.283 回答
7

只需使用 128 位密钥。不需要无限数量的键,因为您很快就会允许比宇宙中的原子数量更多的行。(大约 256 位)。

于 2009-03-31T20:47:13.710 回答
7

如果您有太多数据而遇到此问题,那么选择主键可能是您最不关心的问题。

如果您使用的是 InnoDB 引擎,则选择您将经常搜索的主键(尤其是在搜索返回许多行的情况下)可能有助于提高性能,因为它会聚集主键,从而更好地进行范围扫描.

于 2009-03-31T22:13:30.010 回答
5

我会先转移到 BIGINT 2 ^ 64。GUID 将是另一种选择,但您需要自己以“某种形式”存储这些

于 2009-03-31T20:51:53.123 回答
2

不要使用自动递增的主键 - 使用GUID或类似的 - 来自维基百科文章:

虽然不能保证每个生成的 GUID 都是唯一的,但唯一键的总数(2^128 或 3.4×10^38)是如此之大,以至于生成两次相同数字的概率非常小。例如,考虑可观测宇宙,它包含大约 5×1022 颗恒星;然后,每颗星都可以有 6.8×1015 个普遍唯一的 GUID。

于 2009-03-31T20:48:30.527 回答
1

当您将另一列添加到您的键时,您实际上将需要执行的索引扫描次数加倍(尽管第二列的索引要小得多)。

如前所述,VAST 数据集的最佳选择是 GUID(如果您的 RDBMS 本身支持它)或 varchar(16)。

使用 varchar / varbinary 的好处是,如果需要,您可以在将来自动扩展列。不好的部分是 varchar / varbinary 与整数相比是性能较差的键。

于 2009-03-31T22:05:18.250 回答
0

我不确定如何在 MySQL 中自动生成它们,然后它们不一定是连续的,但我很确定您可以使用 GUID 而不必担心它们会被填满。

于 2009-03-31T20:48:39.263 回答
0

您还可以使用 chars/varchars 作为键列,并使用 GUID 作为键。不过,与整数主键相比,我不知道这是否会导致性能损失。

于 2009-03-31T20:52:17.350 回答
0

如果 BIGINT 对您来说不够用,请在表中使用它,当条目数量达到 BIGINT 边界时,创建另一个表并从 0 重新开始。现在您将有 2 个表来存储相同类型的数据。

于 2020-02-04T12:53:42.777 回答