В настоящее время я работаю над новым веб-проектом с различными типами организаций. Этот сервис будет доступен через REST API, и я думаю о таких конечных точках, как:
api.example.com/users/{user_id}
Для этого я думаю, что автоинкрементный идентификатор для пользователей будет плохим подходом, так как любой может нажать:
api.example.com/users/1
, а потом api.example.com/users/2
, api.example.com/users/3
, и так далее.
Теперь я думаю использовать UUID, но я не знаю, хорошая ли это идея, потому что это VARCHAR(36)
, По этой причине я делаю что-то подобное, когда генерирую идентификатор пользователя на ВСТАВИТЬ запрос (я использую MySQL):
unhex(replace(uuid(),'-',''))
С этим я приведу UUID к двоичному. И я храню BINARY(16)
вместо базы данных.
И когда я хочу получить информацию из базы данных, я могу использовать что-то вроде этого:
SELECT hex(id), name FROM user;
а также
SELECT hex(id), name FROM user WHERE hex(id) = '36c5f55620ef11e7b94d6c626d968e15';
Итак, я работаю с шестнадцатеричной формой, но храню ее в двоичной форме.
Это хороший подход?
Почти там…
Индексы — ваш друг по производительности. предположительно id
индексируется, то
WHERE id = function('...')
использует индекс и идет прямо к строке, но
WHERE function(id) = '...'
не может использовать индекс; вместо этого он сканирует все строки, проверяя каждую. Для большого стола это sloooow.
Так…
Используйте это, чтобы сохранить это:
INSERT INTO tbl (uuid, ...)
VALUES
(UNHEX(REPLACE(UUID(), '-', '')), ...);
И это проверить это:
SELECT ... WHERE
uuid = UNHEX(REPLACE('786f3c2a-21f6-11e7-9392-80fa5b3669ce', '-', ''));
Если вы решите отправить (через REST) 32 символа без тире, вы можете рассчитать это незначительное изменение.
Поскольку это утомительно, создайте пару сохраненных функций. О, у меня есть один для вас; увидеть http://mysql.rjweb.org/doc.php/uuid .
Здесь также обсуждается, почему UUID неэффективны для огромных таблиц, и возможный способ обойти это.
Других решений пока нет …