В нашем веб-приложении мы хотим рандомизировать идентификаторы записей. Причина в том, что мы хотим скрыть, сколько записей уже есть в БД, и у нас есть вещи, не включенные в список. Если бы идентификаторы были простыми инкрементными числами, было бы легко угадать идентификаторы вещей, не включенных в список.
На мой взгляд, есть три способа сделать это:
Простые случайные числа
Алгоритм:
- Создать случайное число при вставке.
- Проверьте, не используется ли уже этот идентификатор. Если да, перейдите к 1.
- Используйте этот идентификатор.
Pro
- easy
- работает с любым размером и типом идентификатора (32 бит, 64 бит, вар.длина, строки)
Contra
- нужна транзакция для возможных условий гонки (алгоритм не является атомарным)
UUID
Pro
- вероятность коллизий настолько мала, что ее можно игнорировать
В отличие от
- мы хотим иметь красивые короткие URL-адреса с заголовком страницы в качестве комментария URL-адреса (
"#{id}--#{page_title}
), UUID переместит этот комментарий полностью к правильно
- Я полагаю, что UUID в качестве первичных ключей будут иметь более низкую производительность при соединениях?
Зашифрованные идентификаторы
Алгоритм:
- Чтение числа из последовательности с использованием
nextval
(атомарно!)
- Зашифруйте идентификатор с помощью секретного ключа и алгоритма шифрования, который работает с размером, используемым для идентификатора
Pro
- без условий гонки (нет необходимости в транзакциях)
Contra
- размер столбца идентификатора никогда не может изменить
- если кто-то может взломать/угадать ключ все было напрасно
Временные метки
Предложено @emboss
Pro
- легко
- не закончатся идентификаторы
продолжение ra
- может приводить к коллизиям (хотя нужно проверить, действительно ли это происходит)
- возможно, в некоторой степени можно предположить
Случайный общедоступный идентификатор/общедоступный идентификатор на основе имени
Предложено @viktor tron
Второй идентификатор для все, что происходит в URL-адресе, используется только для поиска записи. Используются внутренние обычные идентификаторы (для объединений и т. д.).
Pro
- внутренне все остается нормальным
- хороший случайный алгоритм/схема именования должна сделать невозможным угадывание URL (достаточно)
Contra
- изменить много вещей, которые используют идентификаторы в общедоступных интерфейсах
- пользователь может ожидать, что он может сократить URL-адреса с такими заголовками в них, но в этом случае URL-адреса больше не будут работать
Думаю, я воспользуюсь третьим вариантом. Или есть еще аргументы против? Есть ли еще лучшее решение? Мы используем Ruby on Rails 3.x и PostgreSQL 9.x.
Редактировать:Закрытое не значит закрытое! Это означает, как незарегистрированные видео на YouTube. Это обычные видео, которые просто не отображаются в результатах поиска или в профиле пользователя. Таким образом, вы не можете найти их (не перебирая все возможные идентификаторы), но любой, кто знает URL-адрес, может получить к ним доступ. Конечно, пользователь, который делает что-то незарегистрированным и отправляет ссылку кому-то еще, должен знать, что это может не остаться неизвестным (URL-адрес может быть передан и через ссылку может оказаться в поисковой системе).
У нас также есть еще один способ сделать вещи приватными. Это две разные вещи. (Я вижу, что предположение о том, что все знают, что означает «не включенный в список», было ошибкой.)
задан panzi 28 May 2012 в 20:06
поделиться