2009-06-07 5 views
0

Ich habe folgendes Szenario:Implementieren Benutzer/Benutzergruppe Ebene Zugriff auf Datensätze in der Datenbank (auf Anwendungsebene)

1) einen Benutzer Tabelle:

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

2) einen Usergroups Tabelle:

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

3) a UserGroupMembership Tabelle:

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

und 4) ein Kontakte Tabelle:

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

ich nach einem Weg suchen kann haben Kontakte in meinem Kontakte Tisch entweder "öffentlich" (alle sehen es) oder auf eine beliebige Kombination von einer oder mehreren Benutzergruppen oder einzelnen Benutzern beschränkt.

Völlig fest hier .... Hilfe?

Antwort

1

warum nicht eine zusätzliche Tabelle verwenden, die Kontakte und UserGroups betrifft? z.B.

ContactsAccess

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

Sie einen besonderen Wert (zum Beispiel Null (0)) uneingeschränkten Zugang zu zeigen, verwenden könnten, oder Sie könnten die Kontakte Tabelle ändern Sie den Berechtigungstyp anzuzeigen.

+0

Es kann auch nur 4 Personen von "Benutzer" und 2 Gruppen. Das würde eine andere Beziehungstabelle zwischen Benutzern und Kontakten bedeuten, oder? Das wird sehr teuer bei Datenabruf :( – Alex

+0

Wenn es auch Benutzer erfordert, dann würde ich sagen, eine zusätzliche Tabelle ist die richtige Wahl. –

0

Die Art, wie ich wahrscheinlich darüber gehen würde, ist eine Tabelle, ähnlich die folgenden (MySQL):

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

Ein eindeutiger oder Primärschlüssel über all wahrscheinlich drei Felder ist entweder keine schlechte Idee. Der Wechsel zwischen public/private sollte ein Feld in der Tabelle Contacts sein.

+0

Joins zu dieser Tabelle müsste noch verdoppelt werden (auf Typ = ' Kontakt '... und auf type =' Group ') nur hat es den Nachteil, die Tabelle selbst größer zu machen.Ein Ansatz mit zwei Tabellen hat die gleiche Anzahl von Joins, aber kleinere Tabellen und die Möglichkeit, Fremdschlüsseleinschränkungen zu verwenden. –

0

Hier sind zwei Möglichkeiten, es zu tun, ohne zusätzliche MN Tabelle in der db für jede Einheit zu schaffen, wie sie in anderen Antworten vorgeschlagen:

  1. Sie könnten EntityBase Tabelle hinzufügen, die alle Einheiten von erben würden (was bedeutet, dass es eine 1: 1-Beziehung zur Entity-ID geben würde).

    Daher würde es nur eine einzige EntityAccess-Tabelle geben, deren EntityId (fk) mit der EntityBase-Tabelle verknüpft ist. Kontakttabelle würde EntityId (fk, pk) Spalte haben. Sie würden die EntityBase-Tabelle genau dann abfragen, wenn Sie möchten.

    IIRC Dies ist der Ansatz in VTiger CRM, wo es eine allgemeine CRMEntity-Tabelle gibt.

  2. Es gibt noch einen anderen Weg, der von MS Dynamics CRM verwendet wird. Es verhindert das Hinzufügen von Zwischentabellen für jede Entität, stellt jedoch keine Referenzbeschränkungen sicher.

Der Kern dieses Ansatzes liegt in der folgenden Tabelle:

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

PrincipalId Punkt kann entweder UserId oder TeamId (Team ist nur eine Gruppe von Benutzern). ObjectId kann abhängig vom ObjectTypeCode (sei es Kontakt, Konto, Projekt usw.) auf eine beliebige Entität in Ihrem Modell verweisen.

AccessRightMask ist eine binäre enumaration Flagge:

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