说服怀疑者!为什么我的数据库中需要一个“ Roles”表?

| 在设计用于存储简单用户/角色信息的数据库表时,谁能告诉我为什么将角色信息直接存储在用户表上(例如,在“角色”列中用逗号分隔)是一个不好的主意。 想法: 数据库不需要知道角色,这是UI的域 访问特定用户角色的速度越快越好 当然,如果将来我想访问所有用户以使用特定角色,查询可能 有点慢,但是那时谁在乎呢? 这有意义吗?我离开摇杆了吗?创建Roles和UserRole表是否会过大并增加不必要的sql和代码开销? 更新: 为了进一步说明我的观点……在代码中,我想知道用户“ Steve”是否具有角色“ Administrator”。 选项1:在UserRole表中查询用户\“ Steve \”的角色列表。遍历该列表,查看RoleName是否与\“ Administrator \”相匹配。 选项2:在“用户”的“角色”属性中拆分csv,然后查看结果列表中是否包含“管理员” 更新二: 我同意我的建议违反了各种“最佳实践”类型的思维方式,尤其是在数据库设计方面。但是,我看不到“最佳实践”在这种情况下如何有意义。我确实喜欢时不时地摇动最佳实践……我喜欢以一种看起来很聪明的方式编写代码,这意味着有时我需要了解更多信息才能知道自己何时不聪明:)     
已邀请:
        因为它违反了第三范式。您想将所有实体分隔为不同的对象,这意味着您需要一个独立的表以及一个关系表。 违反数据 如果将所有这些信息都放在一个表中,那么您会在用户表中放置太多与用户无关的信息。用户表应该具有仅与该用户有关的字段,例如其名称,用户帐户等。但是在这种情况下,您已经决定添加一些角色信息。这是没有意义的,因为您要添加不必要与用户有关的属性。 结果是您开始添加与用户无关的字段,并且最终拥有大量不相关的信息。解决方案是有一个用户表,如下所示:
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的规则并创建一个不错的关系结构,则UI会简单得多。 UI管理员屏幕不仅看起来不错,而且与解析或搜索相对,获取特定UserID的角色也是如此琐碎...     
我认为这不是一个好计划。假设您正在手动更新某人的角色,并且您键入的角色名称略有错误?如果您有单独的表,则数据库约束将警告您。假设您决定更改角色名称?如果您有单独的表,则只需在一个地方进行更改。 数据库规范化是有充分理由的。不只是挑剔。您不会在多个地方重复代码库中的关键代码;数据库非规范化是等效的。 编辑添加: 您指出应用程序最终将根据数据库返回的值来做出决策;例如如果用户具有名为“ Admin”的角色,则授予某些选项。的确如此,这是另一个独立的地方,例如角色名称的一致性可能会出现问题。我不认为对数据库进行非规范化处理的可能性较小。 解决此问题的一种好方法(也是实现授权的一种好方法)是在代码中拥有一个位置,将角色转换为某些通用功能(例如,管理员可以读写所有实体,来宾可以读取某些实体)并且不能写任何东西,等等。)然后,在许多需要建立访问权限的地方,您要检查能力而不是角色。 就是说,在视图中,如果要确定是否在项目描述上显示“编辑”按钮,则不要通过执行ѭ5进行检查,而是通过进行ѭ6进行检查。您已经在其他地方确定了管理员和编辑者可以编辑项目。例如,请参阅Rails授权系统CanCan使用的方法。 使用这种方法,您只能在一个地方引用角色的名称(例如,在CanCan中,您是否有一个名为“ abilities \”的类,该类根据其角色定义了谁可以做什么的所有规则。在其他任何地方,您都要参考用户确定他们可以做什么或看到的内容的能力。     
         您需要额外的逻辑来在代码端解析CSV。 大多数ORM不支持CSV。 如果角色名很长(例如UserWhoHaveAccessToXObjButNotYObjAndAtTheSameTimeCanDoZ),那么您将浪费所有用户重复此角色的空间。 同样,您的第一个假设并不适用于所有情况。如果我的数据库需要了解角色怎么办?     
        这取决于您是要数据库管理系统来管理数据还是要应用程序来管理数据。在大多数情况下,DBMS做得更好,因为这是它的基础。     
        你说   那么为什么不仅仅定义角色   在应用程序中,并且仅在   应用? 仅当您可以如实地说:“我100%确信每个程序员和每个数据库管理员都将手动完美维护数据完整性,无论使用哪种应用程序,无论使用哪种语言,都可以可靠地做到这一点。从现在开始到使用寿命结束,无论程序员是多么经验丰富或缺乏经验,也不管数据库变得多么复杂,都可以使用这种方式进行编程。” 如果您在职业生涯中达到管理编程项目的水平,那么您的部分工作就是将编码职责分配给最适合执行这些编程职责的人员。在体系结构级别,有人还会将程序职责(例如数据完整性)分配给最适合执行它们的模块或子系统。只能通过将责任分配给dbms来保证数据完整性。将其分配给系统的任何其他部分,无论是代码还是人工的,都只是希望的一种表达,而希望却无法很好地扩展。     

要回复问题请先登录注册