Лучше ли структурировать таблицу SQL так, чтобы было совпадение, или не возвращать результата

StackOverflow https://stackoverflow.com/questions/23399

  •  09-06-2019
  •  | 
  •  

Вопрос

У меня есть интересный дизайнерский вопрос.Я разрабатываю сторону безопасности нашего проекта, чтобы позволить нам иметь разные версии программы по разным ценам, а также разрешить пользователям типа Manager предоставлять или запрещать доступ к частям программы другим пользователям.Он будет размещен в Интернете на наших серверах.

Я использую простую опцию Разрешить или Запретить для каждого "Ресурса" или экрана.

У нас будет большое количество ресурсов, и пользователь сможет создать множество различных групп, в которые будут входить пользователи для контроля доступа.Каждый пользователь может принадлежать только к одной группе.

У меня есть два подхода к этому, и мне было любопытно, какой из них был бы лучше для SQL server с точки зрения производительности.

Вариант А Наличие записи в таблице доступа означает, что доступ разрешен.Для этого не потребуется столбец в базе данных для хранения информации.Если результаты не возвращаются, то доступ запрещен.

Я думаю, это будет означать таблицу меньшего размера, но будут ли запросы выполнять поиск по всей таблице, чтобы определить, что совпадения нет?

Вариант В В базу данных включен столбец bit, который управляет Разрешением / Запретом.Это будет означать, что всегда можно найти результат, и приведет к увеличению таблицы.

Мысли?

Это было полезно?

Решение

Если это будет только Разрешение / Запрет, то простая таблица связей между пользователями и Ресурсами будет работать нормально.Если в таблице привязки есть запись с ключом к Пользовательскому ресурсу, разрешите доступ.

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) запрос был бы ошеломляюще быстрым даже при наличии миллионов записей.

Другие советы

Я бы проголосовал за вариант Б.Если вы выберете вариант A и предположите, что если пользователь существует, он может войти, то в конечном итоге вы столкнетесь с проблемой, заключающейся в том, что вы захотите запретить доступ пользователю, не удаляя запись пользователя.

Будет много случаев, когда вы захотите заблокировать пользователя, но не захотите полностью уничтожать его учетную запись.Один из таких случаев (не обязательно связанный с вашим вариантом использования) - это когда вы не платите, и они отключают ваш аккаунт до тех пор, пока вы не начнете платить снова.Они не хотят удалять запись, потому что они все равно хотят включить ее при повторной оплате, вместо того чтобы воссоздавать учетную запись с нуля и терять всю историю пользователей.

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 был бы разрешен.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top