Frage zum Datenbankdesign

  • VB.NET

Es gibt 30 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Frage zum Datenbankdesign

    Hallo Leute,

    ich brauche Hilfe zum Design meiner kleinen Datenbank und wäre froh um einen Tip.
    Ich möchte eine Stundenerfassung für Projekte machen.
    Die tatsächlich gearbeiteten Stunden sollen dann mit den geplanten Stunden verglichen werden.
    Es handelt sich jedoch nicht nur um eine Art von Tätigkeit pro Projekt, sondern um mehrere Tätigkeiten.
    Jeder dieser Tätigkeiten soll also eine geplante Stundenanzahl bekommen, die dann mit den tatsächlichen Stunden verglichen werden können.

    Für mich gibt es 2 Ansätze:

    1. Ich nehme alles in die Projekttabelle sprich

    IDProjekt/Projektbez/Projektstraße.../geplanteStdTätigkeit1/tatsächlicheStdTätigkeit1/geplanteStdTätigkeit2/tatsächlicheStdTätigkeit2.....

    oder aber die Tabelle "Tätigkeit" wird separiert und schaut so aus:

    TätigkeitID /BezeichnungTätigkeit/geplanteStdTätigkeit/tatsächlicheStudTätigkeit
    1 Tätigkeit1
    2 Tätigkeit2
    3 Tätigkeit3
    .
    .
    .

    Wenn ich die Normalisierungsregeln richtig verstanden habe, ist es so, dass die Variante 1 (alle Stunden in der Projekttabelle) bereits der 3ten Normalisierungsregel entspricht und keine transitive Abhängikeit zw. den Nichtschlüsselattributen besteht. Es besteht keine Abhängigkeit zw. geplantenStundenTätigkeit1 und den tatsächlichenStundenTätigkeit1 und erst recht nicht zw. den geplantenStundenTätigkeit1 und den geplantenStundenTätigkeit2. Diese Variante müsste eigentlich richtig sein.
    Ist die 2te Variante folglich falsch ?
    Für Euren Spezialistenrat bin ich dankbar.
    @Cameron20 Falls Eure Projekte im TFS (Team Foundation Server) aufgeplant sind, dort gibt intern es eine Zeiterfassung für Projekte und sonstiges.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Das erste Modell erschließt sich mir überhaupt nicht.
    Du hast dort das Projekt, dann deine Tätigkeit, und dann plötzlich mehrere Zeitnehmungen für eine Tätigkeit?

    Für mich macht Folgendes viel mehr Sinn:
    Tabelle Projekt:
    ProjektID
    ProjektBezeichnung
    ProjektStraße
    ...

    Tabelle Tätigkeit:
    TätigkeitID
    REF_ProjektID
    TätigkeitBEzeichnung
    TätigkeitZeitSoll
    TätigkeitZeitIst

    Dadurch hast du eine 1:n Beziehung, minimale bis keine Datenredundanz und darüber hinaus keine Horizontale Skalierung (was viele RDBMS sowieso nicht unterstützen)

    Edit:
    3.NF bedeuted kurz gesagt:
    Lagere alles in Tabellen aus, was nicht irgendwie mit dem Primärschlüssel zusammenhängt. Und die Zeitnahmen tun genau das nicht. Sie hängen von der Tätigkeit ab, aber nicht vom Projekt.

    Edit2:
    Wenn mann die möglichen Redundanzen der Tätigkeitentabelle (öfters gleiche angaben bei Bezeichnung etc.) nochmals minimieren möchte, dann müsste man eine dritte Tabelle Projekt_Tätigkeit einführen, die lediglich die Schlüssel der beiden Anderen kombiniert. So kann man herausfinden welche Projekte welche Tätigkeiten haben, welche Tätigkeiten in welchen Projekten vorkommen, usw, ohne auch nur eine Tätigkeit doppelt in der Tabelle führen zu müssen.

    Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „EaranMaleasi“ ()

    Hallo EaranMaleasi,
    ok, danke Dir vielmals. Ich hatte einen Denkfehler. Ich dachte, dass ich den Primärschlüssel der Tätigkeittabelle in die Projekttabelle einbinden muss wenn ich eine eigene Tabelle (Variante 2) für die Tätigkeiten machen. Ich dachte die Tätigkeittabelle ist die Mastertabelle. Projetk ist aber die Mastertabelle.
    Aber wie meinst Du das mit der horizontalen Skalierbarkeit ? Meinst Du hiermit, dass wenn Tätigkeiten hinzukommen, es leichter mit der Detailtabelle "Tätigkeiten" zu bewerkstelligen ist ?

    Noch eine Frage:
    Wenn mann die möglichen Redundanzen der Tätigkeitentabelle (öfters
    gleiche angaben bei Bezeichnung etc.) nochmals minimieren möchte, dann
    müsste man eine dritte Tabelle Projekt_Tätigkeit
    einführen, die lediglich die Schlüssel der beiden Anderen kombiniert.
    So kann man herausfinden welche Projekte welche Tätigkeiten haben,
    welche Tätigkeiten in welchen Projekten vorkommen, usw, ohne auch nur
    eine Tätigkeit doppelt in der Tabelle führen zu müssen.

    Das wäre die Zwischentabelle der n:m Beziehungen, oder ?


    Abschliessen noch eine Frage bzgl. der 3. NF:
    Es heisst doch in der Literatur, dass kein Nichtschlüsselattribut von einem anderen Nichtschlüsselattribut abhängen darf, oder ?
    Und das wäre doch bei Variante 1 der Fall. Redundazen gäbe es auch nicht. Deines ist natürlich eleganter, doch wo ist der Fehler bei Variante 1.
    Umsetzen werden ich den von Dir vorgeschlagenen Weg. Sorry für die Fragen, bin Newbie auf dem Gebiet.

    Cameron20 schrieb:

    Aber wie meinst Du das mit der horizontalen Skalierbarkeit ?
    Mit horizontaler Skalierbarkeit meine ich, dass die Datenbank in der Lage ist nicht nur mit sehr vielen Zeilen umzugehen (vertikal skalierbar) sondern auch mit sehr vielen Spalten (horizontal skalierbar). MySQL hat z.B. eine maximale Satzlänge von ~65KB dies bedeutet, dass du nach "einigen" Spalten bereits an das Satzlimit kommst. (Bitte nicht mit Blob\Text argumentieren, mir ist deren existenz durchaus bewusst)

    Cameron20 schrieb:

    Das wäre die Zwischentabelle der n:m Beziehungen, oder ?
    Exakt.

    Cameron20 schrieb:

    Es heisst doch in der Literatur, dass kein Nichtschlüsselattribut von einem anderen Nichtschlüsselattribut abhängen darf, oder ?
    Und das wäre doch bei Variante 1 der Fall. Redundazen gäbe es auch nicht.
    Da muss ich dich erstmal bitten ein konkretes Beispiel aufzuzeigen, da ich deine erste Variante nicht wirklich verstanden habe.
    Hallo EaranMaleasi,
    ok, Also Bei mir handelt es sich z.B. um Dienstleistungen für ein Bauprojekt in einem Ing. Büro. Hier gibt es verschiedene - ich nenne es "Tätigkeiten" - die im Rahmen eines Projekts anfallen: Man macht z.B. einen Entwurf, zeichnet Schalpläne, dann Bewehrungspläne und man rechnet Statik. Alle diese und (noch mehr) Tätigkeiten gehören zu einem Projekt. Die Zeiten für jede Tätigkeit werden für das Honorar wird im Vorraus geschätzt. Das sind die geplanten Stunden je Tätigkeit. Demgegenüber sollen aber auch die Stunden die tatsächlich für die jeweilige Tätigkeit anfallen erfasst werden. So ist der Sachverhalt.
    Okay, und nun erkläre mir, wie dein Sachverhalt hierzu passt:

    Cameron20 schrieb:

    IDProjekt/Projektbez/Projektstraße.../geplanteStdTätigkeit1/tatsächlicheStdTätigkeit1/geplanteStdTätigkeit2/tatsächlicheStdTätigkeit2.....
    1. Würdest du für jede Tätigkeit, das Projekt mit all seinen Daten mitkopieren. => Redundanz
    2. Hast du hier plötzlich geplanteStdTätigkeit1/tatsächlicheStdTätigkeit1/geplanteStdTätigkeit2/tatsächlicheStdTätigkeit2, wo kommen plötzlich die mehrfachmessungen her? Wird bei einer Tätigkeit mehr als einmal die Zeit gemessen?
    zu 1.
    Ich hätte halt gleich für jedes Projekt im Datensatz die geplante Zeit z.b. für den Bewehrungsplan, in der nächsten Spalte die tatsächliche Zeit für den Bewehrungsplan usw. (siehe Punkt 2)
    Diese Daten hängen ja wirklich nur vom Projekt ab. Oder sehe ich das verkehrt.
    zu 2.
    Also hier habe ich vergessen zu sagen, dass die tats. Stunden die Summe der Zeiterfassung ist. Es sollen also täglich die Stunden je Tätigkeit gebucht werden.
    Korrekt müsste es in der Projekttabelle heissen:
    ProjetkID/..../geplanteStundenBewehrungsplan/tatsächlicheStundenBewehrungsplan/geplanteStundenSchalplan/tatsächlicheStundenSchalplan/.....

    Somit käme jedes Projekt nur einmal vor. Nur das eben manche Spalten bei den Tätigkeiten nicht befüllt sind, wenn es diese Tätigkeiten nicht gibt.

    Cameron20 schrieb:

    Somit käme jedes Projekt nur einmal vor. Nur das eben manche Spalten bei den Tätigkeiten nicht befüllt sind, wenn es diese Tätigkeiten nicht gibt.
    Sehe ich das richtig, dass du:
    • Festgelegte Tätigkeiten hast?
    • Diese Tätigkeiten sich nicht ändern, oder vermehren?
    • Diese Tätigkeiten in einem Projekt vorkommen können, aber nicht müssen?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „EaranMaleasi“ ()

    ganz genau so ist es. Es sind immer die gleichen Tätigkeiten, wie Bewehrungsplan, Schalplan usw. die sich nicht verändern. Sie können vorkommen, müssen aber nicht. Das heisst, es kann sein das man z.B. gar keinen Bewehrungsplan macht.
    Ich danke Dir für die Hilfe !!
    ich empfehle sowas anhand eines ER-Diagramms zu diskutieren.
    Bastel doch mal eins im Dataset-Designer, und hänge Screenshot davon an.
    Oder häng zusätzlich die Xsd auch an, dann kann man sogar Gegenentwürfe unterbreiten.

    Dateien anhängen:

    DatasetDesigner kommt hier im ersten Film vor: vier Views-Videos
    EaranMaleasi:

    So würde das dann ausschauen wenn ich also die geplanten Stunden in die Projekttabelle packe, aber für die Buchung der Iststunden noch eine separate Tabelle mit tbl_Buchung_Ist_Stunden mache. Ist das regelkonform oder hast Du noch Verbesserungsvorschläge ?



    ErfinderDesRades:
    ich hab das jetzt mal mit Access gemacht.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Cameron20“ ()

    Ich tät mich auch mal zu Wort melden, hier ein Vorschlag aus der Praxis (my daily Business):

    ​1. Vorkalkulation(-en) (pro Projekt)
    ​2. Nachkalkulation (pro Projekt)
    ​3. Leistungen (Tätigkeiten) mit einer Zeitangabe (Vorgabezeit)
    ​4. Pro Vorkalkulation gibt es X Leistungen (Dynamisch, nicht fix) zur Auswahl
    ​4.1 Pro Leistung kann eine Qualifikation (mit hinterlegten Kostensatz) gewählt werden
    ​5. In der Nachkalkulation holst du die die Vorkalkulierten Zeiten rein, und lässt den User die Ist-Zeiten eingeben
    5. Die Ist-Zeiten mit dem Stundensatz der Qualifikation verrechnen -> Zack, hast du ein sauberes Ergebnis

    Tipp: Halte alles möglichst flexibel, nachher soll noch was dazu kommen, dann hast du den Salat :D

    Das heißt:
    ​​Keine festen Leistungen pro Vorkalkulation, hier sollten x-beliebig viele in der Vorkalkulation wählbar sein
    ​Keine festen Qualifikationen
    Keine festen (Lohn-) Kostensätze
    ​-> Sollte alles über eine kleine Verwaltung anlegbar sein um später flexibel zu sein, falls du Opfer deines Erfolgs wirst :thumbup:

    Datenbank:
    1. Tabelle Projekte
    1. Tabelle Leistungen
    1. Tabelle Qualifikationen
    ​1. Tabelle Vorkalkulationen
    ​1. Tabelle Nachkalkulationen
    ​+ alles was zur Verwaltung an Sich benötigt wird

    Grüzze und einen schönen Abend

    ​mrMo
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen

    Cameron20 schrieb:

    So würde das dann ausschauen wenn ich also die geplanten Stunden in die Projekttabelle packe, aber für die Buchung der Iststunden noch eine separate Tabelle mit tbl_Buchung_Ist_Stunden mache. Ist das regelkonform oder hast Du noch Verbesserungsvorschläge ?
    Das Konzept für die Ist-Stunden (Bild) finde ich sehr plausibel.
    Unplausibel ist mir, warum die Plan-Stunden einen ganz anderen Niederschlag finden sollen.
    In meim Modell gäbe es ühaupt keinen Unterschied zw. Plan-Stunden und Ist-Stunden - ausser diesen:
    Stunde hätte noch einen Bool, mit dem man geplant von ist unterscheiden kann. Ansonsten ists dieselbe Struktur - kommt also in dieselbe Tabelle.

    Dann hätte ich noch ein paar Anmerkungen zur Benamung.
    Vor allem der unsinnige tbl_-Prefix ist mir ein Gräuel. Der Sinn von Prefixen ist, Unterscheidungen treffen zu können. Wenn aber alle Namen ausnahmslos denselben Prefix haben, bringt das nix zum Unterscheiden - bringt nur was zum Zungen-Brechen und Code-Verhässlichen.
    Auch zur Benamung von Schlüsselspalten habe ich Vorschläge - siehe einfach
    codeproject.com/articles/10331…eginners#Model-Guidelines

    Cameron20 schrieb:

    möglichst einfach halten und muss schnell zum Ergebnis kommen.


    Kann ich nachvollziehen, ich weiß nur leider wie es in der Praxis ist. Sollte deine Software dann mal gut funktionieren (wovon ich ausgehe :) ​), kommen die Wünsche nach X und Y.
    ​Daher halte dir weitere Wege/Erweiterugen offen, auch wenn du es nicht so machst wie ich beschrieben habe :thumbup:
    "Gib einem Mann einen Fisch und du ernährst ihn für einen Tag. Lehre einen Mann zu fischen und du ernährst ihn für sein Leben."

    Wie debugge ich richtig? => Debuggen, Fehler finden und beseitigen
    Wie man VisualStudio nutzt? => VisualStudio richtig nutzen
    Dem wiederspricht aber evtl. das Yagni-Prinzip der agilen Programmierung.
    Dieses sagt: "Treibe keinen Aufwand für Anforderungen, die nicht bestellt sind".
    Also Flexiblität, Erweiterbarkeit selbstverständlich immer mitnehmen, wenns "nichts kostet".
    Aber keinen Aufwand treiben in sog. "vorauseilendem Gehorsam".
    Weil am Ende wirds nicht bestellt, oder wird anders bestellt, und dann war der Zusatz-Aufwand nicht nur für Katz, sondern verursacht noch mehr Zusatz-Aufwand, um den überflüssigen Kropf wieder abzubauen.

    Ist aber auch Abwägungssache.
    Siimpel-Beispiel: manchmal funzt eine Tabelle auch ohne Primärschlüssel. Aber weils wesentlich mehr Möglichkeiten offenhält, wenn man trotzdem eine ID dranmacht, fängt der Yagni wegen das auch nicht an zu weinen.