Генерация случайных чисел в Mysql PHP - PullRequest
0 голосов
/ 15 декабря 2009

У меня 16 миллионов записей, и мне нужно 8-значное УНИКАЛЬНОЕ случайное число для каждой записи, также я хочу, чтобы все числа начинались с 01, и я сохраняю их в отдельной таблице, чтобы я мог назначить УНИКАЛЬНЫЕ номера для каждой записи.

Я не уверен, как это сделать в PHP, чтобы получить 16 миллионов уникальных номеров?

Пожалуйста, помогите?!

J.

Ответы [ 8 ]

4 голосов
/ 15 декабря 2009

С тем, что вы указали, это кажется невозможным.

Вам требуется 16 000 000 уникальных номеров из данного 8-значного номера, из которых ведущим 2 является 01 .

Это оставляет вам только 6 чисел , поэтому ваш диапазон будет 1 000 000 чисел

от 01000000 до 01999999 .

Это не кажется правильным.

1 голос
/ 15 декабря 2009

Джон, в отношении вашего комментария к pavium, если вам нужно, чтобы все числа имели одинаковую длину, но не обязательно случайную, вы можете использовать свойство MySQL ZEROFILL вместе с индексом auto_increment.

0 голосов
/ 23 декабря 2009

Мне нравится использовать 16-символьный базовый-60 varchar для моих случайных первичных ключей. Вот крошечный столик:

mysql> create table foo (k varchar(16), v varchar(255), primary key(k));

... и вот небольшой элементарный PHP, который будет нажимать на функцию k (), пока не найдет неиспользуемый ключ.

<?php

require_once 'connect.php';

$v = 'A value that needs a unique random key.';

while (!mysql_query("INSERT INTO foo VALUES ('" . k() . "', '$v')")) {};

function k() {
   $t = "0123456789ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
   $r = "";
   for ($i = 0; $i < 16; $i++) {
      $r .= substr($t, rand(0, 59), 1);
   }
   return $r;
}

?>

Вероятность столкновения невелика - от 60 до 16 - поэтому k () почти никогда не вызывается дважды. Бонус: если мне когда-нибудь понадобится увеличить этот ключ, то это varchar, поэтому я могу добавлять байты, не удаляя все, что уже есть в таблице.

0 голосов
/ 15 декабря 2009

пусть MySQL сделает это за вас:

  1. создать столбец auto_increment
  2. добавить 100000000, используя ОБНОВЛЕНИЕ
  3. сделано!

если вам действительно нужен начальный ноль, то удалите auto_increment из столбца, измените его на varchar (10) и добавьте 0, используя UPDATE

0 голосов
/ 15 декабря 2009

Вместо генерации случайного числа и борьбы с сохранением выбранных номеров треков, как насчет генерации числа в последовательности, но обновления записей в случайном порядке?

Итак, это полностью MySQL решение. Нет PHP, нет цикла, просто оператор пакетного обновления:

UPDATE 
   your_table, 
   (SELECT @rownum:=@rownum+1 rownum, t.id 
    FROM 
      (SELECT @rownum:=0) r, 
      (SELECT id FROM your_table ORDER BY RAND()) t
   ) p 
SET unique_num = 100000000 + p.rownum 
WHERE p.id = your_table.id

Замените your_table именем таблицы, unique_num - столбцом, в котором будет храниться уникальный номер, и id - столбцом первичного ключа вашей таблицы.

p / s: тестирование работало как минимум на MySQL 5.1.37

0 голосов
/ 15 декабря 2009

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

.. и они будут сгенерированы MySQL, а не PHP. Я думаю, что это будет значительным расходом на создание 16 миллионов случайных, но различных чисел в PHP.

Числа имеют , чтобы быть случайными? Возможно, уникальность является более важным требованием?

0 голосов
/ 15 декабря 2009

Самый простой способ - сначала создать список чисел чисел 16M и отсортировать их случайным образом, а затем сопоставить каждое из них с вашей записью, что в значительной степени выполняется в собственных функциях PHP.

Я добавил шаговый цикл, чтобы он не генерировал слишком большой массив. Но это также означает, что идентификатор будет выглядеть как инкремент, но все же случайные числа.

Может быть, кто-то может предложить лучшее решение, используя вращающуюся струну? Я сейчас на работе. :)

0 голосов
/ 15 декабря 2009

Попробуйте: GUID

<? 
    echo str_replace ("}","",str_replace("{","",com_create_guid()));
?>
...