我写了一个函数,它生成一个随机id makeid();
为了确保id是唯一的,我有一个SQL语句来检查id是否已经存在。
$does_id_exist = mysql_query("SELECT COUNT(*) AS count FROM signups WHERE affid='$affid'");
if(mysql_num_rows($does_id_exist) == 1)
{
#loop function and perform query again
}
else
{
#insert record
}
所以我在循环函数方面遇到了麻烦。如何循环我的函数makeid()
并执行$does_id_exist
检查以确保每个ID
都是唯一的。
- 更新 - 只是为了澄清 - 我的代码创建了一个像YES@281E
的ID但是在我将这个id插入用户记录之前。我只需要验证其他用户是否已拥有此ID。如果另一个用户具有此id,则该事件必须触发我的函数以创建新的id,例如WOW!29E3
并再次检查sql / query以确保没有其他用户该id 。如果失败则继续循环或结束,如果id可用则继续INSERT。
答案 0 :(得分:0)
您可以只在数据库表上使用主键,或类似的东西:
<?php
// the id to insert
$newId = null;
// populate with results from a SELECT `aff_id` FROM `table`
$currentIds = array();
// prepopulate
for( $i=0; $i<100000; $i++ )
{
$currentIds[] = "STRING_" + rand();
}
// generate at least one id
do
{
$newId = "STRING_" + rand();
}
// while the id is taken (cached in $currentIds)
while( in_array($newId, $currentIds) );
// when we get here, we have an id that's not taken.
echo $newId;
?>
输出:
STRING_905649971(运行时间95毫秒);
我绝对不建议重复运行查询。如果您的流量足够高,也许在插入之前进行最后检查。
答案 1 :(得分:-1)
不要COUNT(*)
,因为你不需要知道有多少行(它应该是0或1,因为你需要Id唯一),所以即使DB找到你的行仍然会检查整个表要算。如果你有1行,你真的很在意,所以只需选择具有该ID的行即可。您还应该避免使用rand()
- 这看起来没有帮助,您无法预测在找到“空闲插槽”之前可以执行多少循环。每天使用可预测的内容,例如日期前缀或前缀递增。任何可以帮助您缩小数据集的东西。但是现在(伪代码!):
$id = null;
while( $id == null ) {
$newId = 'prefix' . rand();
mysql_query("SELECT `affid` FROM `signups` WHERE `affid`='${newId}'");
if( mysql_num_rows() == 0) {
$id = newId;
break;
}
}
确保您已将数据库编入索引,以加快速度。
编辑:我同意任何缓存对加快速度都很有用(你可以根据@Josh示例自己轻松添加),但是,我认为这是在错误的地方修复。如果可能,请重新考虑您生成ID的方式。它实际上并不需要自动增量,但比rand()
更可预测的东西会对你有帮助。如果您的ID不需要容易记忆,并且使它们顺序不是任何安全问题,可以使用其他10以上的数字(即使用26将使用所有数字+字母,因此您以{{1}结尾},所以你想要的字符串,同时你可以很容易地快速生成下一个Id