【问题标题】:How many bytes are unique enough for twitter?多少字节对于 twitter 来说是足够独特的?
【发布时间】:2012-09-10 20:59:41
【问题描述】:

我不希望我的数据库 id 是连续的,所以我尝试使用以下代码生成 uid:

$bin = openssl_random_pseudo_bytes(12);
$hex = bin2hex($bin);
return base_convert($hex, 16, 36);

我的问题是:我需要多少字节才能使 id 足够独特以处理大量记录(如 twitter)?

【问题讨论】:

  • 您为什么不希望您的数据库 ID 是连续的?如果这只是为了显示,我建议您找到一种方法来显示它们,但在您的数据库中保留顺序 ID。
  • @Brad 这样更安全,让我可以隐藏我的应用程序的增长。
  • @hugo_leonardo,重复数据?不,我根本不建议这样做!只需以不同的方式显示您的 ID。您的 ID 与安全性有什么关系?没有。我建议您仔细检查您的假设并重新评估您正在尝试做的事情。
  • 如果您有非常大的数据,您可能希望在使用 bigint 而不是字符串作为主键时节省空间和周期。就像@Brad 说的那样,在显示它们之前以某种方式散列它们。如果您使用 uuids 作为 PK,您将失去范围查询、按查询排序和范围分区(分片、...)的效率
  • @hugo_leonardo,看看 Dan 的回答。他的回答正是我的建议。您不存储这些值......它们仅用于显示。您在数据库中存储的是顺序 ID。

标签: php unique uniqueidentifier


【解决方案1】:

使用 PHP 的 uniqid(),并添加熵因子。这会给你足够的空间。

【讨论】:

  • @hugo_leonardo:是这样吗,你能预测现在会是什么吗?您怎么可能知道生成 ID 时的确切微时间。拜托,对于 99.9% 的原因来说,它是随机的,而你的看起来不像 0.01%。
  • 知道一个 id,很容易猜出下一个(或上一个)id,几乎不用蛮力。但是,无论如何......根据@Jan,id应该是数字,所以uniqid不会这样做。
【解决方案2】:

您可能会考虑类似 tinyurl 和其他缩短服务的工作方式。我使用了类似的技术,它保证了唯一性,直到用尽所有组合。所以基本上你选择一个字母,以及你想要多少个字符作为长度。假设我们使用字母数字,大写和小写,所以字母表中有 62 个字符,每个代码 5 个字符。那是 62^5 = 916,132,832 种组合。

您从顺序数据库 ID 开始,然后乘以某个素数(选择一个相当大的数字,例如 2097593)。您所做的就是将其乘以您的数据库 ID,如果超过 62^5,请确保环绕,然后根据您选择的字母将该数字转换为 base-62。

这使得每个代码看起来都相当独特,但是因为我们使用质数,所以在我们已经使用所有代码之前,我们保证不会两次点击相同的数字。而且很短。

如果长度不是问题,您也可以使用带有较小字母的较长键。

这是我问的一个问题:Tinyurl-style unique code: potential algorithm to prevent collisions

【讨论】:

    【解决方案3】:

    假设openssl_random_pseudo_bytes 可以生成所有可能的值,N 个字节将为您提供2 ^ (N * 8) 不同的值。对于 12 个字节,这是 7.923 * 10^28

    【讨论】:

      【解决方案4】:

      使用 MySQL UUID

      insert into `database`(`unique`,`data`) values(UUID(),'Test');
      

      如果您不使用 MySQL 搜索 google 的 UUID(数据库名称),它会给您一个选项

      来源维基百科

      换句话说,仅在接下来的 100 年每秒生成 10 亿个 UUID 之后,仅创建一个副本的概率约为 50%

      【讨论】:

        猜你喜欢
        • 2013-06-27
        • 2011-03-25
        • 1970-01-01
        • 2018-11-17
        • 2021-12-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-27
        相关资源
        最近更新 更多