Небольшое введение: после размышлений о том, какие уникальные идентификаторы будут отображаться в URL-адресах и в других местах для использования, я выбрал линейные конгруэнтные генераторы (http://en.wikipedia.org/wiki/Linear_congruential_generator). Почему не UUID или автоинкремент?
- UUID слишком длинные и их сложнее хранить в db (рекомендуемый способ — преобразовать их в VARBINARY(16)).
- Auto_increment показывает последовательность регистраций и добавлений новых объектов и дает возможность прогнозировать следующие идентификаторы. Например, если сервис становится популярным, пользователи могут сделать несколько регистраций, чтобы заполучить красивый id, а затем попробовать продать такой аккаунт, id даст какой-то статус: чем раньше регистрация, тем круче. Я предпочитаю избегать таких вещей.
В LCG последовательность рандомизирована, и я могу выбирать параметры так, чтобы возможные значения хорошо вписывались в тип данных для конкретной цели. Например, используйте INT UNSIGNED для идентификаторов пользователей и выберите параметры, чтобы задать период 2^32.
Проблема в том, что для генерации следующего идентификатора мне нужно получить значение последнего идентификатора:
nextId = (a * lastId + c) % m
- Как я понимаю, я должен сам установить самый первый id? Важно, какой номер я выберу?
- Каков аккуратный способ создания новых идентификаторов? Возможно, создать таблицу со списком последних сгенерированных идентификаторов для каждой таблицы? Или добавить столбец auto_increment в каждую таблицу, чтобы отслеживать последний сгенерированный идентификатор? И как избежать проблем при большом количестве регистраций за короткое время?
Update1: я нашел один подход, который является безопасным для нескольких пользователей, используя информацию отсюда: http://dev.mysql.com/doc/refman/5.5/en/information-functions.html#function_last-insert-id
CREATE TABLE sequences (users INT UNSIGNED NOT NULL, posts BIGINT UNSIGNED NOT NULL);
INSERT INTO sequences VALUES(123456,123456789);
А затем, чтобы получить новый идентификатор:
UPDATE sequences SET users=LAST_INSERT_ID((a * users + c) % m);
SELECT LAST_INSERT_ID();