我有这个脚本:
$rrezervim_id = rand(1, 5);
$result = mysql_query("SELECT rrezervim_id FROM pax_list WHERE rrezervim_id='$rrezervim_id'");
if(mysql_num_rows($result) == 1)
{
$rrezervim_id = rand(1, 5);
}
else(mysql_num_rows($result) > 1);
{
echo "$rrezervim_id";
}
我想做的是使用PHP和MySql生成一个唯一随机数我在表中有值(rrezervim_id)[Values:1,2,3,5],所以必须生成的唯一空闲随机数是数字4。但使用这个脚本,有些东西不起作用,因为我得到了甚至是已经插入表中的随机值[Values:1,2,3,5]。
任何人都可以帮助我,如果表中已经存在,在生成唯一编号之前在mysql中进行检查是非常重要的。
首先,代码中的直接错误是
if(mysql_num_rows($result) == 1)
{
$rrezervim_id = rand(1, 5);
}
失败,如果您两次命中一个的号码。你需要一个循环,比如
while (mysql_num_rows($result) == 1)
{
$rrezervim_id = rand(1, 5);
$result = mysql_query("SELECT rrezervim_id FROM pax_list WHERE rrezervim_id='$rrezervim_id'");
}
也就是说,我怀疑,你的代码有更多的错误:
如果你想在以后的某个时间点使用这个"空闲"随机数将其插入数据库,那么你很容易遇到竞争条件:两个进程都选择相同的(仍然空闲的)数字,但只有在第一次插入时,它才是唯一的。
如果你的可能随机数字段几乎满了,这种方法可能会有非常糟糕的性能:如果你有80%的填充率,比如在你的例子中,在得到"好"命中之前,你平均会有4次"坏"命中。
我建议您考虑使用内置的数据库,例如久经沙场的AUTO_INCREMENT作为主要手段,然后使用一个公式从中创建难以猜测的伪随机。线性反馈移位寄存器可以是一种方法,而将自动生成的ID和存储在表中的(不一定唯一的)伪随机进行加密组合可能是另一种方法。这两种方法都能为您提供线性性能和无种族限制的使用。
您可以在php 中创建唯一的数字
<?php
echo uniqid();
?>
但你应该使用自动增量。如果你想知道插入的项目是通过哪个号码保存的,可以使用这样的东西:
function insertUser(){
Global $userName;
$sqlInsert="INSERT INTO person (e_mail)
VALUES ('".$userName."')";
if (!mysql_query($sqlInsert)){
die('Error: ' . mysql_error());
}
$userId = mysql_insert_id();
return $userId;
}
$userId是最后插入的值
由于您没有使用AUTO_INCREMENT,建议(这很慢)选择所有有效的数字并随机选择1。
如果我们有[1,2,3,5,7],并且我们允许的元素是1..10,那么我们有5个允许的元素(4,6,8,9,10)。所以我们兰特(1,5)。如果我们得到"1",我们的下一个数字是4,如果我们得到"2",我们的第二个数字是6。为了更好地解释这个想法:
Rand(1,5) Our array Value(available)
1
2
3
1 - 4
5
2 - 6
7
3 8
4 9
5 10
代码示例:
$max_num = 100;
$res = mysql_query("SELECT rrezervim_id FROM pax_list ORDER BY rrezervim_id ASC");
$nums = [];
while($row = mysql_fetch_assoc($res)){
$nums[] = $res['rrezervim_id'];
}
$numbers_allowed = $max_num - count($nums); // actual number of allowed elements
$new_num_idx = rand(1, $numbers_allowed); // The selected element's index
(skipping all existing elements)
// in the following loop: $j starts as our lowest options.
// when $new_num_idx reaches 0 - it means that we have skipped
// over $new_num_idx elements. The next available element is
// our choice. $new_num_idx is a countdown
for($i=0,$j=1, $n=count($nums); $i<$n && $new_num_idx > 0; $i++){
while ($nums[$i]>$i+$j){
$j++; $new_num_idx--;
}
}
return $i+$j;