2009-06-07 4 views
0

je le scénario suivant:Mettre en œuvre un accès au niveau utilisateur/groupe d'utilisateurs à des enregistrements dans la base de données (au niveau de l'application)

1) un utilisateurs table:

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

2) un UserGroups table:

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

3) un UserGroupMembership tableau:

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

et 4) un Contacts table:

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

Je cherche un moyen d'avoir des contacts dans mes contacts la table soit (tout le monde "public" peut voir it), ou limité à une combinaison d'un/plusieurs UserGroups ou d'utilisateurs individuels. Complètement coincé ici .... Aide? Pourquoi ne pas utiliser une table supplémentaire reliant les contacts et les groupes d'utilisateurs?

Répondre

1

par exemple.

ContactsAccess

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

Vous pouvez utiliser une valeur particulière (par exemple zéro (0)) pour indiquer un accès illimité, ou vous pouvez modifier les Contacts table pour indiquer le type d'autorisation.

+0

Il peut également être seulement 4 personnes de "utilisateurs" et 2 groupes. Cela signifierait une autre table de relation entre les utilisateurs et les contacts droit? Cela va être très cher sur la récupération de données :( – Alex

+0

si elle nécessite des utilisateurs aussi, alors je dirais qu'une table supplémentaire est le bon choix –

0

La façon dont je serais probablement aller à ce sujet est une table semblable au suivant (MySQL):

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

Une clé unique ou primaire sur les trois champs est probablement pas une mauvaise idée non plus. Le basculement entre public/private doit être un champ dans le tableau Contacts.

+0

jointures à cette table devrait encore être doublé (sur type = ' Contact '... et sur type =' Group '), il présente l'inconvénient de rendre la table plus grande: une approche à deux tables a le même nombre de jointures, mais des tables plus petites et la possibilité d'utiliser des contraintes de clés étrangères. –

0

Voici deux façons de le faire sans avoir à créer d'autres table MN pour chaque entité dans votre base de données, tel que proposé dans d'autres réponses:

  1. Vous pouvez ajouter la table EntityBase que toutes les entités hériteraient de (ce qui signifie qu'il y aurait une relation 1-1 sur l'identité de l'entité). Par conséquent, il n'y aurait qu'une seule table EntityAccess avec EntityId (fk) liant à la table EntityBase. La table de contact aurait une colonne EntityId (fk, pk). Vous interrogez la table EntityBase juste quand vous le souhaitez. IIRC C'est l'approche utilisée dans VTiger CRM où il existe une table CRMEntity générale.

  2. Il existe encore un autre moyen, utilisé par MS Dynamics CRM. Cela empêche d'ajouter des tables intermédiaires pour chaque entité, mais n'assure pas les contraintes de référence.

Le point crucial de cette approche réside dans le tableau suivant:

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

PrincipalId peut pointer soit UserId teamid (équipe est tout simplement un groupe d'utilisateurs). ObjectId peut pointer vers n'importe quelle entité dans votre modèle, en fonction de ObjectTypeCode (que ce soit Contact, Account, Project, etc.).

AccessRightMask est un indicateur de enumaration binaire:

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