генерирование последовательного пятизначного буквенно-цифрового идентификатора - PullRequest
12 голосов
/ 14 июня 2011

Общий обзор:

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

Проблема:

Проверка на наличие дублирующих псевдонимов неэффективна и требует значительных ресурсов. Пять миллионов записей - это много для поиска. Особенно, когда этот поиск проводится одновременно разными пользователями.

Мой вопрос:

Есть ли способ «автоматического увеличения» комбинаций, разрешенных этой функцией? То есть мне нужно только найти псевдоним последней записи и перейти к следующей комбинации?

Признанные ограничения:

Я понимаю, что код будет сильно отличаться от функции ниже. Я также понимаю, что mysql имеет функцию автоматического увеличения числовых идентификаторов, но для проекта требуется пятизначный псевдоним с разрешенными символами «23456789ABCDEFGHJKLMNPQRSTUVWXYZ». Мои руки связаны в этом вопросе.

Моя текущая функция:

 public function random_id_gen($length)
 {
     $characters = '23456789ABCDEFGHJKLMNPQRSTUVWXYZ';
     $max = strlen($characters) - 1;
     $string = '';

     for ($i = 0; $i < $length; $i++) {
         $string .= $characters[mt_rand(0, $max)];
     }

     return $string;
 }

Ответы [ 3 ]

5 голосов
/ 14 июня 2011

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

CREATE UNIQUE INDEX uniq_alias ON MyTable(alias);

В этот момент вы можете попробовать вставить / обновить и, если он выдаст ошибку, сгенерировать новый псевдоним и повторить попытку.

1 голос
/ 14 июня 2011

Что вам действительно нужно сделать, так это конвертировать из базы 10 в базу strlen($characters).

PHP поставляется со встроенной функцией base_convert, но он не выполняет то, что вам нужно, поскольку он будет использовать числа ноль, единицу и букву 'o', которых нет в вашей версии. Поэтому вам понадобится функция для сопоставления значений от base_convert с / до ваших значений:

function map_basing($number, $from_characters, $to_characters) {
    if ( strlen($from_characters) != strlen($to_characters)) {
       // ERROR!
    }

    $mapped = '';
    foreach( $ch in $number ) {
       $pos = strpos($from_characters, $ch);
       if ( $pos !== false ) {
          $mapped .= $to_characters[$pos];
       } else {
          // ERROR!
       }
    }

    return $mapped;
}

Теперь, когда у вас есть это:

 public function next_id($last_id)
 {
    $my_characters = '23456789ABCDEFGHJKLMNPQRSTUVWXYZ';
    $std_characters ='0123456789abcdefghijklmnopqrstuv';

    // Map from your basing to the standard basing.
    $mapped = map_basing($last_id, $my_characters, $std_characters);

    // Convert to base 10 integer and increment.
    $intval = base_convert($mapped, strlen($my_characters), 10);
    $intval++;

    // Convert to standard basing, then to our custom basing.
    $newval_std = base_convert($intval, 10, strlen($my_characters));
    $newval = map_basing($newval_std, $std_characters, $my_characters);


    return $newval;
 }

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

0 голосов
/ 14 июня 2011

Вы можете бросить свой собственный автоинкремент. Вероятно, это было бы довольно неэффективно, поскольку вам нужно было бы выяснить, где в процессе находился ваш прирост. Например, если вы назначили позицию в вашей случайной строке как целое число и начали с (0) (0) (0) (0) (0), что равнялось бы 22222 в качестве идентификатора. Затем, чтобы получить следующее, просто увеличьте последнее значение до (0) (0) (0) (0) (1), что бы перевести на 22223. Если последнее доберется до длины вашей строки, то установите ее в 0 и увеличьте от второго до последнего и т. д. Это не совсем случайно, но оно будет увеличено и уникально.

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