Убеди скептика!Зачем мне нужна таблица «Роли» в моей базе данных? - PullRequest
2 голосов
/ 06 июня 2011

При проектировании таблиц базы данных для хранения простой информации о пользователе / ​​роли любой может сказать мне, почему было бы плохой идеей хранить информацию о роли непосредственно в таблице пользователя (например, разделенных запятыми в столбце ролей).

Мысли:

  1. База данных не должна знать о ролях, это домен пользовательского интерфейса
  2. Чем быстрее доступ к ролям конкретного пользователя, тем лучше
  3. Конечно, если когда-нибудь в будущем я хочу получить доступ ко всем пользователям для определенной роли, запрос может

быть немного медленным, но кого это волнует?

Имеет ли это какой-то смысл?Я сошел с рокера?Разве создание таблиц Roles и UserRole не будет лишним и добавит ненужные sql и накладные расходы кода?

ОБНОВЛЕНИЕ:

Чтобы проиллюстрировать мою точку зрения ... в коде, я хочу знать, если пользователь "Стив »играет роль« Администратор ».

Вариант 1: запросить в таблице UserRole список ролей для пользователя« Стив ».Прокрутите этот список и посмотрите, соответствует ли RoleName «Администратору».

Вариант 2: разделите CSV в свойстве роли пользователя и посмотрите, содержит ли результирующий список «Администратор»

ОБНОВЛЕНИЕ II:

Я согласен, что мое предложение нарушает все виды мышления типа "наилучшей практики", особенно в отношении дизайна БД.Однако я не вижу, как «лучшие практики» имеют какой-либо смысл в такого рода сценариях.Мне нравится время от времени раскачивать лодку с лучшими практиками ... Мне нравится кодировать так, чтобы это казалось умным, а это значит, что иногда мне нужно больше понимать, чтобы знать, когда я не умный:)

Ответы [ 5 ]

2 голосов
/ 06 июня 2011

Потому что это нарушает третью нормальную форму.Вы хотите разделить все свои сущности как разные объекты, что означает, что вам нужна отдельная таблица, а также таблица отношений.

Нарушение данных

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

В результате вы начинаете добавлять поля, не относящиеся к пользователю, и в итоге получаететонна несвязанной информации.Решением этой проблемы является использование таблицы пользователей следующим образом:

User table
UserID
User
...

Role table
RoleID
Role
....

User Role Table (the relationship)
UserRoles
UserID
RoleID
...

Обновление / вставка данных

Следующая проблема, с которой вам придется столкнуться, если вы храните информацию о ролях внутри таблицы пользователякак выполнять корректные обновления, вставки.Это делает все более сложным.Когда вы редактируете запись, вы должны убедиться, что вы редактируете правильное значение из CSV.

Поиск правильной роли

Здесь находится самая трудная проблема, как найти роль, данную пользователю.Вы можете придумать эту замечательную технику синтаксического анализа в C # или SQL Server, она прекрасно работает ... но она становится ужасно медленной и трудной для чтения.Вы начинаете иметь дело с SubString(), Left(), Right(), Len() и целым рядом других функций, просто чтобы разобраться в роли пользователя.

Решение

Вы можете подумать, что сложить все в один стол сейчас проще.Это, вероятно, займет намного меньше времени.Но вы должны разрабатывать приложения с учетом будущего.Пользовательский интерфейс будет намного проще, если вы будете следовать правилам 3nf и создадите хорошую реляционную структуру.Мало того, что экраны администрирования пользовательского интерфейса будут выглядеть красиво, но получить роль для определенного идентификатора пользователя будет тривиально, в отличие от анализа или поиска ...

1 голос
/ 06 июня 2011

Не думаю, что это отличный план. Предположим, вы вручную обновляете чьи-то роли и вводите название роли немного неправильно? Если у вас есть отдельная таблица, ограничение базы данных предупредит вас. Предположим, вы решили изменить название роли? Если бы у вас была отдельная таблица, вам нужно было бы изменить ее только в одном месте.

Нормализация базы данных выполнена по уважительным причинам; это не просто придирчиво. Вы не будете повторять код ключа в своей кодовой базе более чем в одном месте; денормализация базы данных эквивалентна.

ИЗМЕНЕНО ДЛЯ ДОБАВЛЕНИЯ: Вы подчеркиваете, что приложение в конечном итоге будет принимать решения на основе значений, возвращаемых базой данных; например предоставление определенных опций, если у пользователя есть роль «Администратор». Это верно, и это другое, отдельное место, где последовательность, например, имен ролей может нарушаться. Я не думаю, что денормализация базы данных делает это менее вероятным.

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

То есть, в представлении, если вы решаете, показывать ли кнопку «изменить» в описании элемента, вы не проверяете, делая if role=='ADMIN' or role=='EDITOR', вы проверяете, делая if user.can_edit(item) , В другом месте вы установили, что администраторы и редакторы получают возможность редактировать элементы. См., Например, подход, который использует система авторизации Rails CanCan .

При использовании этого подхода есть только одно место, где вы ссылаетесь на названия ролей (например, в CanCan у вас есть класс, называемый «способностями», который определяет все правила для того, кто что может делать, исходя из их ролей. Везде иначе вы указываете, какие способности пользователь должен определить, что он может делать или видеть.

0 голосов
/ 07 июня 2011

Вы сказали

Так почему бы просто не определить роли в приложении и только в приложение?

Вы можете сделать это надежно, только если вы можете честно сказать: «Я на 100% уверен, что каждый программист и каждый администратор базы данных будут сохранять целостность данных вручную совершенно независимо от того, какое приложение касается этой базы данных, независимо от того, на каком языке она запрограммирована. независимо от того, насколько опытным или неопытным является программист, и независимо от того, насколько сложной становится база данных, с настоящего момента и до конца ее жизни. "

Если вы достигнете момента в своей карьере, когда управляете программным проектом, часть вашей работы будет заключаться в назначении обязанностей по кодированию лицам, наиболее подходящим для их выполнения. На архитектурном уровне кто-то также назначает программные обязанности - например, целостность данных - модулю или подсистеме, наиболее подходящим для их выполнения. Целостность данных может быть гарантирована только , если назначить эту ответственность для dbms. Присвоение его любой другой части системы, будь то код или человек, является просто выражением надежды, и надежда плохо масштабируется.

0 голосов
/ 07 июня 2011

Это зависит от того, хотите ли вы, чтобы система управления базами данных управляла данными, или вы хотите, чтобы приложение управляло данными. В большинстве случаев СУБД работает лучше, потому что для этого она и создана.

0 голосов
/ 06 июня 2011
  1. Вам нужна дополнительная логика для анализа CSV на стороне кода.
  2. Большинство ORM не поддерживает CSV.
  3. Если у вас длинное имя роли (например, UserWhoHaveAccessToXObjButNotYObjAndAtTheSameTimeCanDoZ)затем вы теряете пространство, повторяя его для всех пользователей.

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

...