关于检查唯一ID的逻辑事项?

时间:2010-07-27 15:24:17

标签: php mysql

我有一个随机生成的链接ID,长度为8位,每位数为50,这意味着4x10 ^ 13种可能的组合(我认为)。我每天大约有成千上万的查询。

我的问题是,我应该检查4个表每个查询重复项,还是跳过它?或者使它成为10位数,以便绝对不匹配?

编辑:

我的(可能是复制的)生成器

// START Generates Random String
function genRandString($len=8){
$base='ABCDEFGHKLMNPQRSTWXYZabcdefghjkmnpqrstwxyz23456789';
$max=strlen($base)-1;
$randstring1 ='';
mt_srand((double)microtime()*1000000);
while (strlen($randstring1)<$len+1)
$randstring1.=$base{mt_rand(0,$max)};
return $randstring1;
}
// END Generates Random String

2 个答案:

答案 0 :(得分:3)

这取决于伪随机数发生器的质量。你可能没有足够的熵,所以你更容易发生碰撞。

您有没有使用UUID()的原因?它似乎是为此目的而设计的最佳解决方案。

无论如何,我建议您在插入之前检查重复项。这取决于竞争条件,也就是说,有人可以在您检查之后但在插入之前插入重复值。因此,您无论如何都必须处理重复的密钥违例异常。最好只是尝试插入(不先检查)并根据需要处理异常。


重新评论您的评论和算法:我不会使用该散列方案。在50个不同值的四位数中,您的information位数少于24位。因此,一旦数据库中有几千行,您的chance of collision就非常重要。

此解决方案如何:使用单调递增的主键值,例如AUTO_INCREMENT。要将此数字更改为字母数字字符串,请使用base_convert()

$id = 12345678;
$str = base_convert($id, 10, 36);
echo "$str\n";

结果为7clzi

如果你担心像1,l,i,0,o这样的字母混淆,你可以做一些自定义替换:

$from = array('1', 'l', 'i', '0', 'o');
$to   = array('A', 'B', 'C', 'D', 'E');
$str = str_replace($from, $to, $str);

现在,值12345678已转换为7cBzC。当有人通过此代码请求页面时,请反向进行转换:

$code = str_replace($to, $from, $code);
$id = base_convert($code, 36, 10); 

答案 1 :(得分:0)

在前面加上时间戳并跳过检查