2009-06-07 50 views
0

我有以下情形:实现在数据库中记录的用户/用户组级访问(应用级)

1)用户表:

int Id (PK, Identity) 
// more users table columns (firstname, etc.) 

2)群组表:

int Id (PK, Identity)  
// more usergroups table columns (title etc.) 

3)UserGroupMembership表:

int Id 
int UserId (FK->Users.Id) 
int UserGroupId (FK->UserGroups.Id) 

以及4)联系表:

int Id (PK, Identity) 
// more contacts table columns.. 

我正在寻找一种方法来在我联系人的联系人表无论是 “公共”(每个人都可以看到它),或限制为一个/多个用户组或单个用户的任意组合。

完全卡在这里....帮助?

回答

1

为什么不使用关联Contacts和UserGroups的附加表? 例如

ContactsAccess

int UserGroups.Id (FK) 
int Contacts.Id (FK) 

你可以使用一个特殊值(例如零(0))来表示不受限制的访问,或者你可以修改联系人表指示权限类型。

+0

从 “用户” 和2组也可能只是4个个体。那意味着用户和联系人之间的另一个关系表是正确的? 这对于数据检索来说是非常昂贵的:( – Alex 2009-06-07 05:38:24

+0

如果它需要用户,那么我会说额外的表是正确的选择。 – 2009-06-07 05:39:30

0

我可能会去了解它的方式是类似于以下(MySQL的)的表:

CREATE TABLE `ContactsVisibleTo` (
    `ContactID` INT NOT NULL , 
    `Type` ENUM('User', 'Group') NOT NULL , 
    `ID` INT NOT NULL 
) 

唯一或主键在所有三个字段可能不是一个坏主意要么。公共/私人之间的转换应该是Contacts表中的字段。

0

这里有两种方法可以做到这一点,而无需创建额外的MN表在你的数据库的每个实体,在其他的答案提出:

  1. 您可以添加EntityBase表,所有的实体将继承(这意味着实体id会有1-1关系)。

    因此,EntityId(fk)将只有一个EntityAccess表连接到EntityBase表。联系人表将具有EntityId(fk,pk)列。你会在需要时查询EntityBase表。

    IIRC这是VTiger CRM中使用的方法,其中有一个通用的CRMEntity表。

  2. 还有另一种方式,由MS Dynamics CRM使用。它防止为每个实体添加中间表,但不确保参考约束。

这种方法的关键在于如下表所示:

PrincipalObjectAccess 
--------------------- 
... 
PrincipalId 
ObjectId 
PrincipalTypeCode 
ObjectTypeCode 
AccessRightMask 
... 

PrincipalId可能指向任何用户ID或TeamId(团队是只是一组用户)。 ObjectId可能指向模型中的任何实体,具体取决于ObjectTypeCode(无论是Contact,Account,Project等)。

AccessRightMask是二进制enumaration标志:

Read = 1 
Write = 2 
Append = 4 
AppendTo = 16 
Create = 16 
Delete = 65536 
Share = 262144 
Assign = 524288