【问题标题】:Assigning multiple roles to a single user为单个用户分配多个角色
【发布时间】:2012-11-02 18:00:39
【问题描述】:
我目前正在设计一个具有以下要求的角色驱动菜单的数据库。
1. Menu items can be assigned to a certain 'role'
2. A role will be assigned to a user
3. A user can have multiple roles
我已经设计了数据库,但是在我当前的设计中我无法将多个角色映射到单个用户。另外,我不明白在查询时如何映射重复的菜单项(当用户被分配多个角色时),即使我以某种方式将其包含在我的设计中。
我虽然将角色存储为逗号分隔值,但这会进一步引入复杂性。
他们是更好的解决方案吗?
【问题讨论】:
标签:
asp.net
database-design
relational-database
normalization
database-normalization
【解决方案1】:
用户和角色之间的关系是多对多的关系,因此您必须在具有两个外键的表中对关系进行建模。比如:
UserToRole
====================
UserToRoleId INTEGER
UserId(FK) INTEGER
RoleId(FK) INTEGER
然后您可以使用此表将用户表和角色表连接在一起并获取多个值。
【解决方案2】:
C. Trimble 是正确的 (+1)。如果您的菜单项可用于多个角色并且您的用户可以具有多个角色,那么您实际上有两个多对多关系需要记录。
也就是说你需要再添加一张表,如下:
该表可以根据 C.Trimble 的回答包含列,或者您可以有一个只有 UserId + RoleId 的复合主键 - 类似于您的 MenuItemRoles 表。后者将是我的设计偏好,因为该表是一个纯粹的交集,并且没有特别的理由期望 UserRoles 会有与之相关的孩子。
请注意,当您检索用户菜单项访问权限时,您可以将链接从 UserRoles 短路到 MenuItemRoles,因为它们都有一个 RoleId 列。这意味着您可以直接在交集表之间加入,而将Roles 排除在外。在 TSQL 中它看起来像:
select I.* -- Never select * in the real world.
from MenuItem I
inner join MenuItemRoles IR
on I.ItemId = IR.ItemId
inner join UserRoles UR
on IR.RoleId = UR.RoleId
where
UR.UserId = @TheUserImLookingFor
您可以在 LINQ 中做同样的事情。如果您使用的是 EF,那么您将不得不走很长一段路(通过Roles)。