T. M.: Problem beim Entwurf einer Datenbankstruktur

Hallo Leute,

bin gerade dabei eine Datenbankstruktur(MSSQL-DB) für ein Intranet-Mailprogramm mit ASP.net (Verwaltung von Verteilerlisten, Massenmailversand) zu entwerfen.

Ein Mitarbeiter kann bestimmte Verteiler/Newslisten abonnieren.

Die Listen werden nach bestimmten Gruppen gegliedert, d.h. es gibt pro Gruppe einen "GRUPPENADMINISTRATOR" Dieser kann neue Listen erstellen und für seine Gruppe "DELEGIERTE" bestimmen die seine Funktion übernehmen können. (z.B. bei Abwesenheit).

Zudem gibt es noch den "ADMINISTRATOR", welcher als darf und kann, egal welche Gruppe. (Er darf also auch neue Gruppen eröffnen)

Da jeder Mitarbeiter anhand seiner Personalnummer eindeutig identifiziert werden kann, benutze ich diese gerade als Primärschlüssel(id_users) der Benutzer-Tabelle. Kompliziert ist vorallem, dass ein Benutzer als Administrator oder eben, ein Administrator auch als normaler Benutzer auftreten kann. Ein Administrator muss also auch Listen abonnieren können.

tbl_users     tbl_groups        tbl_lists
---------     ----------        ----------
id_users--+   id_groups  ---+   id_lists   ----+
password  |   name          +-- id_groups      |
..        |   description       name           |
.         |                     description    |
          |                                    |
          |                                    |
          |                                    |
          |   tbl_users_lists                  |
          |   ---------                        |
          +-- id_users                         |
              id_lists ------------------------+

1. Frage:
Wie integriere ich nun am besten die "GRUPPENADMINISTRATOREN", die "DELEGIERTEN" und die "ADMINISTRATOREN"?

Als 1. Lösung bin ich auf folgende Idee gekommen:

Ich habe mir vorgestellt, folgende zusätzlichen Tabellen zu erstellen um die GRUPPENADMINISTRATOREN", die "DELEGIERTEN" und die "ADMINISTRATOREN" zu integrieren:

tbl_groupadmins    tbl_groups_groupadmins
---------------    ----------------------
id_users           id_groups
....               id_users
..

tbl_delegated      tbl_groups_delegated
-------------      ----------------------
id_users           id_groups
....               id_users
..

tbl_admins         tbl_groups_admins
----------         ----------------------
id_users           id_groups
....               id_users
..

Doch das Problem hier ist die Benennung: Es ist verwirrend dass die Tabelle z.B. tbl_groups_admins heisst und nachher aus id_groups und id_users zusammengesetzt ist..? Wie macht man sowas?

Als 2. Lösung bin ich auf die folgende Idee gekommen um das Problem mit der Benennung zu umgehen:

tbl_groupadmins    tbl_users_groupadmins     tbl_groups_groupadmins
---------------    ----------------------    ----------------------
id_groupadmins     id_users                  id_groups
                   id_groupadmins            id_groupadmins

tbl_delegated      tbl_users_delegated       tbl_groups_delegates
-------------      -------------------       --------------------
id_delegated       id_users                  id_groups
                   id_delegated              id_delegates

tbl_admins         tbl_users_admins          tbl_groups_admins
----------         ----------------          -----------------
id_admins          id_users                  id_groups
                   id_admins                 id_admins

Was mir hier nicht sinnvoll erscheint ist ersichtlich wenn man sich die Werte darin vorstellt.

tbl_admins         tbl_users_admins          tbl_groups_admins
----------         ----------------          -----------------
P1111              P1111                     92
                   P1111                     P1111

Wie würdet ihr das machen?

Also, für eure Vorschläge und Tipps bin ich euch sehr dankbar!

Gruss T.M.

  1. Hallo,

    da sich gerade niemand berufen fühlt: ich würde wohl Deinen ersten Ansatz verfolgen. Die Benamsung mag auf den ersten Blick verwirrend erscheinen, ist aber doch sinnvoll... zumindest glaube ich, daß Du dadurch die Zielsetzung abgebildet hast.

    Außerdem wird das Ganze doch wohl einen "Überbau" durch die Funtkionen erhalten, über die Du auf die Tabellen zugreifst.

    Was auf den ersten Blick vielleicht verwirrend wirkt, löst sich dann doch meist durch ein konsequentes Interface auf.

    *schwafel* :)

    So long,
    S.H.

    1. Hallo,

      Danke für dein Feedback. Du meinst also ich sollte eher Lösung 1 verwenden...? Sehen das die anderen auch so?

      T.M.

  2. Hi,

    MEIN GOTT!

    Da jeder Mitarbeiter anhand seiner Personalnummer eindeutig identifiziert werden kann, benutze ich diese gerade als Primärschlüssel(id_users) der Benutzer-Tabelle.

    Ein weiser Ansatz.

    Kompliziert ist vorallem, dass ein Benutzer als Administrator oder eben, ein Administrator auch als normaler Benutzer auftreten kann. Ein Administrator muss also auch Listen abonnieren können.

    Ein Benutzer ist also (Administrator) oder (Benutzer). Das hoert sich gar nicht so kompliziert an. Ich vermute mal, dass ein Administrator alles darf, was ein Benutzer auch darf??

    tbl_users     tbl_groups        tbl_lists
    ---------     ----------        ----------
    id_users--+   id_groups  ---+   id_lists   ----+
    password  |   name          +-- id_groups      |
    ..        |   description       name           |
    .         |                     description    |
              |                                    |
              |                                    |
              |                                    |
              |   tbl_users_lists                  |
              |   ---------                        |
              +-- id_users                         |
                  id_lists ------------------------+

    Also zwischen Benutzer und Listen eine n:m-Beziehung. Aber die Listen zeigen auf die Gruppen???

    1. Frage:
      Wie integriere ich nun am besten die "GRUPPENADMINISTRATOREN", die "DELEGIERTEN" und die "ADMINISTRATOREN"?

    Ein Benutzer ist ggf. Mitglied einer Gruppe. Listen gehen entsprechend der Gruppenzugehoerigkeit raus. So what?

    Als 1. Lösung bin ich auf folgende Idee gekommen: [...]

    Murks, oder?

    Als 2. Lösung bin ich auf die folgende Idee gekommen um das Problem mit der Benennung zu umgehen:

    Murks, oder?

    tbl_admins         tbl_users_admins          tbl_groups_admins
    ----------         ----------------          -----------------
    P1111              P1111                     92
                       P1111                     P1111

    Moment, eine Admintabelle statt einer Nutzertabelle, die auf eine Berechtigungstabelle ("Gruppentabelle") verweist? 'tbl_groups_admins' - uaaaah!

    Also, für eure Vorschläge und Tipps bin ich euch sehr dankbar!

    Dann gehe ich mal davon aus, dass Du eine klare, kritische und etwas bissige Stellungnahme verkraften kannst?!   ;-)

    Gruss,
    Ludger

    1. Hör mal Ludger,

      wo willst Du denn hin ?

      Alles anstänkern ohne einen konkreten Hinweis, eine Idee ist dürftig...

      Dann sachma.

      Gruß,
      S.H.

      1. Hi,

        Alles anstänkern ohne einen konkreten Hinweis, eine Idee ist dürftig...

        ich habe behauptet, dass alles Murks ist.

        Dann sachma.

        Dann sach Du doch mal, warum Du nicht mit den Tabellen 'Nutzer', 'Rechte', eventuell einer Relationtabelle 'Nutzer_Rechte' und 'Listen' auskommst? Gibt's da noch andere Entitaeten?? Gibt's da irgendwelche ungeschilderte (bzw. von mir unverstandene) Probleme?

        Gruss,
        Ludger

      2. Hi,

        Alles anstänkern ohne einen konkreten Hinweis, eine Idee ist dürftig...

        Dann sachma.

        ach so, Du bist nicht einmal der Fragesteller, sondern der Berater.   ;-)

        Dann also an Dich persoenlich die Frage, was Du von der urspruenglichen Anforderungsbeschreibung verstanden hast? (Das geht ja aus Deinem Berastungsbeitrag nicht direkt hervor, oder? ;-)

        Gruss,
        Ludger

    2. Hallo,

      Da jeder Mitarbeiter anhand seiner Personalnummer eindeutig identifiziert werden kann, benutze ich diese gerade als Primärschlüssel(id_users) der Benutzer-Tabelle.

      Ein weiser Ansatz.

      Dachte ich mir auch...

      Also zwischen Benutzer und Listen eine n:m-Beziehung. Aber die Listen zeigen auf die Gruppen???

      Also, nochmals zur Klärung: Die Gruppen sind nur dazu da um die Listen irgendwie unterteilen zu können. (z.B. soll jeder Geschäftszweig eine eigene Gruppe sein und seine eigenen Listen verwalten können). Die Gruppe hat also nichts mit Rechten zu tun. Möchte ein Benutzer über gewisse Dinge innerhalb des Geschäftszweiges informiert werden trägt er sich nur für eine oder mehrere Listen ein und _nicht_ für eine gesamte Gruppe.
      Es geht jetzt nur noch darum, wie ich für die einzelnen Gruppen festlegen kann wer deren ADMINISTRATOR ist oder dessen DELEGIERTE sind. Und dafür bin ich auf Lösungsvorschläge gespannt...

      1. Frage:
        Wie integriere ich nun am besten die "GRUPPENADMINISTRATOREN", die "DELEGIERTEN" und die "ADMINISTRATOREN"?

      Ein Benutzer ist ggf. Mitglied einer Gruppe. Listen gehen entsprechend der Gruppenzugehoerigkeit raus. So what?

      Als 1. Lösung bin ich auf folgende Idee gekommen: [...]

      Murks, oder?

      Als 2. Lösung bin ich auf die folgende Idee gekommen um das Problem mit der Benennung zu umgehen:

      Murks, oder?

      tbl_admins         tbl_users_admins          tbl_groups_admins
      ----------         ----------------          -----------------
      P1111              P1111                     92
                         P1111                     P1111

      Moment, eine Admintabelle statt einer Nutzertabelle, die auf eine Berechtigungstabelle ("Gruppentabelle") verweist? 'tbl_groups_admins' - uaaaah!

      Wie gesagt, die Gruppen werden zur Kategorisierung der Listen benutzt und haben _nichts_ mit Berechtigungen zu tun. Beispiel:

      "Verkauf" (Gruppe)
        +--"Verkauf von Telefonen" (Liste)
        +--"Verkauf von PC's" (Liste)

      Letztendlich müssen für eine Gruppe folgende Daten gespeichert werden können:

      "Verkauf" (Gruppe) (Gruppenadministrator: P1111, Delegierte: P1112, P1113)
        +--"Verkauf von Telefonen" (Liste)
        +--"Verkauf von PC's" (Liste)

      Also, für eure Vorschläge und Tipps bin ich euch sehr dankbar!

      Dann gehe ich mal davon aus, dass Du eine klare, kritische und etwas bissige Stellungnahme verkraften kannst?!   ;-)

      Klar, ein besserer Lösungsvorschlaf würde mir aber trotzdem weiterhelfen...?

      Gruss,
      Ludger

      Gruss T. M.

      1. Hi!

        Da jeder Mitarbeiter anhand seiner Personalnummer eindeutig identifiziert werden kann, benutze ich diese gerade als Primärschlüssel(id_users) der Benutzer-Tabelle.

        Ein weiser Ansatz.

        Dachte ich mir auch...

        (Noch weiser waere es m.E. aber einen bedeutungsfreien Primaerschluessel vom Typ uniqueidentifier zu nutzen.)

        Also, nochmals zur Klärung: Die Gruppen sind nur dazu da um die Listen irgendwie unterteilen zu können. (z.B. soll jeder Geschäftszweig eine eigene Gruppe sein und seine eigenen Listen verwalten können). Die Gruppe hat also nichts mit Rechten zu tun.

        Ja, das habe ich zuletzt nicht verstanden. Darum also die "n:m"-Beziehungen zwischen Liste und Gruppe.

        Möchte ein Benutzer über gewisse Dinge innerhalb des Geschäftszweiges informiert werden trägt er sich nur für eine oder mehrere Listen ein und _nicht_ für eine gesamte Gruppe.

        Der Nutzer traegt sich _nie_ in eine Gruppe ein, die beispielsweise eine bestimmte Liste (BTW - was bedeutet Liste hier genau?) abonniert. Stattdessen traegt er sich fuer eine Liste ein?

        Es geht jetzt nur noch darum, wie ich für die einzelnen Gruppen festlegen kann wer deren ADMINISTRATOR ist oder dessen DELEGIERTE sind. Und dafür bin ich auf Lösungsvorschläge gespannt...

        Also ich frage mich immer noch, warum Du nicht mit den Tabellen "Nutzer", "Berechtigungen", ggf. einer Relationentabelle "Nutzer-Berechtigungen", "Listen" und ggf. einer Relationentabelle "Brechtigungen-Listen" auskommst. Du koenntest in letztere Tabelle doch eine "IsAdmin"-Kennung einbauen?

        Wie gesagt, die Gruppen werden zur Kategorisierung der Listen benutzt und haben _nichts_ mit Berechtigungen zu tun. Beispiel:

        "Verkauf" (Gruppe)
          +--"Verkauf von Telefonen" (Liste)
          +--"Verkauf von PC's" (Liste)

        Moment, das riecht nach einer Tabelle "Listenkategorien", die mit der Tabelle "Listen" in einer "1:n"-Beziehung steht, oder?

        Klar, ein besserer Lösungsvorschlaf würde mir aber trotzdem weiterhelfen...?

        Was denkst Du wie so ein Loesungsansatz aussieht? Wir muessen hier die Gegebenheiten der Realitaet erlaeutern, um dann diese in einem relationalen Datenbankmodell (RDBMS: 'M$ SQL Server' - programmiere ich uebrigens seit der Version 6.5) nachzubilden. Es handelt sich also weniger um einen Loesungsnansatz, der hier zu eroerten ist und den es zu finden gilt, als mehr um ein Gesamtverstehen, dessen was Du nachbilden willst (und dessen, was Du nachbilden musst, aber das waere schon ein anderes Thema ;-).

        Gruss,
        Ludger

  3. yo,

    wenn ich dich richtig verstanden habe, dann hast du erst einmal drei entitäten:

    • user: id_user, name,...
    • groups: id_groups, name, description
    • lists: id_lists, name, description,...

    daraus ergeben folgende beziehungstabellen:

    jeder user kann einer oder mehrerer(falls nur eine gruppe möglich entsprechend ändern 1:n) gruppen angehören, jede gruppe kann einen oder mehrere user haben. ein group kann einen oder mehrere delegierte besitzen. jeder user kann mehrere groups als vertretung administrieren. delegiert ist ein flag (0/1), ob er delegierterder group ist.

    • user_groups: id_user, id_groups, delegiert -> n:m beziehung

    ein user kann eine oder mehrere groups verwalten. eine group hat genau einen admin.

    • fremdschlüssel in der tabelle groups der auf die users referenziert -> 1:n beziehung

    jede group kann eine oder mehrere listen abnonnieren, jede liste wird genau einer group zugeordnet (hier wäre eventuell zu überlegen, ob es nicht wünschwenswert ist, ob eine liste auch mehreren groups zugeordnet werden kann):

    • fremdschlüssel in der tabelle lists der auf die group referenziert -> 1:n beziehung

    was die rechte angeht des "super-admin" betrifft, so solltest du bei user eine spalte dazunehmen, die einen user als solchen kennzeichnet. will jemand etwas an einer group ändern, zum beispiel eine neue list dazu nehmen oder löschen, sind skripte entsprechend so zu programmieren, dass auf drei dinge geprüft wird. ist er:

    1. super-admin
    2. group admin
    3. delegierter der group

    ausserdem ist zu überlegen, ob eine group ebenfalls verschwinden soll und somit alle lists der group, wenn ein group administrator aus der user tabelle gelöscht wird.

    ps: ich finde den namen der tabelle "doppelt gemoppelt". es gibt zwar sicherlich auch andere datenbankobjekte, aber um ehrlich zu sein, ich bin bis jetzt noch nicht auf das problem gestossen, eine tabelle nicht als soche zu erkennen. das ist ein wenig so, als wenn ich zwei hunde habe und den einen hund_lessie nenne und den anderen hund_hektor. aber das ist geschmackssache und kann man halten wie ein dachdecker.

    Ilja

    1. Hallo Ilja,

      hab dein Vorschlag mal umgesetzt:
      http://a11111.dyndns.org/diagram.jpg

      Hast du das so gemeint? Scheint mir eine einfache und gute Lösung zu sein! Schwierig dürfte es aber dann werden wenn z.B. alle Delegierten zusätzliche Felder erhalten müssen....?

      Gruss

      1. yo

        Hast du das so gemeint? Scheint mir eine einfache und gute Lösung zu sein! Schwierig dürfte es aber dann werden wenn z.B. alle Delegierten zusätzliche Felder erhalten müssen....?

        nicht ganz. ich bin davon ausgegangen, dass jeder user sich einer group zuordnen muss, wenn er eine list haben will. insofern gbt es bei meinen alten ansatz auch keine verbindung zwischen list und user.

        inzwischen habe ich weiter unten gesehen, dass der jeweilige user auch ohne einer group anzugehören, eine list bekommen kann. dem hast du das datenmodell schon angepasst. das sieht schon alles sehr gut aus, bin es aber nur überflogen. habe heute geburtstag und gleich kommen die ersten gäste. habe immer noch einen in der krone vom reinfeiern. eine ist mir aufgefallen. es fehlen die zusammengestzten pk in den beziehungstabellen.

        zum glück ist die feier nur ein kleines sit in, sollte also nicht all zu lange dauern. werde es mir dann noch mal genauer anschauen. warum sollte alle delegierten ein zusätzliches feld benötigen ?

        Ilja

        1. Hallo,

          als erstes einmal "GRATULATION ZUM GEBURTSTAG":-)

          inzwischen habe ich weiter unten gesehen, dass der jeweilige user auch ohne einer group anzugehören, eine list bekommen kann. dem hast du das datenmodell schon angepasst. das sieht schon alles sehr gut aus, bin es aber nur überflogen. habe heute geburtstag und gleich kommen die ersten gäste. habe immer noch einen in der krone vom reinfeiern. eine ist mir aufgefallen. es fehlen die zusammengestzten pk in den beziehungstabellen.

          Die Zusammengesetzten PK's? Dazu gerade eine Frage: Warum müssen die auch notiert werden? Sind diese nicht ersichtlich? Was bedeuten sie? Ich habe sie eben extra entfernt. Erstellen muss ich diese aber nicht in der DB, oder?

          Habe aber noch ein Update mit zusammengesetzten PK's ins Netz gestellt (Enthält noch weitere Tabellen, die müssen dich aber nicht stören...) http://a11111.dyndns.org/diagram1.jpg

          zum glück ist die feier nur ein kleines sit in, sollte also nicht all zu lange dauern. werde es mir dann noch mal genauer anschauen. warum sollte alle delegierten ein zusätzliches feld benötigen ?

          Könnte ja sein...Vielleicht stellt sich später heraus dass ein Delegierter z.B. noch bestimmte Ansichtseinstellungen speichern kann, was ein normaler User nicht kann.

          Gruss M.T.

          1. yo,

            bin wieder da, war eine kurze und schmerzlose runde. und danke für deine gratulation.

            Die Zusammengesetzten PK's? Dazu gerade eine Frage: Warum müssen die auch notiert werden? Sind diese nicht ersichtlich? Was bedeuten sie? Ich habe sie eben extra entfernt. Erstellen muss ich diese aber nicht in der DB, oder?

            pk vereinen zwei eigenschaften in sich, erstens die felder dürfen nicht null (leer) sein und zweitens sie müssen eindeutig sein. und diese beiden constraints solltest du in deinem datenbank-modell auch implementieren. null werte machen zum einen gar keinen sinn und zweitens soll ein und derselbe user ja nicht zweimal in einer group vorkommen können. zum anderen werden durch das dbms automatisch für jeden pk ein index erstellt, der hier ebenfalls sehr sinnvoll ist.

            Könnte ja sein...Vielleicht stellt sich später heraus dass ein Delegierter z.B. noch bestimmte Ansichtseinstellungen speichern kann, was ein normaler User nicht kann.

            dazu brauchst du kein weiteres feld in der datenbank, dass läßt sich alles über das programm steuern, da ja mit dem flag in der beziehungstabelle klar wird, ob jemnd delegierter ist oder nicht.

            Ilja