我目前正在设计一个具有角色驱动菜单的数据库,该菜单具有以下要求。
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
我设计了数据库但是我无法在当前设计中将多个角色映射到单个用户。此外,我不明白如何在查询时映射重复的菜单项(当用户被分配多个角色时),即使我以某种方式将其包含在我的设计中也是如此。
我虽然将角色存储为逗号分隔值,但这会进一步引入并发症。 他们是更好的解决方案吗?
答案 0 :(得分:2)
用户和角色之间的关系是多对多关系,因此您将不得不在具有两个外键的表中建模关系。类似的东西:
UserToRole
====================
UserToRoleId INTEGER
UserId(FK) INTEGER
RoleId(FK) INTEGER
然后,您可以使用此表将Users和Roles表连接在一起并获取多个值。
答案 1 :(得分:2)
℃。 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
)。