@starkzz

Как организовать генерацию номеров тикетов?

Доброго времени суток.
Ситуация есть 2 сайта с на которых подключен сервис для создания тиекта(задание вопроса, описание какой-то проблемы у пользователя).
Есть сайт агрегатор тикетов на котором сидят операторы и помогают пользователям 2 сайтов.
Как работает сейчас - на сайте №1 пользователь жмет кнопочку "создать тикет", заполняет поля и жмет "отправить".
Запрос летит на агрегатор, там выдается уникальный цифровой код - номер тикета и возращается пользователю (бла-бла-бла, ваш тикет зарегистрирован под номером 1234567890).
Операторы на агрегаторе не в курсе для клиента какого сайта они отвечают, так и должно быть.
Суть кода генерации тикета явно не корректная - генерируется случайное n-значное число, делается селект из базы, ничего не селектнулось - отлично, у тикета будет такой номер, селектнулось - генерируется номер и селектается опять.
Сейчас сайта 2, но в будущем может быть и 100.
Выдать каждому сайту какой-то диапазон номеров - так себе идея, с 1 может за год прийти 2 тикета, а с другого 100 за 1 день.
Была мысль генерить номер на сайте-клиенте, а на сайте агрегаторе хранить номер в куче с ИД сайта-клиента, но тогда возможна ситуация, что у оператора могут оказаться перед глазами 2 тикета - 3334445, один с сайта №1, а другой с сайта №2 (напоминаю, что оператор не должен знать с какого сайта клиента пришел тикет)
Была мысль организовать сторонний сервис на каком-то node.js который будет держать пул всех номеров с отмеченными занятыми и на запрос просто будет выдавать номер и сразу же его блокировать(немного сомнительной кажется идея)

Вопрос: как организовать корректную генерацию номеров тикетов?
  • Вопрос задан
  • 283 просмотра
Пригласить эксперта
Ответы на вопрос 4
@Kostik_1993
Web Developer
Чем вам плох autoincrement и last insert id? Это самое удобное что было придумано. зачем городить городки?
Ответ написан
Sanes
@Sanes
Префикс сервера+id
Ответ написан
kawabanga
@kawabanga
А я подумал о том, чтобы создать дополнительный сервер, выдающий ИД.

СайтСервер запрашивает ИД у ИдСервер, ИдСервер создает у себя в таблице строку, с краткой информацией, с какого сайта пришел запрос.
Ответ написан
sergiks
@sergiks Куратор тега PHP
♬♬
Как это сделано у Redis, алгоритм Redlock:
  1. понадобится доп. поле для случайной строки;
  2. генерите случайный ID и случайное значение;
  3. вставляете в таблицу запись с этим ID и значением. БД не позволит вставить, если уже есть такой ID.
  4. Читаете эту запись и её доп.поле. Если считанное доп.значение совпало с вашим сгенеренным случайным значением – всё круто, этот ID ваш, можно его использовать;
  5. Если считалось, но там другое значение доп. поля – придётся снова генерить новый случайный ID и сл. значение ему в пару – до тех пор, пока не попадёте пальцем в небо. Чем больше тикетов в системе, тем дольше может понадобиться погадать. И скорее переписать всю ущербную систему на последовательную нумерацию записей и генерацию не выглядящих последовательными биьективных трансформаций из них (самое простое – инверсия порядка битов).


Upd. подробнее об идее с перемешиванием битов последовательных ID, чтобы они выглядели непоследовательно. Самый простой вариант однозначного соответствия между двумя множествами это инверсия порядка битов. В БД храните последовательные возрастающие ID. Тип INT в MySQL занимает 4 байта, это 32 бита. Для отображения их клиенту вы в PHP или NodeJS (они все 64-битные) инвертируете порядок бит в младших 4 байтах. Например:
было 199
00000000 00000000 00000000 11000111
стало (зеркально)
11100011 00000000 00000000 00000000
это 64-битное число 3808428032

было 200
00000000 00000000 00000000 11001000
стало
00010011 00000000 00000000 00000000 (318767104)


Такое зеркалирование порядка – операция обратимая. Дважды отзеркалить – будет исходное. Поэтому клиентам показываете эти сложные номера, у себя ведёте последовательные упорядоченные ID.

Код для реверса порядка бит на JS и PHP я уверен, вы напишете самостоятельно. Подскажу, что для увеличения скорости операции удобно использовать небольшую таблицу байтов 16x16.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы