Search code examples
asp.netdatabase-designrelational-databasenormalizationdatabase-normalization

Assigning multiple roles to a single user


I am currently designing a database with a role driven menu which has following requirements.

 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

I have designed the database however I cannot map multiple roles to a single user in my current design. Also, I don't understand how would I map the duplicate menu items (When a user is assigned multiple roles) while querying even if I include it in my design somehow.

I though about storing roles as comma separated values however that would further introduce complications. Is their a better solution? enter image description here


Solution

  • C. Trimble is right (+1). If your menu items are available to multiple roles and your users can have multiple roles, then you actually have two many-to-many relationships that need to be recorded.

    That means that you need to add one more table, as below:

    ERD

    This table could have columns as per C. Trimble's answer, or you could have a compound primary key of just UserId + RoleId - analogous to your MenuItemRoles table. The latter would be my design preference since the table is a pure intersection and there is no particular reason to expect that UserRoles would have children relating to it.

    Note that when you are retrieving user menu item access you can short-circuit the link from UserRoles to MenuItemRoles because they both have a RoleId column. This means you can join directly between the intersection tables, leaving Roles out of it. In TSQL it would look like:

    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
    

    You could do the same thing in LINQ. If you're using EF then you're just going to have to go the long way around (through Roles).