如何根据查询结果循环我的函数

时间:2012-09-06 18:52:41

标签: php mysql

我写了一个函数,它生成一个随机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。

2 个答案:

答案 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