我有一个随机生成的链接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
答案 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)
在前面加上时间戳并跳过检查