生成数据库的随机ID

时间:2018-08-16 14:49:48

标签: php string random uniqueidentifier unique-key

我对一个项目有要求

  • 我需要生成唯一的ID。
  • ID必须为大写。
  • 我无法检查数据库以查看以前是否使用过ID。

我们希望每月有数百万条记录添加到数据库中。

我在这里尝试过解决方法:PHP: How to generate a random, unique, alphanumeric string? 虽然它们一开始似乎很有效,但我的测试表明,随着时间的流逝,它们会重复出现。

现在我正在使用带前缀的uniqid。我发现使用不带前缀的uniqid的问题是,当同时的请求在相同的确切时间进入服务器时,将生成重复项。我希望使用前缀可以解决此问题。
我正在考虑使用此功能:

private function generate_id()
{
    $alpha_numeric = 'ABCDEFGHIJKLMNPQRSTUVWXYZ0123456789';
    $max = strlen($alpha_numeric);
    $prefix = '';

    for ($i = 0; $i < 5; $i++)
    {
        $prefix .= $alpha_numeric[random_int(0, $max - 1)];
    }
    return strtoupper(uniqid($prefix));
}

前缀为5个字符的字母数字字符串。这足以满足我的要求吗?

*****编辑*****

按照建议的方式使用UUID是限制冲突机会的最佳方法,但是已决定采用上述方法,但是将前缀增加到7个字符。如果两个ID在同一毫秒内生成,则发生碰撞的机会约为830万中的1。高层人士认为这是可以接受的。

4 个答案:

答案 0 :(得分:0)

您是否考虑过在数据库中使用唯一键来强制唯一性?在这种情况下,您不必自己检查重复项,而是会生成唯一值,并尝试将记录插入数据库中,直到成功为止。

如果是MySQL,请阅读此内容-Using MySQL UNIQUE Index To Prevent Duplicates。如果不是,请-查找所选数据库的文档。

uniquid不能保证返回值的唯一性!使用more_entropy设置为TRUE的函数可以增加唯一值的机会。

return strtoupper(uniqid($prefix), true);

是否有必要将自己限制为仅大写字母和数字?与使用大写,小写,数字和符号相反,这将减少从函数生成的唯一值的最大数量。

您还可以考虑使用密码功能来增加随机性。

答案 1 :(得分:0)

如果您使用的是PHP7,请查看http://php.net/manual/en/function.random-bytes.php

例如

<?php
echo strtoupper(bin2hex(random_bytes(32)));
?>

应该足以满足您的要求,如果需要,可以使用更多字节。

答案 2 :(得分:0)

如果您使用Composer或外部库,请参见https://github.com/ramsey/uuid

或此功能可能满足您的需求。根据您的需求strtoupper,结果:

/**
 * generate
 *
 * Returns a version 4 UUID
 *
 * @access public
 * @return string
 */
public static function generate()
{
    $data = openssl_random_pseudo_bytes(16);

    $data[6] = chr(ord($data[6]) & 0x0f | 0x40); // set version to 0100
    $data[8] = chr(ord($data[8]) & 0x3f | 0x80); // set bits 6-7 to 10

    return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
}

请参见https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random)

答案 3 :(得分:0)

通常来说-当您无法检查数据库中的现有值时,总会有重复项。您所能做的就是将重复的可能性降低到足够低的用例。这是GUID背后的想法。

如果您确实无法访问数据库,并且如果您真的仅限于大写字符,那么我建议您使用uniqid函数生成GUID,然后删除不需要的字符并转换为大写。如果您担心会发生重复,请串联两个或多个GUID以减少这种可能性。

类似的东西:

$unique_string = str_replace(".", "", strtoupper(uniqid(uniqid(uniqid(), true), true)));