Сгенерируйте уникальный трехбуквенный код и сравните с существующими в PHP / MySQL - PullRequest
0 голосов
/ 20 сентября 2009

Я делаю сценарий генерации кода для системы ЛОКОД ООН, и в базе данных есть уникальные трехбуквенные коды в каждой стране. Так, например, база данных содержит «EE TLL», EE - страна (Эстония) и TLL - уникальный код внутри Эстонии, также может существовать «AR TLL» (код страны и трехбуквенный / цифровой код хранятся отдельно). Коды заглавными буквами.

База данных довольно большая и уже содержит огромное количество местоположений, пользователь также имеет возможность ввести 3 буквы / цифры сам (которые будут проверены по базе данных перед отправкой автоматически).

Наконец, ни 0, ни 1 не могут использоваться (возможная путаница с O и I).

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

Что я придумал:

  1. Я бы проверял с AAA до 999, но тогда для каждого кода требовался бы новый запрос (медленно?).

  2. Я мог бы сохранить все 40000 возможностей в массиве и вычесть все использованные коды, которые уже есть в базе данных ... но которые используют слишком много памяти IMO (не уверен, о чем я здесь говорю, на самом деле, может быть, 40000 не такое большое число).

  3. Создайте случайный код и надейтесь, что он еще не существует, и посмотрите, будет ли он, если он начнется снова. Это просто риск.

Есть ли какой-нибудь волшебный MySQL-запрос / PHP-скрипт, который может дать мне следующий доступный код?

Ответы [ 3 ]

0 голосов
/ 20 сентября 2009

Я хотел бы для варианта 1 (т.е. выполнить последовательный поиск), добавив таблицу, которая дает последний назначенный код для каждой страны (то есть такой, что AAA..code все уже назначены). При назначении нового кода посредством последовательного сканирования эта таблица обновляется; для назначенных пользователем кодов он остается неизменным.

Если вы не хотите выдавать повторные запросы, вы также можете записать это сканирование как хранимую подпрограмму .

Чтобы упростить итерацию, лучше было бы рассматривать трехбуквенные коды как числа (как предлагает Шон Сяо), то есть придавать значение A-Z = 0..25 и 2..9 = 26..33. Тогда XYZ - это число X*34^2+Y*34+Z == 23*1156+24*34+25 == 27429. Это должно быть выполнено с использованием стандартных функций MySQL, в частности с помощью CONV.

0 голосов
/ 21 сентября 2009

Я пошел со вторым вариантом. Я также смог сделать скрипт, который будет пытаться сопоставить как можно ближе название страны, например, для Тарту он будет пытаться сопоставить T **, затем TA * и, если возможно, TAR, если нет, он попробует TAT как T следующая буква после R в Тарту.

Код довольно обширный, я просто опубликую часть, которая использует первый возможный код:

$allowed = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ23456789';
$length = strlen($allowed);
$codes = array();
// store all possibilities in a huge array
for($i=0;$i<$length;$i++)
    for($j=0;$j<$length;$j++)
        for($k=0;$k<$length;$k++)
            $codes[] = substr($allowed, $i, 1).substr($allowed, $j, 1).substr($allowed, $k, 1);

$used = array();
$query = mysql_query("SELECT code FROM location WHERE country = '$country'");
while ($result = mysql_fetch_array($query))
    $used[] = $result['code'];

$remaining = array_diff($codes, $used);

$code = $remaining[0];

Спасибо за ваше мнение, это будет ключ к транспортным кодам по всему миру:)

0 голосов
/ 20 сентября 2009

Я пойду с номером 2, это просто, а 40000 - не большое число.

Чтобы сделать его более эффективным, вы можете сохранить число, представляющее каждый трехбуквенный код. Преобразование должно быть тривиальным, потому что у вас есть всего 34 (A-Z, 2-9) буквы.

...