2012-04-17 3 views
0

Мне нужно создать абсолютно случайное число для каждого пользователя на моем сайте и вставить его в базу данных MySQL. Цифры никогда не могут повторяться, и я не хочу использовать MySQL AutoIncrement, потому что мне нужен определенный диапазон. Скажем от 111,111 до 999,999,999,999. На данный момент не выше или ниже. У меня есть определенная причина для этого диапазона, если вы хотите знать. Я знаю, что могу использовать функцию unique в MySQL, но это только мешает мне вставлять дубликаты. Я думал о наличии двух функций, один для генерации числа, а другой - для проверки того, используется ли это число. Они будут продолжать цикл, пока не найдут номер, который не использовался. Я знаю, насколько неэффективен и как долго это может произойти, когда большинство этих чисел было принято, поэтому я пришел сюда, чтобы получить лучший ответ. Что вы предлагаете мне делать, потому что я полностью из идей. Спасибо за любую помощь!PHP никогда не повторяющийся случайный номер

+0

Вы действительно будете использовать «большинство» чисел в диапазоне? – mellamokb

+0

Почему это должно быть случайным? Может ли он автоматически увеличиваться в этом диапазоне? –

+1

Полностью у стены и не знаю, будет ли это работать, но что-то вроде ...'Выберите случайный из myTable, где случайный не существует (выберите ID из myTable) limit 1' – xQbert

ответ

1

Предполагая, что позволит генерировать любое значение в отрезке [111111,999999999999], то мы просто должны найти целое число которое является относительно простым для

999999999999 - 111111 + 1 = 999999888889 

Это составное число, с довольно большими коэффициентами {18181, 55002469}.

Итак, теперь создайте простой, а не ужасно случайный (но верно соответствующий здесь) генератор чисел, который будет генерировать новое псевдослучайное целое из последнего выбранного. Сделайте это простым модульным вычислением. Выберите номер для начала и другое целое число, которое является относительно простым с перечисленными выше факторами.

N(1) = 111111111111 
N(i+1) = mod(N(i)*2803 + 4353454321 , 999999888889) 

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

Поскольку вы хотите, чтобы нижний предел был 111111, просто добавьте это значение к каждому числу, когда вы его используете. Эта процедура дает следующую последовательность:

{111111111111, 448832453975, 81861723884, 462790945592, 207518059664, 677539248004, 147076609322, 260135161619, 163292472297, 713204080539, 115613316027, 68514277966, ...} 

Вы добавите 111111 каждое значение, чтобы гарантировать, что нижний предел действительно 111111, так что последовательность, которая будет сообщаться только:

{111111222222, 448832565086, 81861834995, 462791056703, 207518170775, 677539359115, 147076720433, 260135272730, 163292583408, 713204191650, 115613427138, 68514389077, ...} 

Приятная все, что вам нужно, это сохранить последний элемент последовательности и выполнить модульные операции над числом, которое будет вписываться в 64-битное целое число.

6

Вы знаете, вы можете просто:

ALTER TABLE `mytable` AUTO_INCREMENT=111111 

Правильно?

Во всяком случае, если вы все еще согнуты на хаотичность, это, вероятно, наиболее эффективно SELECT все существующие значения, загружать их в массив PHP, то есть PHP вызов rand(111111,999999999999) пока вы не получите число, которое не in_array.

Замечание: PHP не может обрабатывать 999,999,999,999, если это не 64-разрядная версия, потому что это число слишком велико для 32-битных.

+0

Я уже рассмотрел его, это 64-разрядная версия. Я убедился в этом до того, как я разместил сообщение. –

+0

+1. Такое же базовое решение, как и я (на 24 секунды быстрее), и объяснение того, что выбор всего в массив и выбор случайного из этого массива - это * путь * более эффективный. Кроме того, хорошее упоминание о проблемах, если не на 64-битном PHP. – sberry

+0

Быстрый вопрос, есть ли способ сделать это, так что только 1 поле имеет значение auto_increment, начиная с 111111, остальные начинаются с 1? Извините, если это простой вопрос, я еще не лучший в MySQL-коде. Спасибо за это, хотя, отличный ответ! –

2

насчет установки количества автоматического приращения к 1111111.

ALTER TABLE YourTable AUTO_INCREMENT=1111111; 
Смежные вопросы