我对一个项目有要求
我们希望每月有数百万条记录添加到数据库中。
我在这里尝试过解决方法: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。高层人士认为这是可以接受的。
答案 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)