Рандомизация идентификаторов записей БД

В нашем веб-приложении мы хотим рандомизировать идентификаторы записей. Причина в том, что мы хотим скрыть, сколько записей уже есть в БД, и у нас есть вещи, не включенные в список. Если бы идентификаторы были простыми инкрементными числами, было бы легко угадать идентификаторы вещей, не включенных в список.

На мой взгляд, есть три способа сделать это:

Простые случайные числа

Алгоритм:

  1. Создать случайное число при вставке.
  2. Проверьте, не используется ли уже этот идентификатор. Если да, перейдите к 1.
  3. Используйте этот идентификатор.

Pro

  • easy
  • работает с любым размером и типом идентификатора (32 бит, 64 бит, вар.длина, строки)

Contra

  • нужна транзакция для возможных условий гонки (алгоритм не является атомарным)

UUID

Pro

  • вероятность коллизий настолько мала, что ее можно игнорировать

В отличие от

  • мы хотим иметь красивые короткие URL-адреса с заголовком страницы в качестве комментария URL-адреса ( "#{id}--#{page_title}), UUID переместит этот комментарий полностью к правильно
  • Я полагаю, что UUID в качестве первичных ключей будут иметь более низкую производительность при соединениях?

Зашифрованные идентификаторы

Алгоритм:

  1. Чтение числа из последовательности с использованием nextval(атомарно!)
  2. Зашифруйте идентификатор с помощью секретного ключа и алгоритма шифрования, который работает с размером, используемым для идентификатора

Pro

  • без условий гонки (нет необходимости в транзакциях)

Contra

  • размер столбца идентификатора никогда не может изменить
  • если кто-то может взломать/угадать ключ все было напрасно

Временные метки

Предложено @emboss

Pro

  • легко
  • не закончатся идентификаторы

продолжение ra

  • может приводить к коллизиям (хотя нужно проверить, действительно ли это происходит)
  • возможно, в некоторой степени можно предположить

Случайный общедоступный идентификатор/общедоступный идентификатор на основе имени

Предложено @viktor tron ​​

Второй идентификатор для все, что происходит в URL-адресе, используется только для поиска записи. Используются внутренние обычные идентификаторы (для объединений и т. д.).

Pro

  • внутренне все остается нормальным
  • хороший случайный алгоритм/схема именования должна сделать невозможным угадывание URL (достаточно)

Contra

  • изменить много вещей, которые используют идентификаторы в общедоступных интерфейсах
  • пользователь может ожидать, что он может сократить URL-адреса с такими заголовками в них, но в этом случае URL-адреса больше не будут работать

Думаю, я воспользуюсь третьим вариантом. Или есть еще аргументы против? Есть ли еще лучшее решение? Мы используем Ruby on Rails 3.x и PostgreSQL 9.x.

Редактировать:Закрытое не значит закрытое! Это означает, как незарегистрированные видео на YouTube. Это обычные видео, которые просто не отображаются в результатах поиска или в профиле пользователя. Таким образом, вы не можете найти их (не перебирая все возможные идентификаторы), но любой, кто знает URL-адрес, может получить к ним доступ. Конечно, пользователь, который делает что-то незарегистрированным и отправляет ссылку кому-то еще, должен знать, что это может не остаться неизвестным (URL-адрес может быть передан и через ссылку может оказаться в поисковой системе).

У нас также есть еще один способ сделать вещи приватными. Это две разные вещи. (Я вижу, что предположение о том, что все знают, что означает «не включенный в список», было ошибкой.)

5
задан panzi 28 May 2012 в 20:06
поделиться