Уникальное значение в неосновном поле - PullRequest
0 голосов
/ 14 декабря 2011

Я генерирую случайную 10-символьную строку с помощью php и вставляю ее в столбец в моей БД.Моя проблема в том, что я хочу, чтобы эта строка была уникальной (в базе данных).Я думал о многих способах сделать это, но задавался вопросом, какой способ является наиболее эффективным.

Мой PHP выглядит следующим образом (длина произвольной строки может составлять всего 10 символов):

 //generates an almost unique(not quite) ticket number
 $pretrimmedtask = md5(uniqid(mt_rand(),true));
 $tasknum =  substr($pretrimmedtask ,0,10);

Затем я беру это «уникальное» значение и вставляю его.Но из-за обрезки строки это значение ни в коем случае не уникально.Мне интересно, каков наилучший способ убедиться, что это значение никогда не будет дублироваться, но при этом остается эффективным.

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

Ответы [ 4 ]

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

Вам следует обновить таблицу и сделать соответствующий столбец UNIQUE KEY, затем попытаться вставить сгенерированную строку, если строки не вставлены, сгенерировать другой ключ и повторить попытку.

ALTER TABLE table_name ADD UNIQUE KEY (column_name);

Приведенный ниже код попытается INSERT ввести новую строку в table1, если не удастся, он попытается снова с другим случайно сгенерированным $key.

IE.запрос не будет выполнен успешно, если col2 имеет ограничение уникального ключа и значение $key уже существует в столбце.

function generate_random_string () {
  $charset = array_merge (
    range ('a', 'z'), range ('A','Z'), range ('0','0')
  );

  shuffle ($charset);

  return join ('', array_slice ($charset, 0, 9));
}

/* ....................................................... */

do {
  $key = generate_random_string ();
} while (
  !mysql_query ("INSERT INTO table1 (col1,col2) VALUES (123, '$key')")
);

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

ПРИМЕЧАНИЕ: Убедитесь, что запрос потенциально может быть успешным, чтобы вы не попали в бесконечный цикл.

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

Создайте уникальный индекс mysql, который охватывает только это поле, и вставьте значение в цикл до успеха.

Как:

while (true) {
    $random = generate it;
    try to insert;
    if (inserted without errors) break;
}
0 голосов
/ 15 декабря 2011

У меня была эта проблема.

Я использую (insert) time () и insert / row id (+ массив специальных букв) md5-ed все вместе как одну строку и хэшируем - для некоторых целей cookie допустим. Итак, этот ключ открыт.

Идентификатор вставки (или строки) не может быть продублирован и объединен с меткой времени Unix (10 цифр) + случайными буквами и md5-ed вместе, несомненно, создает уникальный «второй ключ», который несколько сложнее сломать, что доступно через куки. В этом случае невозможно его сломать.

Но это хеш.

Если необходимо 10 символов - как я не могу найти причину - вы можете создать функцию для создания ключей, таких как (99999999999999999999-первичный ключ) + substr 10 с включенными буквами, но это зависит от уровня подверженности этот ключ.

Однако substr не является опцией, а роль первичного ключа просто - существенна.

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

Должно ли это быть 10 символов.С помощью crypt () вы можете генерировать хэши длиной 13 символов.

Здесь http://www.php.net/manual/en/function.hash.php вы можете проверить длину различных методов хеширования.К сожалению, ни один из них не создает ровно 10 символов строки.Но вы можете сгенерировать длинную строку из 8 символов и добавить два символа.

Другое возможное решение, которое я придумал, - использовать текущую дату создания строки.Unixtimestamp - это только числа и длинные, но мы можем преобразовать дату в строку из 10 символов следующим образом

Создать два массива, сначала с ключами от 1 до 31, и назначить один символ для каждой клавиши (26 букв плюс 10 цифрдобьемся цели), второй массив должен иметь ключи от 0 до 99 и иметь значения длинной строки в два символа.

Теперь возьмите день, месяц, год (2 цифры), часы, минуты и секунды текущего времени и замените значение значением из массива, где день и месяц берутся из первого массива иотдых от второго.Добавьте к этому уникальную строку длиной 10 символов.

...