У меня есть 16 миллионов записей и для каждой записи требуется 8-значное UNIQUE случайное число, также я хочу, чтобы все числа начинались с 01 и сохраняли их в отдельной таблице, поэтому я могу назначить UNIQUE номера для каждой записи.
Я не уверен, как это сделать в PHP, чтобы получить 16 миллионов уникальных номеров?
Пожалуйста, помогите?!
J.
С тем, что вы указали, это не представляется возможным.
Вам требуется 16 000 000 уникальных номеров из заданного 8-значного номера, из которых ведущий 2 01.
Это оставляет вам только 6 номеров, поэтому ваш диапазон будет 1 000 000 чисел
от 01000000 до 01999999.
Это не выглядит правильным.
Джон, относительно вашего комментария к pavium, если вам нужно, чтобы все числа имели точно такую же длину, но не обязательно случайные, вы можете использовать ZEROFILL Свойство MySQL вместе с индексом auto_increment.
Мне нравится использовать 16-символьный varchar base-60 для моих случайных первичных ключей. Вот крошечная таблица:
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, поэтому я могу добавить байты без обрезки всего, что уже есть в таблице.
Вместо того, чтобы генерировать число случайным образом и бороться с сохранением выбранных номеров треков, как насчет генерации числа в последовательности, но обновления записей в произвольном порядке?
Итак, вот полное решение 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
mysql сделает это за вас:
если вам действительно нужен начальный ноль, затем удалите auto_increment из столбца, измените его на varchar (10) и добавьте 0, используя UPDATE
Самый простой способ - сначала сгенерировать список чисел 16M чисел и случайный сортировать их, а затем сопоставить каждому с вашей записью, и это будет сделано в основном в PHP-функциях.
Я добавил цикл шага, чтобы он не генерировал слишком большой массив. Но это также означает, что идентификатор будет выглядеть как нарастающие, но все же случайные числа.
Может быть, кто-то может придумать лучшее решение, используя вращающуюся строку? Я сейчас не работаю.:)
Попробуйте это: GUID
<?
echo str_replace ("}","",str_replace("{","",com_create_guid()));
?>
Обычный способ создания уникального числа для каждой записи - это значение auto_incrementing - поэтому они будут уникальными, но не случайными.
.. и они будут генерироваться MySQL, а не PHP. Я думаю, что для создания 16 миллионов случайных, но отличных чисел в PHP было бы значительным накладные расходы.
Должны ли номера быть случайными? Возможно, уникальность является более важным требованием?