@starkzz

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

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

Вопрос: как организовать корректную генерацию номеров тикетов?
  • Вопрос задан
  • 287 просмотров
Пригласить эксперта
Ответы на вопрос 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.
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Похожие вопросы