Portal > Foren > PHP > PHP-Programmierung > datenbankschema für gruppenbasierte Rechteverwaltung
Antwort
 
LinkBack Themen-Optionen Thema durchsuchen
Alt 18.10.2008, 11:15 Nach oben    #1
Jann Hendrik Bekaan
 
Benutzerbild von Jann Hendrik
 
Registriert seit: 02.12.2004
Ort: Wildeshausen
Beiträge: 3.198
Standard datenbankschema für gruppenbasierte Rechteverwaltung

Ich möchte ein Gruppenbasiertes Rechtesystem in einer Datenbank verwalten. Dabei soll es verschiedene Dinge geben, die eingestellt werden sollen, was man machen darf. Dann soll es verschiedene Gruppen geben, die verschiedene Dinge aus der Rechte-Liste zugewiesen bekommen können, was sie dürfen und was nicht.
Jeder user wird dann einer oder mehr Gruppen zugewiesen, worduch sich seine Rechte ergeben.

Soweit eigentlich nichts spektakulär neues - nur für mich ist das was neues

Ich denke, dass ich das ganze soweit normalisiert habe (was man ja machen soll).


Ich habe eine Tabelle mit usern, in der die wichtigen Daten enthalten sind: Name, Passwort, E-Mail-Adresse usw.
Hier mal nur der wichtige Auszug aus der Tabelle:
Code:
+------------------------------+
| user                         |
+------------------------------+
| ID | name         | password |
+----+--------------+----------+
| 1  | Jann Hendrik | abc      |
| 2  | pago         | def      |
| 3  | noch jemmand | ghi      |
| .. | ...          | ...      |
+----+--------------+----------+
Dann habe ich eine Tabelle mit der Übersicht der verschiedenen Gruppen, die es in dem System gibt:

Code:
+--------------------+
| groups             |
+--------------------+
| ID | groupname     |
+----+---------------+
| 1  | bloger        |
| 2  | user          |
| 3  | moderator     |
| 4  | administrator |
| .. | ...           |
+----+---------------+
Die Verknüpfung der beiden Tabellen geschieht über die Tabelle, die ich hier mal einfach 'user_in_groups' genannt habe. Es wird also die ID des users und die ID der Gruppe miteinander verknüpft. Der User mit der ID x kann also in mehreren Gruppen sein.

Code:
+-------------------------+
| user_in_groups          |
+-------------------------+
| ID | user_ID | group_ID |
+----+--------------------+
| 1  | 1       | 1        |
| 2  | 1       | 3        |
| 3  | 5       | 2        |
| 4  | 2       | 1        |
| .. | ...     | ...      |
+----+--------------------+
Dann möchte ich einstellen können, welche Rechte es alles geben kann:

Code:
+-----------------+
| permission      |
+-----------------+
| ID | permission |
+----+------------+
| 1  | darf_a     |
| 2  | darf_b     |
| 3  | darf_c     |
| 4  | darf_d     |
| .. | ...        |
+----+------------+
Und dann benötige ich natürlich noch die Einstellungen welche Gruppe was darf_
Code:
+-------------------------------+
| group_permission              |
+-------------------------------+
| ID | group_ID | permission_ID |
+----+----------+---------------+
| 1  | 1        | 1             |
| 2  | 4        | 2             |
| 3  | 3        | 1             |
| 4  | 1        | 2             |
| .. | ...      | ...           |
+----+----------+---------------+
Gibt es gegen das Desing was einzuwenden?


Wenn nicht, dann hätte ich dazu nämlich ein paar Fragen.

Ich möchte wenn sich nun ein user einlogt eine session starten, in der sämtliche Rechte abgespeichert sind.
Auf der jeweiligen Seite die ihm dann angezeigt wird, sofern er die Rechte hat, wird dann eine entsprechende Abfrage gestartet, ob der user auch wirklich die Rechte für diese Seite hat à la
PHP-Code:
<?php
 
if(!isset($_SESSION['darf_a']) or $_SESSION['darf_a'] === FALSE)
   exit(
'<h2>Bitte erst einloggen! bzw. nicht ausreichend Rechte</h2>');
?>
Nun aber die Frage: Wie komme ich zu diesem session_array?
Ich habe gerade keine Idee, wie ICH die 5 Tabellen sinnvoll verbinden kann.
Die Thematik JOIN bei mysql habe ich bisher immer vermieden, weil ich das bisher nicht verstanden habe. Mir scheint aber so, als wäre das nun mal an der Zeit....
__________________

Umfragen:
bitte beachten: Vorschläge für künftige Umfragen
Woher weißt du vom developers-guide?

Wenn du dich in ein interessantes Thema eingearbeitet hast, dann lass andere daran teilhaben! Schreibe ein Tutorial und beschreibe, wie es geht, was nicht klappt, wo man aufpassen muss usw.
Danke!
Jann Hendrik ist gerade online  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 18.10.2008, 11:33 Nach oben    #2
Erfahrener Benutzer
 
Registriert seit: 18.03.2005
Beiträge: 696
Standard

Zitat:
Gibt es gegen das Desing was einzuwenden?
Wenn der Benutzer in mehrere Gruppen eingeteilt werden kann, finde ich das ok.
Wenn der Benutzer jedoch nur einer Gruppe zugeteilt wird, dann kann man die group_ID auch gleich in die User-Tabelle schreiben und spart man sich schon ein Query.
Bei diversen Projekten von mir, ist das unter user_level definiert.
Die jeweilige SESSION kann ja ein Array sein, was alle group_IDs enthält.

$_SESSION['level']['darf_a']
$_SESSION['level']['darf_b']
etc...

Muss dann natürlich immer abgefragt werden.

Zitat:
Die Thematik JOIN bei mysql habe ich bisher immer vermieden
Da bist du nicht der einzigste :)
CIX88 ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 18.10.2008, 12:04 Nach oben    #3
Jann Hendrik Bekaan
 
Benutzerbild von Jann Hendrik
 
Registriert seit: 02.12.2004
Ort: Wildeshausen
Beiträge: 3.198
Standard

Zitat:
Zitat von CIX88 Beitrag anzeigen
und spart man sich schon ein Query.
Das mag sein - aber diese Flexibilität möchte ich mir nicht nehmen.
Ich halte es in diesem Falle für vorteilhaft, wenn user x in Gruppe a, b und c sein kann auch wenn es eine kleine Performance-Bremse darstellen sollte.
Das wird kein Projekt wo zig user gleichzeitig drauf zugreifen werden, so dass ich denke, dass das vertretbar sein dürfte.


In der Session selbst wollte ich das in etwa so abspeichern
PHP-Code:
$_SESSION['permission']['darf_a'] = true//false, jenachdem 
Dann kann ich das ganz bequem auf jeder Seite aus dem Session-Array entnehmen.
Alternativ könnte ich auch erst auf der Seite die SQL-Abfrage machen, was ich aber dann doch lieber über das array cachen möchte.

In Abhängigkeit des arrays möchte ich nämlich auch die Navigation darstellen. Die Bereiche, für die der jeweilige user keine Rechte hat, die sollen ihm auch in der Navigation verborgen bleiben. Somit wäre es (finde ich) schon sinnvoll das Rechte-System in dem array abzuspeichern, damit man dann nicht bei jedem Aufrauf wieder die DB-Abfrage starten muss.
__________________

Umfragen:
bitte beachten: Vorschläge für künftige Umfragen
Woher weißt du vom developers-guide?

Wenn du dich in ein interessantes Thema eingearbeitet hast, dann lass andere daran teilhaben! Schreibe ein Tutorial und beschreibe, wie es geht, was nicht klappt, wo man aufpassen muss usw.
Danke!

Geändert von Jann Hendrik (18.10.2008 um 12:07 Uhr)
Jann Hendrik ist gerade online  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 18.10.2008, 13:59 Nach oben    #4
Neuer Benutzer
 
Registriert seit: 04.08.2006
Beiträge: 1
Standard

Zu der Tabelle "user_in_groups":
Warum benutzt du noch eine Id? Eine Zeile ist doch schon eindeutig identifizierbar, da kein Benutzer 2x in der gleichen Gruppe ist.
zwerg ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 18.10.2008, 14:39 Nach oben    #5
Johannes Müller
 
Benutzerbild von $traight-$hoota
 
Registriert seit: 15.09.2005
Ort: Königreich Flieden
Beiträge: 693
Standard

Die Berechtigungen in der Session zu speichern ist eigentlich ziemlicher standard und funktioniert auch ganz gut. Ggf. müsste man sich nur was überlegen, wie die gespeicherten Rechte erneuert werden können, wenn ein Administrator irgendwelche Rechte ändert während gerade ein User eingeloggt ist und diese Änderung nicht erfahren würde. Also für die Anzeige etc. ist das sicherlich nicht so schlimm, sobald aber irgendwelche Änderungen durchgeführt werden, wäre ein live-abgleich mit der Datenbank praktisch, um zu überprüfen, ob die Rechte wirklich noch vorhanden sind.
Das wäre nur ein Ansatz, es könnte auch so gemacht werden, dass bei ner Änderung der Berechtigungen irgendwie alle Session-Daten gelöscht werden, damit sie beim nächsten Seitenaufruf eines Users wieder neu aus der DB geholt werden.

Bei deinen Tabellen besteht unter Umständen noch Optimierungspotential.
Die Tabelle user_in_groups benötigt keine ID, da durch die beiden Keys jeder Zeile eindeutig benannt ist. Möglicherweise könntest du dir die Tabelle, ähnlich wie beim Vorschlag von CIX, auch ganz sparen, indem du eine Spalte groups in der user-Tabelle anlegst, die ein Array aller Gruppen-IDs enthält, denen der User angehört.
Dadurch geht die primäre Abfragerichtung "User -> Gruppen" etwas schneller (da ein Query gespart), die Abfrage "Gruppe -> Users" ist dagegen relativ selten (wird eigentlich nur für die Mitgliederübersicht einer Gruppe benötigt), also macht es nichts, wenn die ein bischen langsamer ist. Wobei ich garnicht mal weiß, ob das soo viel dann ausmacht.

Als nächstes stellt sich mir die Frage, ob die Tabelle permission überhaupt notwendig ist. Sie dient ja eigentlich nur dazu, in MySQL irgendwelche Konstanten festzulegen. Bei einer vernünftigen Programmierung müssten diese Konstanten als Bezeichner für eine Berechtigung aber auch im Programm definiert sein, daher ist in der Datenbank nur eine unnötige Doppelung, die noch mehr Aufwand macht.
Dann ist nämlich auch group_permission unnötig und es geht ganz einfach mit einer Spalte permissions in der Tabelle groups, in der durch Kommata getrennt die einzelnen Rechte stehen.

Interessant ist es bei solchen Designentwürfen auch immer, sich mal anzusehen, wie das in anderer Software gelöst wird. Ich habe jetzt grad keine DB zur Verfügung, aber ich meine, dass z.B. Drupal das so ähnlich macht, dass die zugewiesenen Rechte einfach als Namen in einer Spalte in der Tabelle User bzw. Gruppe stehen.

Noch ein paar kleinere Sachen:
Warum sind alle Tabellennamen im Singular, nur groups im Plural?
Das Password wird in Wirklichkeit doch als Hash gespeichert, oder?
__________________
Weißt Bescheid - Scheiß wie weit
$traight-$hoota ist gerade online  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 18.10.2008, 15:13 Nach oben    #6
Jann Hendrik Bekaan
 
Benutzerbild von Jann Hendrik
 
Registriert seit: 02.12.2004
Ort: Wildeshausen
Beiträge: 3.198
Standard

Zitat:
Zitat von zwerg Beitrag anzeigen
Zu der Tabelle "user_in_groups":
Warum benutzt du noch eine Id? Eine Zeile ist doch schon eindeutig identifizierbar, da kein Benutzer 2x in der gleichen Gruppe ist.
Okay, das ist ein Argument. Ich gestehe: Eine ID die als Primärschlüssel dient (auto_increment) packe ich eigentlich erstmal immer in eine neue Tabelle.



Zitat:
Zitat von $traight-$hoota Beitrag anzeigen
Ggf. müsste man sich nur was überlegen, wie die gespeicherten Rechte erneuert werden können, wenn ein Administrator irgendwelche Rechte ändert während gerade ein User eingeloggt ist und diese Änderung nicht erfahren würde.
Genau das ist der Eiertanz bei der Sache des Cachens. Aber ich kann in diesem Fall damit durchaus gut leben.
Was man machen könnte ist der Session noch einen Zeitstempel aufdrücken.
Wenn dann die Startseite besucht wird und der Zeitstempel zu alt, dann werden die Session-Daten neu geschrieben.
Bei mir reicht es aber völlig aus, wenn der entspr. user sich einmal aus- und später wieder einlogen muss.

Zitat:
Zitat von $traight-$hoota Beitrag anzeigen
Bei deinen Tabellen besteht unter Umständen noch Optimierungspotential.
Die Tabelle user_in_groups benötigt keine ID, da durch die beiden Keys jeder Zeile eindeutig benannt ist.
Wie bereits gesagt... Bei mir gibt es erstmal die ID - und dann schaue ich, ob mein Design sie auch benötigt...

Zitat:
Zitat von $traight-$hoota Beitrag anzeigen
Möglicherweise könntest du dir die Tabelle, ähnlich wie beim Vorschlag von CIX, auch ganz sparen, indem du eine Spalte groups in der user-Tabelle anlegst, die ein Array aller Gruppen-IDs enthält, denen der User angehört.
Okay, das wäre eine Möglichkeit, wobei ich ein array in einem DB-Feld nicht sonderlich geschickt finde.
Wenn ich es mir aussuchen darf, dann würde ich bei dem bisherigen Designvorschlag bleiben wollen.

Zitat:
Zitat von $traight-$hoota Beitrag anzeigen
Als nächstes stellt sich mir die Frage, ob die Tabelle permission überhaupt notwendig ist. Sie dient ja eigentlich nur dazu, in MySQL irgendwelche Konstanten festzulegen. Bei einer vernünftigen Programmierung müssten diese Konstanten als Bezeichner für eine Berechtigung aber auch im Programm definiert sein, daher ist in der Datenbank nur eine unnötige Doppelung, die noch mehr Aufwand macht.
Den Teil kann ich gerade noch nicht nachvollziehen!

Zitat:
Zitat von $traight-$hoota Beitrag anzeigen
Interessant ist es bei solchen Designentwürfen auch immer, sich mal anzusehen, wie das in anderer Software gelöst wird.
Das setzt voraus, dass man das dort auch noch nachvollziehen kann.
Ich bin auf den Aufbau gekommen, weil ich mir überlegt habe, wie es gelöst sein könnte, weil ich weiß, welche Flexibilität es dadurch erlaubt. Gerade das ist ein Punkt, der in der Rechteverwaltung zB dieses Forums von mir sehr geschätzt wird. Durch den Aufbau der Datebank jedoch steige ich nicht ausreichd gut durch, als das ich sagen könnte, dass es reicht mir diesen Teil davon abschauen zu können.

Zitat:
Zitat von $traight-$hoota Beitrag anzeigen
Noch ein paar kleinere Sachen:
Warum sind alle Tabellennamen im Singular, nur groups im Plural?
Das Password wird in Wirklichkeit doch als Hash gespeichert, oder?
Ja, die Namen sind noch nicht optimal gewählt, das ist richtig. Aber ich denke, dass sie zur Demonstration hier ihren Zweck erfüllen.
Das Passwort - das ist bereits der hash ;) Nein, natürlich ist er das nicht... die werden nicht im Klartext gespeichert. Damit wollte ich mich aber separat beschäftigen. In der user-Tabelle stehen noch einige Daten mehr drin, die aber hierfür nicht relevant sind.
__________________

Umfragen:
bitte beachten: Vorschläge für künftige Umfragen
Woher weißt du vom developers-guide?

Wenn du dich in ein interessantes Thema eingearbeitet hast, dann lass andere daran teilhaben! Schreibe ein Tutorial und beschreibe, wie es geht, was nicht klappt, wo man aufpassen muss usw.
Danke!
Jann Hendrik ist gerade online  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 18.10.2008, 16:31 Nach oben    #7
Erfahrener Benutzer
 
Registriert seit: 12.06.2006
Beiträge: 335
Standard

Zitat:
Zitat von $traight-$hoota Beitrag anzeigen
Interessant ist es bei solchen Designentwürfen auch immer, sich mal anzusehen, wie das in anderer Software gelöst wird.
TYPOlight (mein Lieblingsbeispiel ;) ) löst das wie folgt für die Backend-User: Die Rechte sind Zugriffsrechte auf einzelne Felder der Tabellen der DB, sprich das TL-Backend fungiert als eine Art GUI/Wrapper für die DB. Man setzt also Schreibrechte auf Tabellenfelder. (Dazu müssen die DB-Felder "registriert" werden, ein Config-Array (bei TL heißt das Data-Container-Array, DCA) beschreibt Typ, Inhalt, Label, etc. Das ermöglicht auch die automatische Generierung und Validierung der Input-Felder.)

Das Frontend behandelt das glaub so: Ein Inhaltselement (das dann bestimmte Aktionen ermöglicht) bekommt ein paar Gruppen-IDs zugewiesen; diese werden mit den Gruppen-IDs des Nutzers verglichen. Wenn es Übereinstimmungen gibt, wird das Element angezeigt.
FloB ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 18.10.2008, 16:37 Nach oben    #8
Johannes Müller
 
Benutzerbild von $traight-$hoota
 
Registriert seit: 15.09.2005
Ort: Königreich Flieden
Beiträge: 693
Standard

Zitat:
Zitat von Jann Hendrik Beitrag anzeigen
Zitat:
Zitat von $traight-$hoota Beitrag anzeigen
Möglicherweise könntest du dir die Tabelle, ähnlich wie beim Vorschlag von CIX, auch ganz sparen, indem du eine Spalte groups in der user-Tabelle anlegst, die ein Array aller Gruppen-IDs enthält, denen der User angehört.
Okay, das wäre eine Möglichkeit, wobei ich ein array in einem DB-Feld nicht sonderlich geschickt finde.
Wenn ich es mir aussuchen darf, dann würde ich bei dem bisherigen Designvorschlag bleiben wollen.
Das darfst du natürlich, is ja deine Sache
Es mag zunächst vielleicht etwas befremdlich klingen, ein Arrayfeld in einer Tabelle zu verwenden, aber: Was ist denn so schlimm dran?? Man muss nicht alle Daten, die irgendwie in einer Listen- oder Tabellenform vorliegen zwanghaft in eine eigene Datenbanktabelle packen, wenn das überhaupt nicht erfoderlich ist; nur das meint man beim Design einer Datenbank meistens^^
Wenn man sich, wie oben schon angesprochen, mal andere Software anguckt, findet man es sehr oft, dass Daten, für die man auf den ersten Blick in eine eigene Tabelle erwarten würde, einfach irgendwo als Array in eine Spalte gespeichert sind, weil es einfach nicht notwendig ist eine Tabelle anzulegen, wenn in den meisten Fällen sowieso eine Abfrage aller Elemente des Array erfolgt und eine (einzelne) Rückverfolgung (in welchem Datensatz befindet sich der Wert XY) eher selten ist.
Zitat:
Zitat von Jann Hendrik Beitrag anzeigen
Zitat:
Zitat von $traight-$hoota Beitrag anzeigen
Als nächstes stellt sich mir die Frage, ob die Tabelle permission überhaupt notwendig ist. Sie dient ja eigentlich nur dazu, in MySQL irgendwelche Konstanten festzulegen. Bei einer vernünftigen Programmierung müssten diese Konstanten als Bezeichner für eine Berechtigung aber auch im Programm definiert sein, daher ist in der Datenbank nur eine unnötige Doppelung, die noch mehr Aufwand macht.
Den Teil kann ich gerade noch nicht nachvollziehen!
Nunja, hier solltest du dich wieder fragen: was bringt mir die Tabelle permissions, wenn dort nur einzelne Keywords gespeichert sind, die in der Form auch genauso im Quellcode enthalten sind.
Ausgehend von der Gruppenid hast du zum Abfragen aller Berechtigungen einer Gruppe (in Form des Namens "darf_X") folgenden Weg:
Code:
<Gruppe>:group.group_ID -> group_permission.group_ID | group_permission.permission_ID -> permission.ID | permission.permission:<Permission>
Wobei vorher schon jeder Aufruf der tabelle group n mal erfolgt, je nachdem in wie vielen Gruppen der User Mitglied ist. Die Anzahl der Aufrufe von group_permission und permission sind dann n*m(n) über zwei Tabellen (wobei m(n) jeweils die Anzahl der Berechtigungen einer Gruppe).
Das ganze ist viel einfacher, wenn bei einer einzigen Abfrage von groups bereits alle Berechtigungen als Array zurückgeliefert werden, genau so brauchst du es doch auch für dein Skript und das Caching in der Session.

Zitat:
Zitat von FloB Beitrag anzeigen
TYPOlight (mein Lieblingsbeispiel ) löst das wie folgt für die Backend-User: Die Rechte sind Zugriffsrechte auf einzelne Felder der Tabellen der DB, sprich das TL-Backend fungiert als eine Art GUI/Wrapper für die DB. Man setzt also Schreibrechte auf Tabellenfelder. (Dazu müssen die DB-Felder "registriert" werden, ein Config-Array (bei TL heißt das Data-Container-Array, DCA) beschreibt Typ, Inhalt, Label, etc. Das ermöglicht auch die automatische Generierung und Validierung der Input-Felder.)
Das halte ich ehrlich gesagt für nen ziemlichen Overhead, da Aktionen, zu denen eine Berechtigung notwendig ist, meist eine Vielzahl von DB-Feldern beeinflussen.
Wenn wir beispielsweise eine Berechtigung darf_editieren haben, entspricht das den Datenbankänderungen (und somit beim System von TYPYlight einzelnen Berechtigungen) der Felder article.name, article.body, article.lastModified. darf_erstellen entspricht article.id, article.name, article.body, article.created, article.lastModified. Und das sind noch relativ wenige Datenbankänderungen, die bei vielen anderen CMS mit einer einzigen Aktion (und der Berechtigung dazu) ausgeführt werden.
__________________
Weißt Bescheid - Scheiß wie weit

Geändert von $traight-$hoota (18.10.2008 um 16:49 Uhr)
$traight-$hoota ist gerade online  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 18.10.2008, 16:42 Nach oben    #9
Erfahrener Benutzer
 
Registriert seit: 18.03.2005
Beiträge: 696
Standard

Zitat:
Zitat von zwerg Beitrag anzeigen
Zu der Tabelle "user_in_groups":
Warum benutzt du noch eine Id? Eine Zeile ist doch schon eindeutig identifizierbar, da kein Benutzer 2x in der gleichen Gruppe ist.
Naja, wenn aber ein Nutzer unterschiedliche Gruppen haben kann, dann geht das nimmer :) Ich persönlich ziehe es auch immer vor eine ID anzulegen. Spätestents beim Verwalten von Einträgen macht sich das bezahlt.

Es sei denn, du benutzt eine andere Möglichkeit unterschiedliche Gruppen in einen Datensatz zu erfassen.
CIX88 ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 18.10.2008, 16:58 Nach oben    #10
Johannes Müller
 
Benutzerbild von $traight-$hoota
 
Registriert seit: 15.09.2005
Ort: Königreich Flieden
Beiträge: 693
Standard

Zitat:
Zitat von CIX88 Beitrag anzeigen
Zitat:
Zitat von zwerg Beitrag anzeigen
Zu der Tabelle "user_in_groups":
Warum benutzt du noch eine Id? Eine Zeile ist doch schon eindeutig identifizierbar, da kein Benutzer 2x in der gleichen Gruppe ist.
Naja, wenn aber ein Nutzer unterschiedliche Gruppen haben kann, dann geht das nimmer Ich persönlich ziehe es auch immer vor eine ID anzulegen. Spätestents beim Verwalten von Einträgen macht sich das bezahlt.

Es sei denn, du benutzt eine andere Möglichkeit unterschiedliche Gruppen in einen Datensatz zu erfassen.
Hä?

user.ID und group.ID sind jeweils Primary Keys und daher auch als Foreign Keys in user_in_group jeweils eindeutig. Über die nur einmal mögliche Kombination gleicher Keys user_ID und group_ID ergibt sich somit eine eindeutige Benennung jedes Datensatzes. Großartiges Verwalten sollte es da nicht geben, sondern lediglich das Hinzufügen eines Users zu Gruppe (neuer Datensatz mit den beiden IDs) und das Entfernen eines Users aus einer Gruppe (Datensatz mit den beiden IDs löschen).
__________________
Weißt Bescheid - Scheiß wie weit
$traight-$hoota ist gerade online  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 18.10.2008, 17:09 Nach oben    #11
Erfahrener Benutzer
 
Registriert seit: 12.06.2006
Beiträge: 335
Standard

Zitat:
Zitat von $traight-$hoota Beitrag anzeigen
Das halte ich ehrlich gesagt für nen ziemlichen Overhead, da Aktionen, zu denen eine Berechtigung notwendig ist, meist eine Vielzahl von DB-Feldern beeinflussen.
Wenn wir beispielsweise eine Berechtigung darf_editieren haben, entspricht das den Datenbankänderungen (und somit beim System von TYPYlight einzelnen Berechtigungen) der Felder article.name, article.body, article.lastModified. darf_erstellen entspricht article.id, article.name, article.body, article.created, article.lastModified. Und das sind noch relativ wenige Datenbankänderungen, die bei vielen anderen CMS mit einer einzigen Aktion (und der Berechtigung dazu) ausgeführt werden.
So einfach darf man das nicht sehen ;). Das System ermöglicht größtmögliche Flexibilität!

Beispiel: Redakteure bekommen das Recht, Inhalte, Überschriften etc. einzutragen, aber veröffentlich können sie einen Artikel nicht. Das kann dann aber der Chefredateur.
Sowas ist mit TL fix eingerichtet ;).

Einmal gibt es die "allgemeinen" Zugriffsrechte auf die Module/Extensions/Einstellungen etc, diese entsprechen dem Lesezugriff. Dann definiert man in den Gruppen nochmal die editierbaren Felder. Mag sein, dass an einer Stelle des Codes dann ein kleiner Overhead ensteht, aber an anderen Stellen wird somit jede Menge eingespart! Bei der Extension-Entwicklung z.B. muss man kaum Code schreiben (hauptsächlich die Beschreibungsarrays definieren). Rest läuft automatisch ab.

Schau es dir einfach mal an, ich kann es nicht so gut beschreiben.

Edit: Wo hast du z.B. kompliziertere Aktionen in einem Schritt? Sowas wird doch eh meist über mehrere Seiten verteilt ... dir ist bewusst, dass wir von Website-Verwaltungapplikationen reden ;) ?


Zu den Arrays: Kann ich meinen Vorrednern nur zustimmen. Arrays kann man prima in DBs legen. Einfach serialisieren und in ein BLOB damit.

Geändert von FloB (18.10.2008 um 17:11 Uhr)
FloB ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 18.10.2008, 17:29 Nach oben    #12
Erfahrener Benutzer
 
Registriert seit: 18.03.2005
Beiträge: 696
Standard

Zitat:
user.ID und group.ID sind jeweils Primary Keys
Möglich, mir wäre es allerdings zu heiß, auf die primäre ID zu verzichten.
Ich arbeite auch gerne mit primären IDs die völlig getrennt vom jeweiligen Datensatz sind. Einmal nicht aufgepasst, und schon wurde der falsche Datensatz erwischt :) Nene, dem beuge ich vor :) Sicher kann man darauf verzichten, jedoch bei mir hat sich das so angeeigent :) Aber um so mehr ich darüber nachdenke (spätere Verwaltung etc..) kann man sicher daruf verzichten.
CIX88 ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 18.10.2008, 19:32 Nach oben    #13
Jann Hendrik Bekaan
 
Benutzerbild von Jann Hendrik
 
Registriert seit: 02.12.2004
Ort: Wildeshausen
Beiträge: 3.198
Standard

Okay, nach dem für und wider würde ich sagen, dass ich trotz der Vorschläge dabei bleibe das DB-Design so aufzubauen.


Zitat:
Zitat von Jann Hendrik Beitrag anzeigen
Nun aber die Frage: Wie komme ich zu diesem session_array?
Ich vermute mal, dass ich mir eine Monster-SQL-Abfrage bauen muss, wo die verschiedenen keys ineinander greifen mit verschiedenen inner/outer und sonstwas-joins, oder?


Ich denke, ich würde das auch mit geschätzten 400 einzelnen queries hinbekommen, aber... dann würde ich ja nicht fragen :)
Ich will ja dabei auch noch was lernen.

Mag mir jemand Anschub-Hilfe geben?
__________________

Umfragen:
bitte beachten: Vorschläge für künftige Umfragen
Woher weißt du vom developers-guide?

Wenn du dich in ein interessantes Thema eingearbeitet hast, dann lass andere daran teilhaben! Schreibe ein Tutorial und beschreibe, wie es geht, was nicht klappt, wo man aufpassen muss usw.
Danke!
Jann Hendrik ist gerade online  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 18.10.2008, 23:30 Nach oben    #14
Christian W. Achatz
 
Benutzerbild von dr.e.
 
Registriert seit: 05.02.2007
Ort: München
Beiträge: 198
Standard

Hallo Jann,

Zitat:
Mag mir jemand Anschub-Hilfe geben?
An sich sind die Anfragen bei einem derartigen Design immer identisch. Veränderlich ist lediglich die Anzahl der JOINs und die Reihenfolge. Ich habe im Rahmen des GenericORMapper ein allgemeingültiges UserManagement-Modul implementiert, das du dir mal anschauen kannst. Um alle Benutzer zu selektieren, die einer Applikation zugeordnet sind, kannst du einfach ein

Code:
SELECT ent_user.* FROM ent_user
INNER JOIN cmp_application2user ON ent_user.UserID = cmp_application2user.UserID
INNER JOIN ent_application ON cmp_application2user.ApplicationID = ent_application.ApplicationID
WHERE ent_application.ApplicationID = '1'
ORDER BY ent_user.LastName ASC, ent_user.FirstName ASC;
als Abfrage selektieren. Um alle Benutzer einer bestimmten Gruppe in einer Applikation zu bekommen musst du zweimal über die entsprechenden Beziehungstabellen JOINen.

Hier noch die relevanten Links:
* http://adventure-php-framework.org/S...aden-von-Daten
* http://forum.adventure-php-framework...c.php?f=5&t=54
* http://adventurephpfra.svn.sourcefor...sermanagement/

Solltest du Fragen dazu haben, dann her damit! :)
__________________
Viele Grüße,
Dr.E.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1. Think about software design before you start to write code!
2. Discuss and review it together with experts!
3. Choose good tools (-> http://adventure-php-framework.org)!
4. Write clean and reusable software only!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dr.e. ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 18.10.2008, 23:36 Nach oben    #15
Jann Hendrik Bekaan
 
Benutzerbild von Jann Hendrik
 
Registriert seit: 02.12.2004
Ort: Wildeshausen
Beiträge: 3.198
Standard

Zitat:
Zitat von dr.e. Beitrag anzeigen
Solltest du Fragen dazu haben, dann her damit!
Die werden sehr wahrscheinlich kommen!
Aber erstmal versuche ich die Infos zu verdauen. Ggf. komme ich dann ja schon einen Schritt weiter ... :)
__________________

Umfragen:
bitte beachten: Vorschläge für künftige Umfragen
Woher weißt du vom developers-guide?

Wenn du dich in ein interessantes Thema eingearbeitet hast, dann lass andere daran teilhaben! Schreibe ein Tutorial und beschreibe, wie es geht, was nicht klappt, wo man aufpassen muss usw.
Danke!
Jann Hendrik ist gerade online  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 19.10.2008, 12:45 Nach oben    #16
Jann Hendrik Bekaan
 
Benutzerbild von Jann Hendrik
 
Registriert seit: 02.12.2004
Ort: Wildeshausen
Beiträge: 3.198
Standard

Also, ich habe meine Beispiel-Tabelle nun mal mit Daten gefüllt.
Für den Anfang darf jeder user nur in einer Gruppe sein und jeder Gruppe darf nur eine Sache machen. Für diesen Fall hätte ich das zwar auch direkt in die user-Tabelle schreiben können - aber... ich will mal klein anfangen.

Mit
Code:
SELECT
    `user`.`ID`, 
    `user`.`name`, 
    `user`.`password`, 
    `user`.`mail`, 
    `groups`.`groupname`, 
    `permissions`.`permission`

FROM  
    `user` 

INNER JOIN 
    `user_in_group` 
  ON 
    `user`.`ID` = `user_in_group`.`user_ID` 

INNER JOIN 
    `groups` 
  ON 
    `user_in_group`.`ID` = `groups`.`ID`

INNER JOIN 
    `group_permission` 
  ON 
    `groups`.`ID` = `group_permission`.`ID`

INNER JOIN 
    `permissions` 
  ON 
    `permissions`.`ID` = `group_permission`.`ID` 

WHERE 
    `user`.`ID` = 1
bekomme ich nun also heraus, in welcher Gruppe der user mit der ID 1 steckt und welches Recht (bisher Singular) diese Gruppe hat.

Allerdings stoße ich damit auf mein erstes Problem.
Wenn ein user in mehr als nur einer Gruppe ist funktioniert das insofern nicht mehr, als dass nicht alle Gruppen (nur eine) angezeigt werden. Ebenso auch, wenn eine Gruppe mehr als nur eine permission hat. Dann wird auch nur eine angezeigt.

Wenn ich die Rechte des users mit der ID 1 auslesen möchte, sollten aber alle dargestellt werden:
Code:
SELECT
`permissions`.`permission`
FROM  `user` 
INNER JOIN `user_in_group` ON `user`.`ID` = `user_in_group`.`user_ID` 
INNER JOIN `groups` ON `user_in_group`.`ID` = `groups`.`ID`
INNER JOIN `group_permission` ON `groups`.`ID` = `group_permission`.`ID`
INNER JOIN `permissions` ON `permissions`.`ID` = `group_permission`.`ID` 

WHERE `user`.`ID` = 1
Als Ausgabe hätte ich dann gerne sowas in der Art:

Code:
+------------+
| permission |
+------------+
| darf_a     |
| darf_c     |
| darf_r     |
+------------+

Deinen drei links konnte ich leider nichts verwertbares entnehmen. Das liegt ggf. aber auch an mir :)
__________________

Umfragen:
bitte beachten: Vorschläge für künftige Umfragen
Woher weißt du vom developers-guide?

Wenn du dich in ein interessantes Thema eingearbeitet hast, dann lass andere daran teilhaben! Schreibe ein Tutorial und beschreibe, wie es geht, was nicht klappt, wo man aufpassen muss usw.
Danke!
Jann Hendrik ist gerade online  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 19.10.2008, 13:24 Nach oben    #17
Christian W. Achatz
 
Benutzerbild von dr.e.
 
Registriert seit: 05.02.2007
Ort: München
Beiträge: 198
Standard

Hallo Jann,

das ist so ein bischen eine Frage der Philosophie. Im APF usermanagement habe ich das konzeptionell so gelöst, dass du dir erst mal einen Benutzer selektierst und diesen dann nach seinen Rechten fragst.

In einer Abfrage abgebildet kannst du das auf Grund der Beziehungen aber auch selektieren. Es muss in diesem Fall jedoch sichergestellt sein, dass deine Datenschicht diese Datenkonsistent gewährleistet. Um vom gleichen zu sprechen, nehmen wir mal folgendes UML als Basis: http://adventure-php-framework.org/S...aden-von-Daten

Dort steht beschrieben, dass eine Rolle und eine Gruppe jeweils "seinen" Benutzer kennt (Assoziation). Weiterhin kennt die Rolle "sein" PermissionSet, das wiederum seine Permissions komponiert. In diesem Fall würdest du die Permissions eines Benutzers über ungefähr folgendes Statement selektieren können:

Code:
SELECT ent_permission.* FROM ent_permission
INNER JOIN cmp_permissionset2permission ON ent_permission.PermissionID = cmp_permissionset2permission.PermissionID
INNER JOIN ent_permissionset ON cmp_permissionset2permission.PermissionSetID = ent_permissionset.PermissionSetID
INNER JOIN ass_role2permissionset ON ent_permissionset.PermissionSetID = ass_role2permissionset.PermissionSetID
INNER JOIN ent_role ON ass_role2permissionset.RoleID = ent_role.RoleID
INNER JOIN ass_role2user ON ent_role.RoleID = ass_role2user.RoleID
INNER JOIN ent_user ON ass_role2user.UserID = ent_user.UserID
WHERE ent_user.UserID = 1;
Wie ich schon sagte, musst du dir klar werden, in welchem Verhältnis / Beziehung die Objekte zueinander stehen und dann über die jeweils relevanten Beziehungstabellen JOINen.

Jetzt klar?
__________________
Viele Grüße,
Dr.E.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1. Think about software design before you start to write code!
2. Discuss and review it together with experts!
3. Choose good tools (-> http://adventure-php-framework.org)!
4. Write clean and reusable software only!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dr.e. ist offline  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Alt 23.10.2008, 19:24 Nach oben    #18
Jann Hendrik Bekaan
 
Benutzerbild von Jann Hendrik
 
Registriert seit: 02.12.2004
Ort: Wildeshausen
Beiträge: 3.198
Standard

Okay, ich realisiere, dass ich dafür gerade nicht die notwendige Ruhe habe...

Ich werde mich demnächst nochmal an das Thema machen.
__________________

Umfragen:
bitte beachten: Vorschläge für künftige Umfragen
Woher weißt du vom developers-guide?

Wenn du dich in ein interessantes Thema eingearbeitet hast, dann lass andere daran teilhaben! Schreibe ein Tutorial und beschreibe, wie es geht, was nicht klappt, wo man aufpassen muss usw.
Danke!
Jann Hendrik ist gerade online  
Add Post to del.icio.usBookmark Post in TechnoratiDiesen Beitrag zu Mister Wong hinzufügen!
Mit Zitat antworten
Antwort

Lesezeichen


Aktive Benutzer in diesem Thema: 1 (Registrierte Benutzer: 0, Gäste: 1)
 
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus


Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
Gruppierte Rechteverwaltung mittels PHP und MySQL Chr!s PHP-Programmierung 18 18.10.2006 14:06


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:02 Uhr.


Powered by vBulletin® Version 3.8.4 (Deutsch)
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47