У меня есть интересный вопрос дизайна. Я разрабатываю сторону безопасности нашего проекта, чтобы позволить нам иметь разные версии программы для разных затрат, а также чтобы пользователи типа «Менеджер» могли предоставлять или запрещать доступ к частям программы другим пользователям. Он собирается на веб-основе и размещается на наших серверах.
Я использую простой параметр «Разрешить» или «Запретить» для каждого «ресурса» или экрана.
У нас будет большое количество ресурсов, и пользователь сможет создать много разных групп, чтобы пользователи могли контролировать доступ. Каждый пользователь может принадлежать только к одной группе.
У меня есть два подхода к этому, и мне было любопытно, что будет лучше для SQL-сервера с точки зрения производительности.
Вариант A Наличие записи в таблице доступа означает, что доступ разрешен. Это не будет нуждаться в столбце в базе данных для хранения информации. Если результаты не возвращаются, доступ запрещен.
Я думаю, что это будет означать меньшую таблицу, но будут ли запросы выполнять поиск по всей таблице, чтобы определить, что совпадений нет?
Вариант B Битовый столбец включен в базу данных, которая управляет разрешить / запретить. Это будет означать, что всегда найдется результат, и это приведет к увеличению таблицы.
Мысли?
Если это будет только Разрешить / Запретить, то простая таблица связывания между пользователями и ресурсами будет работать нормально. Если в таблице ссылок есть запись, связанная с User-Resource, разрешите доступ.
UserResources
-------------
UserId FK->Users
ResourceId FK->Resources
и sql будет что-то вроде
if exists (select 1 from UserResources
where UserId = @uid and ResourceId=@rid)
set @allow=1;
При включенном кластерном индексе (UserId и ResourceId) запрос будет ослепительно быстрым даже с миллионами записей.
Я бы проголосовал за вариант Б. Если вы выберете вариант А и исходите из предположения, что если пользователь существует, он может войти, то в конечном итоге вы столкнетесь с проблемой, по которой вы захотите запретить доступ пользователю, не удаляя его. запись пользователя.
Будет много случаев, когда вы захотите заблокировать пользователя, но не захотите полностью уничтожить его учетную запись. Один из таких случаев (не обязательно связанный с вашим вариантом использования) - это когда вы не платите, и они отключают вашу учетную запись, пока вы не начнете платить снова. Они не хотят удалять запись, потому что они все еще хотят включить ее при повторной оплате, вместо того, чтобы заново создать учетную запись и потерять всю историю пользователей.
B. Это позволяет намного лучше проверять, являются ли данные полными (например, когда вы добавляете допустимую / запрещаемую функцию).
Кроме того, размер таблицы должен учитываться только для таблиц, которые, как вы знаете, будут содержать много записей (например, 100 000+). Вы даже потратили время на то, чтобы указать размер таблицы в этом вопросе, и так уже стоили больше, чем дополнительное место на жестком диске.
Подход А, но я бы также включил явное отрицание в дополнение к неявному отказу от вас. Я хотел бы использовать некоторые варианты, чтобы убедиться, что ваша конечная логика работает, но вот несколько примеров.
User1 is in group1 and group2.
User2 is in group1
User3 is in group2
Folder1 allows group1 and deny group2.
User1 is denied.
User2 is allowed.
User3 is denied.
Я верю, что ваш подход users1 будет разрешен.