0

我编写了一个生成随机 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 可用则插入。

4

2 回答 2

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(运行时间95ms);

我绝对不建议重复运行查询。如果您的流量足够高,也许在您插入之前进行最后检查。

于 2012-09-06T18:57:31.990 回答
-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 将使用所有数字 + 字母,因此您将以 结尾PREFIX-AX3TK,因此字符串为你想要,同时你可以很容易地快速生成下一个 Id

于 2012-09-06T19:02:08.867 回答