Нужны доводы против последовательных целочисленных индексов
Я стою на пороге нового проекта для своей организации и разрабатываю архитектуру этого веб-приложения. При этом у меня возник, вернее опять обострился, давний конфликт с не-IT архитекторами и будущими пользователями: я хочу скрывать ID записей (объектов) в пользовательском интерфейсе и использовать GUID на стороне сервера (в базе данных), потому что везде скрыть не получится, а я не хочу давать пользователям шанс знать структуру и играться угадывая номера (например, если у записи ID 123 то есть наверняка 122 и 124). В случае GUID еще облегчается много других вещей, таких как кластеризация БД в будущем и т.п. (давайте не будем пока спорить о производительности INT vs GUID, что лучше дебажить и.т.п. )
Проблема в том, что все остальные не просто хотят целочисленные последовательные индексы, они хотят их видеть везде, чтобы потом можно было легко ссылаться на них в разговорах и корреспонденции, например, «Эй! Кто отвечает за проект 4096?», при том, что этот же проект всегда имеет собственное имя и можно ведь ссылаться на него.
Как вариант, я предложил им целочисленные индексы выглядящие случайным образом и имеющие одинаковую длину (на сервере я бы перекодировал их на лету в нормальные целочисленные ID), но они не хотят слушать, так как это тяжело запомнить.
В общем, какие есть еще доводы чтобы переубедить? Как такую проблему решаете вы?
Ну, допустим, кто-то захочет перебрать все паблик-записи, например. Непосредственной угрозы как-бы нет, но и пользы тоже, особенно если это будет делать скрипт во время наибольшей активности пользователей. Плюс такая проблема как предоставление статистики конкурентам, например количество пользователей и т.п.
Вообще говоря использовать uniqueidentifier'а в качестве Primary Key плохая затея. Говорю это из своего опыта. Когда проект только начинался мы бездумно сделали все PK c типом uniqueidentifier, и через год, когда количество записей стало исчисляться миллионами, база данных начал непонятно тупить. Тогда мы узнали что такое фрагментация индексов. Фрагментация кластерного индекса очень сильно замедляет вставку. Говоря о выборке, банальные join'ы 100 на 100 записей стали медленными, потому что серверу надо делать множество сиков на диске для перехода к нужной записи. И не говорите о плохих индексах, в данном случае мы выжали всё что могли, и именно сики стали головной болью. Перенос огромной базы на SSD тоже на самая безопасная операция. Так уже больше года мы потихоньку меняем старые Guid'ы на int/bigint и с болью вспоминаем то неосмотрительное решение.
Я бы рекомендовал вам разработать архитектуру с хорошим слоем проверки безопасности. И тогда перебор id ничего не даст злоумышленнику. Также никто не мешает добавить ещё одну колонку SecureId и использовать её в местах, которые совсем-совсем не хочется показывать наружу.
Хотел писать свой ответ, но потом увидел последний абзац и решил просто плюсануть. Не вижу никаких реальных проблем с «играми». Если доступ к записи открыт, то какая разница, как на нее зашёл пользователь — по прямой ссылке или перебором? Если закрыт, то обеспечивать эту закрытость надо чем угодно, но только не «случайными числовыми индексами».
Проверка на стороне сервера это само-собой, просто как-то не хочется светить айди, сам не знаю почему — мне просто кажется это неправильным, т.е. чем меньше юзер знает о системе, тем лучше. Ваш довод о фрагментации принят, спасибо.
Вы ошибаетесь. Мне лень искать 100500 подтверждений, но первое же мое предположение подтвердилось:
otvet.mail.ru/question/78920084/ использует прямые числовые индексы, и вполне себе работает.
Не хотите светить id — придумайте обратимую функцию(id,field_name) и пользуйтесь ей при отправке/получении данных. Но это спасет вас от хакеров бухгалтерского уровня, не выше.
В случае с интернет магазином (не знаю, что у Вас) очевидно, что ID пользователя и ID заказа должны быть не последовательными. Иначе зарегистрировавшись я получу ID и узнаю количество юзеров, а создав пару заказов и увидев, что ID последовательные, я увижу количество заказов в магазине и смогу сделать предположение о его обороте. И даже никакой перебор мне не понадобится.
Для справки: CHAR(7) — набор из a-z0-9 даёт 78364164096 вариаций.
Начните говорить с ними с другого конца: Скажите, что нужно определиться с уровнем защиты и безопасности в проекте. Дайте им какую-то градацию, и пусть они сами выберут, что они считают в проекте секретным, а что нет. А когда вы с ними определитесь с секьюрностью отдельных частей проекта, вы и сможете им сказать «Для такой степени безопасности нужно принять таки и такие меры в таких и таких местах.»