Случайное число, которое не используется - PullRequest
0 голосов
/ 20 декабря 2011

Я пытаюсь создать уникальный номер "dosieid" для моего веб-сайта.Мой веб-сайт является программным решением для управления персоналом, в котором пользователи программы создают dosie своих работников в своей фирме ... мне нужен случайный dosieid, поэтому, когда пользователь создает dosie в поле dosieid, автоматически показывается dosieid, которые раньше не использовались ...dosieid, который не существует в базе данных.В другом случае я бы использовал автоинкремент, но в этом случае dosie еще не создан.И в форме dosieid должна быть опция для изменения числа, если случайный пользователь не в порядке.Еще одна подсказка: цифры должны быть от 1 до 9999. Кто-нибудь может мне помочь?Я пробовал много кодов, но я не нашел ничего подобного с этой спецификацией.

Это то, что я делал до сих пор.Он получает случайное число, но я не знаю, как сравнить это случайное число со строкой базы данных "dosieid"?

$id_num = mt_rand(1,9999);

$query = "SELECT dosjeid FROM albums";

$result = mysql_query($query) or die(mysql_error());

while($account = mysql_fetch_array($result)){

    if ($id_num == $account['id']){ 

        $id_num = mt_rand(1,9999);  

    }

}   
echo"$id_num<br>";

Ответы [ 4 ]

2 голосов
/ 20 декабря 2011

Это чрезвычайно запутанно ... почему не хватает числа с автоинкрементом? Этот код также никогда не будет работать должным образом. Если по какой-либо причине вы ДОЛЖНЫ использовать случайное число, то вы сделаете это так:

while(true) {
    $id_rand = mt_rand(1,9999);
    $result = mysql_query("SELECT count(*) FROM albums WHERE dosjeid=$id_rand") or die(mysql_error());
    $row = mysql_fetch_row($result);
    if ($row[0] == 0) { 
       break; // our random number isn't in the database, so exit the loop
    }
}

Однако вот некоторые проблемы с этим:

1) Вы получите бесконечный цикл, когда достигнете 9999 записей Доси
2) Чем больше записей в базе данных, тем дольше этот цикл займет поиск «свободного» слота. По мере того, как вы приближаетесь к 9999 записям, у вас будет ДОЛГОЕ время найти этот один пустой слот
3) Если вы пытаетесь «скрыть» идентификаторы любого члена, чтобы пользователи не могли просто увеличить параметр идентификатора где-нибудь, чтобы увидеть записи других людей, есть FAR FAR FAR более эффективные / более простые способы сделать это, такие как шифрование Значение идентификатора перед отправкой клиентам.

0 голосов
/ 20 декабря 2011

Это ужасный дизайн. Вы должны либо:

  1. не позволяет пользователям создавать dosieid (создайте его самостоятельно, передайте им после создания записи)
  2. Попробуйте сначала создать запись-заглушку с назначенным dosieid, а затем обновите ее с информацией
  3. или используйте UUID, для которых требуется гораздо больший диапазон, чем 1-9999

Даже если вы проверяете, что номер был уникальным, между временем, когда вы его проверяете, и временем, когда вы вставляете запись, кто-то другой мог ее взять.

И ни при каких обстоятельствах вы не должны находить пустой идентификатор, выбирая числа случайным образом. Это делает время выполнения вашей программы недетерминированным, и если вы в конечном итоге получите 5000 сотрудников, вы можете ждать долгое время .

Кроме того, этот диапазон слишком мал для требования случайности.

0 голосов
/ 20 декабря 2011

Используйте номер автоинкремента в качестве первичного ключа и дополнительный идентификатор дисплея с атрибутом UNIQUE в качестве идентификатора, показанного пользователю. Таким образом, у вас есть уникальный идентификатор для внутренней обработки и идентификатор дисплея, который можно легко изменить.

0 голосов
/ 20 декабря 2011

Возможно, вы также захотите прочитать о хешах, состоящих только из цифр (проверьте частоту столкновений алгоритма) - php: хэш только с числами?

function doesIdExists($id)
{
   $query = "SELECT dosjeid FROM albums";
   $result = mysql_query($query) or die(mysql_error());
   while($account = mysql_fetch_array($result)) 
   {
      if ($id_num == $account['id'])
           return true;  /* The id is taken */
   }
   return false; /* Not taken */
}

$recNotAdded = true;

while($recNotAdded)
{
    $rand = mt_rand(1,1000);  //Whatever your numbers
    $doesExist = doesIdExists($rand);
    if(!$doesExist)
    {
       /* Add to DB */
       $recNotAdded = false;
    }
 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...