Ankündigung

Einklappen
Keine Ankündigung bisher.

Datenbankdesign

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Datenbankdesign

    Liebe Mitglieder,

    in diesem Fall fehlt mir aufgrund der wenigen Erfahrung auf diesem Gebiet ein sinnvoller Ansatz, ein Best-Practice-Beispiel oder ggf. auch nur ein Schlagwort um mich weiter einzulesen.
    Es geht darum, eine für mich komplexe Datenbankstruktur zu erstellen, die es möglich macht Daten "definierten Zeiträumen" zuzuordnen, gleichzeitig wenig Redundanz aufkommen lässt und die Performance dabei natürlich nicht vergisst.

    Am einfachsten ist vermutlich ein kleines Beispiel:
    Man stelle sich eine Benutzergruppe mit ca. 2000 Mitgliedern vor, die jeweils für einen fest definierten Zeitraum mehreren Projekten zugeordnet werden sollen. Für jeden Zeitraum kommen ca. 200 Mitglieder dazu, damit man eine Einschätzung über das Datenvolumen bekommt. Klassischerweise hatte ich die Idee, die Mitglieder, die Projekte und auch die "fest definierten" Zeiträume in einer Datenbanktabelle zu erfassen. Mein Problem ist nun, dass die Relation Zeitraum, Projekt, Mitglied nur eine von vielen in dieser Art ist und es neben diesen Verknüpfungen auch noch weitere Beziehungen gibt. Man denke an Projektleiter, Ressourcen wie Räume, ... die natürlich jeweils mit den Projekten bzw. Mitgliedern in Abhängigkeit des Zeitraums verknüpfbar sein müssen.

    So dachte ich an eine Tabelle (nennen wir sie "period"), die die Zeiträume beschreibt (ich vereinfache ein wenig)
    Code:
    id|name
    1|Zeitraum 1
    Natürlich an Mitglieder
    Code:
    id|name
    1|Björn Beispiel
    und an die Projekte
    Code:
    id|name|period_id
    1|Projekt A|1
    2|Projekt B|1
    Und an die n:m Verknüpfung der Projekte und der Mitglieder
    Code:
    user_id|project_id|period_id
    1|1|1
    1|2|1
    An irgendeiner Stelle muss ja nun die Relation zum Zeitraum untergebracht werden. Wird diese in der Verknüpfungstabelle aufgenommen oder wird das Projekt einem Zeitraum zugeordnet oder beides? Ich würde diese nur an die Projektetabelle angliedern.
    Wie sieht das in der Praxis mit der Performance aus? Ich erhalte mit den Testdaten und ersten Versuchen aufgrund der angedeuteten weiteren Beziehungen, die sich auch am jeweiligen Zeitraum orientieren, unglaublich lange Ladezeiten, da sich in den SQL Abfragen durchaus bis zu 6 Joins finden und erhalte damit Ladezeiten jenseits von 1 Sekunde, was wohl nicht im Sinne des Erfinders sein kann.

    Liegt das Problem grundsätzlich im Datenbankdesign?

    Ich hatte zwischenzeitlich auch schon die glorreiche Idee, für jeden neuen Zeitraum neue Tabellen zu generieren, die sozusagen "Rückschlüsse" auf den Zeitraum zulassen, so dass mit einer Konstante (oder wie auch immer umgesetzt) jeweils nur die aktuell ausgewählten Tabellen abgefragt werden, was zwar die Performance erhöht hat, aber ich damit natürlich nur noch schwer Beziehungen zwischen den Zeiträumen abbilden kann, was derzeit zwar nicht notwendig wäre, aber eine solche Umsetzung behagte mir nicht wirklich.

    Dennoch hoffe ich, dass ich mein Problem anschaulich darstellen konnte. Ich freue mich über jede Rückfrage oder Ideen, die mir weiterhilft mein Problem überhaupt strukturell zu erfassen. Für diese Art des Designs bzw. die Idee, die ich damit verfolge wird es doch bestimmt einen Namen geben. Bin bin gespannt.

    Viele Grüße
    Guido




  • #2
    Zitat von ecomeback Beitrag anzeigen
    Liebe Mitglieder,

    in diesem Fall fehlt mir aufgrund der wenigen Erfahrung auf diesem Gebiet ein sinnvoller Ansatz, ein Best-Practice-Beispiel oder ggf. auch nur ein Schlagwort um mich weiter einzulesen.
    Es geht darum, eine für mich komplexe Datenbankstruktur zu erstellen, die es möglich macht Daten "definierten Zeiträumen" zuzuordnen, gleichzeitig wenig Redundanz aufkommen lässt und die Performance dabei natürlich nicht vergisst.

    Am einfachsten ist vermutlich ein kleines Beispiel:
    Man stelle sich eine Benutzergruppe mit ca. 2000 Mitgliedern vor, die jeweils für einen fest definierten Zeitraum mehreren Projekten zugeordnet werden sollen. Für jeden Zeitraum kommen ca. 200 Mitglieder dazu, damit man eine Einschätzung über das Datenvolumen bekommt. Klassischerweise hatte ich die Idee, die Mitglieder, die Projekte und auch die "fest definierten" Zeiträume in einer Datenbanktabelle zu erfassen. Mein Problem ist nun, dass die Relation Zeitraum, Projekt, Mitglied nur eine von vielen in dieser Art ist und es neben diesen Verknüpfungen auch noch weitere Beziehungen gibt. Man denke an Projektleiter, Ressourcen wie Räume, ... die natürlich jeweils mit den Projekten bzw. Mitgliedern in Abhängigkeit des Zeitraums verknüpfbar sein müssen.

    Da sind so Stichworte wie Ressourcen und Zeiträume. Du willst möglicherweise verhindern, daß eine Ressource wie z.B. ein Zimmer in mehreren, sich überschneidenden Zeiträumen verplant werden - also doppelt. Das kann man in der DB schon mit einem guten Design verhindern - wenn man dafür gleich RANGE-Typen und Exclusion Constraints verwendet.

    Ansonsten sind Deine Anforderungen eher trivial.
    PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services

    Kommentar


    • #3
      Moin,

      ich denke du legst den Fokus zu sehr auf den Zeitraum.
      Hau das einfach mit ins Projekt.

      Wenn die Mitarbeiter-Hierarchien nicht komplexer sein sollen als 'Projektleiter' und 'Projektarbeiter' kannst du die User-ID vom Projektleiter auch einfach in die Projekttabelle aufnehmen, oder eben nen Flag in der Zuordnungstabelle zwischen User und Projekt.

      Tabelle für Projekte:
      id
      Bezeichnung etc
      Startdatum
      Enddatum
      (evtl Projektleiter)

      Tabelle für User:
      id
      Userdaten... nothing special

      Tabelle für Zuordnungen Projekt-User:
      user-ID
      projekt-ID
      (evtl flag für Projektleiter)

      Bei den restlichen Ressourcen musst du eben konkreter sagen, wo da die Schwierigkeiten auftreten. Gebäude oder Räume zuordnen ist ja auch kein großes Ding.

      Ich erhalte mit den Testdaten und ersten Versuchen aufgrund der angedeuteten weiteren Beziehungen, die sich auch am jeweiligen Zeitraum orientieren, unglaublich lange Ladezeiten, da sich in den SQL Abfragen durchaus bis zu 6 Joins finden und erhalte damit Ladezeiten jenseits von 1 Sekunde, was wohl nicht im Sinne des Erfinders sein kann.
      Vielleicht schlechte Query? Indizes gesetzt? 6 Joins stellen nicht annähernd ein Problem dar.
      Mit angedeuteten Infos kann man die Ausführungszeig nicht wirklich beurteilen. Die von dir genannte Anzahl von Datensätzen in den Tabellen ist ja auch eher unkonkret
      Man stelle sich eine Benutzergruppe mit ca. 2000 Mitgliedern vor, die jeweils für einen fest definierten Zeitraum mehreren Projekten zugeordnet werden sollen. Für jeden Zeitraum kommen ca. 200 Mitglieder dazu, damit man eine Einschätzung über das Datenvolumen bekommt.
      Sagt gar nichts aus, Hättest mal sagen müssen wie viele Zeiträume es denn gibt etc
      Relax, you're doing fine.
      RTFM | php.de Wissenssammlung | Datenbankindizes | Stay fit

      Kommentar


      • #4
        Hallo und vielen Dank für eure Antworten.

        Du willst möglicherweise verhindern, daß eine Ressource wie z.B. ein Zimmer in mehreren, sich überschneidenden Zeiträumen verplant werden - also doppelt.
        Grundsätzlich eine gute Idee, aber das ist nicht im Kern das, was ich erreichen möchte, bzw. trifft im Kern nicht mein Problem.

        Je mehr ich darüber nachdenke und angelehnt an den Vorschlag von VPh den Zeitraum einfach an die Projekte zu binden, was so sogar ausgelagert in eine andere Tabelle mit einem Flag auch noch kein Problem wäre, habe ich mit folgender Anforderung die größten Schwierigkeiten. Mal angenommen die Projekte bekommen ein Start- und Enddatum und es gibt eine n:m Zuordnung zwischen Usern und den Projekten mal unabhängig von irgendwelchen Gruppen oder Hierachien. Wie verknüpfe ich sinnvoll mit den Usern eine Tabelle, die beispielweise Daten in Abhängigkeit des Zeitraumes aber im Prinzip unabhängig vom Projekt speichern sollen.

        Wir legen die Tabellen für die User, Projekte und die Zuordnungstabelle aus dem Thread #3 zur Grunde und nennen eine weitere Tabelle reports, die Rückmeldungen zu einem Benutzer beinhalten sollen.
        Code:
        Tabelle reports
        id|name|....|user_id
        Vielleicht stehe ich auch gerade ganz neben mir, aber was ist hierbei der sinnvollste Weg den Zeitraum unterzubringen und/oder wie sieht das in der Umsetzung bzw. auf der Basis einer SQL Abfrage aus?
        Code:
        SELECT r.*, u.*
        FROM reports AS r
        LEFT JOIN users AS u ON u.id = r.user_id
        LEFT JOIN user_project_map AS upm ON upm.user_id = upm.project_id
        LEFT JOIN project AS p ON p.id = upm.project_id
        WHERE p.period_id = 1   // von eben innenhalb eines Zeitraumes
        Vielleicht schlechte Query? Indizes gesetzt? 6 Joins stellen nicht annähernd ein Problem dar.
        Mit angedeuteten Infos kann man die Ausführungszeig nicht wirklich beurteilen. Die von dir genannte Anzahl von Datensätzen in den Tabellen ist ja auch eher unkonkret
        Mir ist bewusst, dass ich mir das im Detail noch einmal ansehen muss. Da ich aber die Struktur noch einmal überdenken und überarbeiten möchte, muss ich einige Dinge natürlich anders etwas angehen und kann erst nach dem Datenbankdesign Genaueres zur letztendlichen Umsetzung und den Ladezeiten sagen. Ich bin nur furchbar überrascht, dass das bei meinen Tests im Durchschnitt 1,2 Sekunden waren.

        Sagt gar nichts aus, Hättest mal sagen müssen wie viele Zeiträume es denn gibt etc
        Verstehe. Vielleicht habe ich das etwas zu kryptisch ausgedrückt. Praktisch ab dem Start sind die Benutzerzahlen mit jedem neuem Zeitraum linear wachsend. Nach 10 Zeiträumen also 4000 User.... In jedem Zeitraum gibt es ca. 40 Projekte.. Um so erstaunlicher sind die Ausführungszeiten.

        Viele Grüße
        Guido

        Kommentar


        • #5
          Zitat von ecomeback Beitrag anzeigen
          Vielleicht stehe ich auch gerade ganz neben mir, aber was ist hierbei der sinnvollste Weg den Zeitraum unterzubringen und/oder wie sieht das in der Umsetzung bzw. auf der Basis einer SQL Abfrage aus?
          Code:
          SELECT r.*, u.*
          FROM reports AS r
          LEFT JOIN users AS u ON u.id = r.user_id
          LEFT JOIN user_project_map AS upm ON upm.user_id = upm.project_id
          LEFT JOIN project AS p ON p.id = upm.project_id
          WHERE p.period_id = 1 // von eben innenhalb eines Zeitraumes
          Wahrscheinlich richtig gedacht, aber da fehlt glaub ich ein join zwischen user (u) und user_project_map (upm) oder es wird der falsche Alias benutzt.

          Insgesamt klingen Deine Zweifel zu verwirrt, für das, was bis jetzt an Anforderungen da ist. Wie hast Du die Anforderungen gesammt?
          Hast Du das mal aufgestellt, Operationen und Darstellungsbedarf ermittelt?
          Ich würde auch nicht in dieser Phase mit vermeintlichen Optimierungen beginnen, sondern tatsächlich entsprechend des Bedarfs logisch aufbauen. Ein fertiges System mit funktionierenden Queries, Operationen und Reports kannst Du später bei Bedarf "aufweichen"/performanceoptimieren. Besonders dann nicht, wenn es nur um ein paar tausend Datensätze geht. Hilfreich sind dabei Views für die Darstellungsschicht. Wenn sich hinter den Views etwas im Modell ändert, ist das nicht so dramatisch.

          Kommentar


          • #6
            Ich weiß nicht, ob ich es richtig verstanden habe, aber warum machst du nicht einfach eine Zuordnungstabelle, in der du das Zuordnungsdatum speicherst... etwa so:
            Code:
            user_to_project
            ----------------------
            user_id
            project_id
            assigned_from
            assigned_till
            Dann kannst du völlig unabhängig von der Projektlaufzeit festlegen, wie lange ein Benutzer zugeordnet sein soll. Ich finde auch nicht, dass die Zeit der Zuordnung etwas mit der Projektlaufzeit zu tun hat, abgesehen davon, dass start und ende der Zuordnung nicht außerhalb der Projektlaufzeit liegen dürfen. Aber das würde ich dann im Programm überprüfen.
            Fynder - http://www.fynder.de - Tutorials zum Thema Technik

            Kommentar


            • #7
              Hallo und herzlichen Dank für eure Antworten,

              Wahrscheinlich richtig gedacht, aber da fehlt glaub ich ein join zwischen user (u) und user_project_map (upm) oder es wird der falsche Alias benutzt.
              richtig, da hat sich ein Fehler eingeschlichen.

              Wie hast Du die Anforderungen gesammt?
              An den akuellen Abläufen, die jetzt ohne Software ablaufen orientiert mit dem Bick, was lässt sich optimieren und welche Übertragung möglich ist.

              Hast Du das mal aufgestellt, Operationen und Darstellungsbedarf ermittelt?
              Ja, die gibt es, vielleicht nicht in aller Ausführlichkeit, aber es gibt neben einem teil UML Modell auch bereits einen Prototypen, der zumindest die Views und die beispielweise die notwendigen Filter etc. vollständig enthält.

              [...] warum machst du nicht einfach eine Zuordnungstabelle, in der du das Zuordnungsdatum speicherst
              Richtig, das hatte ich ja bereits auch schon im Post #1 angedeutet, dass ich das für eine weitere Lösung halten würde und mir zum einen nicht sicher bin, welches von beiden der sinnvollste Weg ist.

              Wenn es nur diese Abhängigkeit gäbe, dann machte ich mir auch nicht so viele Gedanken. Meine Schwierigkeit ist, dass noch mehr Daten gespeichert werden müssen, die sich immer auf einen fixen Zeitraum beziehen. Eine Lösung, die unglaublich viel Redundanz auslösen würde, wäre es für jeden neuen Zeitabschnitt alle vorhanderen User mit neuer id zu kopieren.

              Es geht also nicht nur um die user_to_projekt Zuordnung, sondern beispielsweise auch um eine Zuordnung von Rückmeldungen zu Benutzern, die auch für den gleichen Zeitraum gespeichert werden sollen.

              Ich denke es mal so: Es müsste in dieser Datenbankstruktur möglich sein, dass ein User abhängig vom gewählten Zeitraum, sowohl unterschiedlichen Projekten, als auch anderen Daten wie Rückmeldungen etc. zugeordneten werden kann.
              Im Prinzip benötige ich einen "virtuellen" User, der unterschiedliche Eigenschaften zu bestimmten Zeiten annimmt und diese Eigenschaften beziehen sich nicht nur auf Projekte sondern auch auf weitere Datentabellen.

              Lässt sich das allein mit der Zuordnung des Zeitraumes zu einer Projekttabelle oder einer Zuordung zur Verknüpfungstabelle (Post #6) und der entsprechenden Joins lösen?

              Kommentar


              • #8
                Zitat von ecomeback Beitrag anzeigen
                Wenn es nur diese Abhängigkeit gäbe, dann machte ich mir auch nicht so viele Gedanken. Meine Schwierigkeit ist, dass noch mehr Daten gespeichert werden müssen, die sich immer auf einen fixen Zeitraum beziehen.
                ..
                Es geht also nicht nur um die user_to_projekt Zuordnung, sondern beispielsweise auch um eine Zuordnung von Rückmeldungen zu Benutzern, die auch für den gleichen Zeitraum gespeichert werden sollen.
                ..
                Das ist wieder recht schwammig, deswegen fragte ich nach einer konkreten Liste.
                Ob man gleich so einen "virtuellen User" haben muss, würde ich bezweifeln.
                Was spricht gegen eine Tabelle FEEDBACK mit einer Referenz zu User , zu Projekt und oder zu Zeitraum? Wenn man es hübsch machen will, kann eine Auswahl von User oder Projekt, die Auswahl für das jeweils andere Feld einschränken.
                Und wenn es weitere Merkmale gibt, die in dieser Abhängikeit erfasst werden müssen, dann wären das weitere Tabellen nach dem gleichen Schema.
                Alternativ kannst Du eine solche Tabelle auch mit Kategorien versehen und dadurch verschiedene Aspekte zuordnen (Sofern sich diese Aspekte strukturell stark ähneln).

                Kommentar

                Lädt...
                X