Konzept um Baumstruktur mit Vererbung anhängender Daten abzubilden



  • N'abend & frohes neues zusammen!

    Ich hätte da mal ein Problem im Angebot (wie so viele andere auch 🙂 ), wo ich mir Eure Hilfe erhoffe:

    • Was ich erreichen möchte:
      Ich möchte gerne Schlüssel-Wert-Paare in einer Datenbank abbilden. Diese sollen dann wiederum verschiedenen Nodes in einer Baumstruktur zugeordnet werden, und dann wiederum für alle nachfolgenden Nodes in der Baumstrutur gültig sein.

    Als zusätzliche kleine Schwierigkeit kommt noch hinzu, daß jedes dieser Schlüssel-Wert-Tupel über einen weiteren Wert verfügt, der regelt, ob ein anderes Tupel aus einer niederen Ebene im Baum dieses überschreiben darf.

    • Wie ich am Ende darauf zugreifen möchte:
      Wenn die Datenstruktur steht, dann möchte ich in Abhängigkeit einer Node-ID und des jeweiligen Schlüssels auf den Wert des aktuell gültigen Tupels zugreifen können. Außerdem benötige ich dann noch die Information, bei welcher Node-ID der jeweilige Wert für den Schlüssel gesetzt wurde, und wie das oben angesprochene Überschreibe-Flag gesetzt ist.
    • Das ganze nochmal nicht ganz so abstrakt:
      Ich möchte gerne eine Konfiguration für ein Benutzergruppensystem in einer relationalen Datenbank abbilden. Eine Gruppe kann dabei n verschiedene Untergruppen haben, welche dann wiederum wieder m eigene Unter-Untergruppen haben können. Ein Benutzer kann allerdings immer nur Mitglied in einer Gruppe sein, und momentan halte ich es für am schlausten, wenn er als Untergruppe für die ihm zugeordnete Gruppe betrachtet wird. Für jeden Benutzer soll sich so quasi ein eigener Namensraum ergeben mit beliebigen Variablen, welcher durch die Schlüssel-Wert-Tupel aus den Gruppen zustande kommt.

    Für den Benutzer sollen dabei die folgenden Aktionen im System abgebildet werden:

    1. Alle Variablen einsehen.
    2. Alle die Variablen überschreiben, die nicht in einer der übergeordneten Gruppen als nicht überschreibbar markiert wurden. Dies soll über ein neues Schlüssel-Wert-Paar in der Gruppe des Mitglieds realisiert werden.
    3. Eigene Variablen anlegen.
    • Die technische Basis:
      Ihr werdet mich erschlagen, aber die technische Basis für das ganze ist bisher MySQL in einer 4er Version (evtl. kommt später noch Postgres dazu, der DB-Layer ließe das jedenfalls zu, entschieden ist das aber noch nicht). Letztendlich bedeutet das also, daß Constraints und Trigger zur Absicherung der referentiellen Integrität der ganzen Kiste weitgehend flach fallen. (Okay - letztere würde man auch nur wirklich für das löschen von Benutzern brauchen...)
    • Was bisher schon steht:
      7 Tabellen:
    1) KeyValueMap:
       id     Serial / Autoincrement Integer  -   eindeutiger numerischer Wert
       label  Char(50)                        -   Der Schlüssel
       nid    Integer                         -   FK für die zugehörige Node
       vType  SET('NUMERIC','BLOB','STRING')  -   Inhaltstyp, legt fest in welcher 
                                                  Tabelle der Inhalt steht.
       vid    Integer                         -   FK für die Inhaltstabellen
    
    2,3,4) NumValues/BlobValues/CharValues
       Nur die "vid" als PK und jeweils "value" vom passenden Typ
    
    5) GroupStructure
       NodeID Serial/Autoincrement Integer    -   PK, eindeutig & numerisch
       lft    Integer                         -   linke Schranke
       rgt    Integer                         -   rechte Schranke
       isGrp  Bool                            -   Typisierung ob Gruppe oder 
                                                  Mitglied
    
    6) Groups
       id     Serial/Autoincrement Integer    -   PK, eideutig & numerisch
       label  Char(30)                        -   Gruppenbezeichner
       info   Text                            -   Ausführlichere Beschreibung der 
                                                  Funktion
       nid    Integer                         -   FK zur Node
    
    7) User
       id     Serial/Autoincrement Integer    -   PK, eideutig & numerisch
       name   Char(50)                        -   Benutzername
       pwd    Char(40)                        -   Passwort-Hash in Sha1
       email, etc ...
       nid    Integer                         -   FK zur Node
    
    • Was ich hinbekomme:

    Ich kann Gruppen anlegen, verschieben und löschen. Ich kann Benutzer anlegen (inkl. der jeweils dazugehörigen Gruppe). Ich bekomme es auch hin, mir die gesammte Gruppen-/Nutzer-Struktur anzeigen zu lassen.

    • Und wo hakt es nun?
      Prinzipiell hänge ich mich an zwei Punkten auf:
    1. Ich bekomme es einfach nicht hin, beim Anlegen eines neuen Schlüssel-Wert-Paares zu überprüfen, ob dieses denn überhaupt erlaubt ist, sprich ob nicht in einer der übergeordneten Gruppen ein passendes Tupel existiert, welches als "nicht überschreibbar" markiert wurde.

    2. Ich schaffe es auch nicht, mir die Informationen auszulesen, die ich hier als zweiten Punkt aufgeführt habe. Ich schaffe es einfach nicht, in Abängigkeit vom aktuellen Nutzer auf die Werte seines Namespaces zuzugreifen. Ich finde einfach keine inteligente Lösung für das Vererbungs-/Überschreibungs-Problem.

    Ich hoffe mal, irgendwer von Euch kann mir einfach mal die Algorithmen für die genannten Probleme visualisieren. Ich wage nämlich mal zu befürchten, daß ich mir hier einfach schon zu lange das Hirn verknotet habe, und einfach den Wald vor lauter Bäumen nicht mehr sehe... Ich glaub da muss mal ein fremdes Auge ran.

    Ich danke auf jeden fall schonmal allen, die sich das ganze bis hier her durchgelesen haben, und hoffe auf Eure Eingebungen.

    Gruß Jens



  • Hallo,

    ich kann dir jetzt leider nicht ganz folgen, aber mir ist zumindest klar, dass du eine Hierarchie aufbauen möchtest.
    Hast du schon mal an eine objektorientierte Datenbank gedacht?

    Schau dir mal folgenden Beitrag (aus dem Python Forum) an:
    http://python.sandtner.org/viewtopic.php?t=2412

    Oder hier (Datenbanken II Skript)
    http://www.fh-rosenheim.de/~petkovic/ie/scripts.html

    MfG



  • Hi EdiRitter,

    erstmal danke für Deine Antwort. Ich bin mir jedoch nicht sicher, in wie weit, mir diese hilft. Soweit ich das Konzept der OODBMS kenne lassen es diese doch nur zu, Eigenschaften, also Strukturinformationen zu vererben. Zum Erstellungszeitpunkt der Datenstruktur ist mir jedoch absolut unbekannt, welche Struktur am Ende in der Hierarchie abgelegt werden soll.

    Leider kommt noch dazu, daß ich in der Wahl meiner technischen Mittel momentan etwas beschränkt bin. Ich kann also nicht einfach so von den Vorgaben abweichen und Caché & Co aus dem Hut zaubern.

    Ich versuch nochmal anhand eines Beispiels zu erklären, welche Informationen ich verarbeiten können will.

    Nehmen wir an, es liegt die folgende Gruppenstruktur vor:

    System
               /\
              /  \
       Funktion1 Funktion2
         /           /\
        /           /  \
    Person1      Pers2 Pers3
    

    Auf der obersten Ebene möchte ich jetzt zum beispiel ein Flag definieren,
    welches eine Beschränkung für irendeine Aktion beinhaltet. Weiterhin möchte ich sicherstellen, daß diese Beschränkung Systemweit gilt.

    Ich setze also

    Node='System'
      Überschreibbar=0
      Schlüssel='isAllowedToTakeActionX'
      Wert=0
    

    Außerdem möchte ich auf der obersten Ebene noch Default-Werte setzen können, welche aber möglich sind zu verändern.

    Ich setze also z.B.

    Node='System'
      Überschreibbar=1
      Schlüssel='GUIBgColor'
      Wert='rgb(255,255,255)'
    

    Jetzt endscheide ich mich aber auch noch dafür, daß alle Personen, die den Arbeitsplatz "Funktion1" bedienen, doch lieber mit einem etwas dunkleren Hintergrund arbeiten sollten. Auf Ebene "Funktion1" lege ich also folgenden Eintrag an:

    Node='Funktion1'
      Überschreibbar=1
      Schlüssel='GUIBgColor'
      Wert='rgb(225,225,225)'
    

    Nun könnte es ja Bestandteil des Clients für alle Arbeitnehmer sein, daß sie eine eigene ToDo-Liste verwalten können.

    Der besagte Client könnte also für Pers3 folgenden Eintrag anlegen wollen:

    Node='Pers3'
      Überschreibbar=1
      Schlüssel='MyToDoList'
      Wert='Die ist irgendein Text mit ToDo-Liste'
    

    So, und das ganze soll am Ende dann genutzt werden. Wenn sich ein Client am System authentifiziert, so ist immer der Name der jeweiligen Node des Benutzers relevant. Je nach Benutzer würde ich jetzt gerne folgende Ergebnisse extrahieren:

    Pers1:
      isAllowedToTakeActionX(Value:0,DefinedIn:System,Changeable=0)
      GUIBgColor(Value: rgb(225,225,225),DefinedIn:Funktion1:Changeable=1)
    Pers2:
      isAllowedToTakeActionX(Value:0,DefinedIn:System,Changeable=0)
      GUIBgColor(Value: rgb(255,255,255),DefinedIn:System:Changeable=1)
    Pers3:
      isAllowedToTakeActionX(Value:0,DefinedIn:System,Changeable=0)
      GUIBgColor(Value: rgb(255,255,255),DefinedIn:System:Changeable=1)
      MyToDoList(Value: 'Die ist irgendein Text mit ToDo-Liste',DefinedIn:Pers3:Changeable=1)
    

    So und ich suche jetzt quasi eine Möglichkeit, daß ganze schon in der Datenbank zu erledigen, um nicht in der Endapplikation aufwendig & für jeden Schlüssel die komplette Baumstrukrur zu durchlaufen, um die Vererbung der Einzelwerte aufzulösen.

    Es ist nur halt etwas unpraktisch, daß ich ganz allgemein von Schlüssel-Wert-Paaren, also von beliebigen Konfigurationsschaltern ausgehen muss, da aufgrund der Modulariesierung der einzelnen Systemkomponenten nicht vorhersehbar ist, was da an Schlüsseln und Unterebenen anfallen kann. Es könnte im Extremfall passieren, daß die komplette Organisationsstruktur eines Unternehmens in diesem System abgebildet wird, und daß sich die jeweiligen zu ladenden Module - und damit dann halt auch die unterstützten Parameter - erst durch Flags in eine jeweils übergeordneten Ebene ergeben.

    Ich hoffe, es ist nun etwas klarer geworden, worauf ich abziele?

    Gruß Jens



  • Hallo,

    jetzt habe ich verstanden was du vorhast.

    Ich finde einfach keine intelligente Lösung für das Vererbungs-/Überschreibungs-Problem.

    Ich auch nicht 😞 Das größte Problem ist, dass sich die Knoten ändern und die Vererbung somit pfutsch ist ..

    Ich befürchte mit dieser Lösung wirst du nicht glücklich.

    Meine Idee, aber keine Garantie:
    - Die Person von der Funktion trennen. ⚠ Eine Person von einer Funktion erben, ist ein bißchen merkwürdig.
    - Der Person die richtige Funktion übergeben. Man kann mit einer Funktions-Id evtl. rauslesen, welche Funktion die Person gerade benutzt.

    Ich werde dir leider keine große Hilfe sein, mir fehlt etwas die Erfahrung, aber vielleicht haben auch andere Forumsuser ein paar neue Ideen..

    MfG


Anmelden zum Antworten