0

我需要生成一个格式为 105-##### 的随机数,并且在将其保存到数据库之前,我需要根据已创建的数字检查这个生成的数字,以确保它不存在。

这是我生成数字本身的代码:

$digits = 5;
$second_num = str_pad(rand(0, pow(10, $digits)-1), $digits, '0', STR_PAD_LEFT);
$order_gen = "105-".$second_num;

既然我有了这个 $order_gen 编号,那么循环遍历 order_number 数据库表中已有的内容以确保没有重复项的最佳方法是什么?我正在考虑使用 while 循环,但不知道如何应用它。

4

3 回答 3

1

我能想到的有3个选项:

  1. 生成一个id并查询看看是否被使用。如果使用,生成另一个并重复,直到找到一个未使用的。这可能是最慢的。

  2. 有一张包含所有可能 ID 的表格。从该表中选择一个随机行,使用该 ID 并将其删除,这样就不会再次使用它。不过,这需要一个仅用于保存这些 id 的表。根据您的需要,这可能是不可能的。

  3. 在 PHP 中,按 id 顺序查询所有现有的 id。循环结果并制作一个包含所有 id 的数组。从那里您可以生成,如果存在于数组中,则再次像 #1 那样生成,或者制作一个包含所有可能 id 的数组,array_diff($allIDS, $usedIDs)以查找未使用的 ID,并使用 array_rand 获取随机 ID。此选项在 php 中使用更多内存,必须查询所有现有 id。

如果两个请求同时发生,所有 3 种方法都可能会受到竞争条件的影响,其中 id 可能会重复。#2 可能最容易防止竞争条件。在删除查询中,检查受影响行的计数(如果使用 PDO,则为 PDOStatement::rowCount),如果为 0,则假设在您使用它并获得另一个 id 之前其他人得到了它。

于 2013-10-30T22:31:55.907 回答
1

给定您的算法,除了为您生成的每个 ID 查询数据库之外,没有更好的方法,直到找到一个未被使用的 ID。

将整个内容包装在一个do/while语句中,并定义一个通过该随机 ID 查询数据库的方法,如果记录存在则返回 true,否则返回 false:

do {
  $digits = 5;
  $second_num = str_pad(rand(0, pow(10, $digits)-1), $digits, '0', STR_PAD_LEFT);
  $order_gen = "105-".$second_num;
} while (record_exists($order_gen);

或者,随机生成一次,然后递增,直到找到未使用的数字:

$digits = 5;
$second_num = str_pad(rand(0, pow(10, $digits)-1), $digits, '0', STR_PAD_LEFT);
$order_gen = "105-".$second_num;

while (record_exists($order_gen) {
  $second_num += 1
  $second_num = str_pad($second_num, '0', STR_PAD_LEFT);
  $order_gen = "105-".$second_num;
}
于 2013-10-30T22:20:09.760 回答
-1

这可以完成工作

$rand = mt_rand(000123,999999); //prefix between 000123 to 999999
$id = "105".$rand;

$error = true;
while($error){
 $query = "SELECT id FROM table WHERE id = '$id'";
 $result = mysqli_query($conn,$query);
 $count = mysqli_num_rows($result);
  if($count!=0){
   $error = true;
   $rand = mt_rand(000123,999999);
   $id = "105".$rand;    
  }else{
   $error = false;
  }
}
于 2017-08-02T17:10:07.443 回答