it-swarm.com.de

Erstmaliges Datenbankdesign: Bin ich ein Ingenieur?

Hintergrund

Ich bin ein CS-Student im ersten Jahr und arbeite Teilzeit für das kleine Geschäft meines Vaters. Ich habe keine Erfahrung in der praktischen Anwendungsentwicklung. Ich habe Skripte in Python geschrieben, einige Kursarbeiten in C, aber nichts dergleichen.

Mein Vater hat ein kleines Schulungsunternehmen und derzeit werden alle Kurse über eine externe Webanwendung geplant, aufgezeichnet und nachverfolgt. Es gibt eine Export-/"Berichts" -Funktion, die jedoch sehr allgemein ist und für die wir spezielle Berichte benötigen. Wir haben keinen Zugriff auf die eigentliche Datenbank, um die Abfragen auszuführen. Ich wurde gebeten, ein benutzerdefiniertes Berichtssystem einzurichten.

Meine Idee ist, die generischen CSV-Exporte und -Importe (wahrscheinlich mit Python) in eine MySQL-Datenbank zu erstellen, die jede Nacht im Büro gehostet wird und von der aus ich die erforderlichen Abfragen ausführen kann. Ich habe keine Erfahrung mit Datenbanken, verstehe aber die Grundlagen. Ich habe ein wenig über das Erstellen von Datenbanken und normale Formulare gelesen.

Wir werden vielleicht bald internationale Kunden haben, daher möchte ich, dass die Datenbank in diesem Fall nicht explodiert. Wir haben derzeit auch ein paar große Unternehmen als Kunden mit verschiedenen Abteilungen (z. B. ACME-Muttergesellschaft, ACME-Gesundheitsabteilung, ACME-Körperpflegeabteilung).

Das Schema, das ich mir ausgedacht habe, ist das folgende:

  1. Aus Kundensicht:
    • Clients ist der Haupttisch
    • Kunden sind mit der Abteilung verbunden, für die sie arbeiten
      • Die Abteilungen können über ein Land verteilt sein: Personalabteilung in London, Marketing in Swansea usw.
      • Abteilungen sind an die Aufteilung eines Unternehmens gebunden
    • Die Geschäftsbereiche sind an die Muttergesellschaft gebunden
  2. Aus der Sicht der Klassen:
    • Sitzungen ist der Haupttisch
      • Ein Lehrer ist mit jeder Sitzung verbunden
      • Für jede Sitzung wird eine Status-ID vergeben. Z.B. 0 - Abgeschlossen, 1 - Abgebrochen
      • Sitzungen werden in "Packs" beliebiger Größe gruppiert
    • Jedes Paket ist einem Kunden zugeordnet

Ich habe das Schema auf einem Blatt Papier "entworfen" (eher wie gekritzelt) und versucht, es auf die dritte Form zu normalisieren. Ich habe es dann in MySQL Workbench gesteckt und es hat alles schön für mich gemacht:
( Klicken Sie hier, um die Grafik in Originalgröße zu sehen )

alt text
(Quelle: maian.org )

Beispielabfragen, die ich ausführen werde

  • Welche Kunden mit noch verbleibendem Guthaben sind inaktiv (diejenigen, für die in Zukunft kein Unterricht geplant ist)
  • Wie hoch ist die Anwesenheitsquote pro Kunde/Abteilung/Abteilung (gemessen an der Status-ID in jeder Sitzung)?
  • Wie viele Klassen hat ein Lehrer in einem Monat
  • Kennzeichnen Sie Kunden mit geringer Anwesenheitsrate
  • Benutzerdefinierte Berichte für Personalabteilungen mit Anwesenheitsraten der Mitarbeiter in ihrer Abteilung

Fragen)

  • Ist das überarbeitet oder bin ich auf dem richtigen Weg?
  • Wird die Notwendigkeit, mehrere Tabellen für die meisten Abfragen zu verknüpfen, zu einem großen Leistungseinbruch führen?
  • Ich habe den Clients eine 'lastsession'-Spalte hinzugefügt, da dies wahrscheinlich eine häufige Abfrage sein wird. Ist das eine gute Idee oder sollte ich die Datenbank streng normalisieren?

Vielen Dank für Ihre Zeit

244
bob esponja

Noch einige Antworten auf Ihre Fragen:

1) Sie sind ziemlich genau auf dem richtigen Weg für jemanden, der sich zum ersten Mal einem solchen Problem nähert. Ich denke, die Hinweise von anderen zu dieser Frage decken sie so ziemlich ab. Gut gemacht!

2 & 3) Der Performance-Hit, den Sie erzielen werden, hängt in hohem Maße davon ab, ob Sie die richtigen Indizes für Ihre speziellen Abfragen/Verfahren und vor allem das Volumen der Datensätze haben und optimieren. Wenn Sie nicht von weit über einer Million Datensätzen in Ihren Haupttabellen sprechen, scheinen Sie auf dem besten Weg zu sein, ein ausreichend Mainstream-Design zu haben, bei dem die Leistung bei angemessener Hardware kein Problem darstellt.

Das heißt, und dies bezieht sich auf Ihre Frage 3. Mit dem Anfang, den Sie haben, sollten Sie sich wahrscheinlich nicht wirklich übermäßig Sorgen um die Leistung oder die Überempfindlichkeit gegenüber der Normalisierungsorthodoxie machen. Hierbei handelt es sich um einen Berichtsserver, den Sie erstellen, und nicht um ein transaktionsbasiertes Anwendungs-Backend, dessen Profil sich in Bezug auf die Bedeutung von Leistung oder Normalisierung erheblich unterscheidet. Eine Datenbank, die eine Live-Anmeldung und eine Terminierungsanwendung sichert, muss Abfragen berücksichtigen, die Sekunden benötigen, um Daten zurückzugeben. Eine Berichtsserverfunktion ist nicht nur toleranter für komplexe und langwierige Abfragen, auch die Strategien zur Leistungsverbesserung sind sehr unterschiedlich.

In einer transaktionsbasierten Anwendungsumgebung können Sie beispielsweise die Leistung verbessern, indem Sie gespeicherte Prozeduren und Tabellenstrukturen bis zum n-ten Grad umgestalten oder eine Caching-Strategie für kleine Mengen häufig angeforderter Daten entwickeln. In einer Berichtsumgebung können Sie dies sicherlich tun, aber Sie können die Leistung noch stärker beeinträchtigen, indem Sie einen Snapshot-Mechanismus einführen, bei dem ein geplanter Prozess ausgeführt und vorkonfigurierte Berichte gespeichert werden und Ihre Benutzer ohne Belastung für Ihre Datenbankebene auf die Snapshot-Daten zugreifen eine pro Anfrage Basis.

All dies ist eine langwierige Demonstration, um zu veranschaulichen, dass die von Ihnen verwendeten Designprinzipien und -tricks in Anbetracht der Rolle der von Ihnen erstellten Datenbank unterschiedlich sein können. Ich hoffe das ist hilfreich.

42
Tom Crowe

Du hast die richtige Idee. Sie können es jedoch bereinigen und einige der Zuordnungstabellen (mit *) entfernen.

Was Sie tun können, ist in der Tabelle Abteilungen CityId und DivisionId hinzuzufügen.

Abgesehen davon denke ich, dass alles in Ordnung ist ...

14
Reverend Gonzo

Es sieht so aus, als würden Sie mit einer guten Detailgenauigkeit entwerfen.

Ich denke, dass Länder und Unternehmen in Ihrem Design wirklich dasselbe sind wie Städte und Abteilungen. Ich werde die Tabellen "Countries and Cities" (und "Cities_Has_Departments") entfernen und bei Bedarf der Tabelle "Companies" ein boolesches Flag "IsPublicSector" hinzufügen (oder eine Spalte "CompanyType", wenn es mehr Auswahlmöglichkeiten gibt als nur "Private Sector"/"Public Sector").

Ich denke auch, dass bei der Verwendung der Tabelle "Abteilungen" ein Fehler aufgetreten ist. Es sieht so aus, als ob die Tabelle "Abteilungen" als Referenz für die verschiedenen Arten von Abteilungen dient, die jeder Kundenbereich haben kann. In diesem Fall sollte es DepartmentTypes heißen. Ihre Kunden (ich nehme an, Teilnehmer) gehören jedoch nicht zu einem Abteilungs-TYP, sondern zu einer tatsächlichen Abteilungsinstanz in einem Unternehmen. So wie es jetzt aussieht, werden Sie wissen, dass ein bestimmter Kunde irgendwo einer Personalabteilung angehört, aber nicht welcher!

Mit anderen Worten, Clients sollten mit der Tabelle verknüpft sein, die Sie Divisions_Has_Departments nennen (aber die ich einfach Departments nennen würde). Wenn dies der Fall ist, müssen Sie Städte wie oben beschrieben in Abteilungen reduzieren, wenn Sie die standardmäßige referenzielle Integrität in der Datenbank verwenden möchten.

6
Larry Lustig

Die einzigen Änderungen, die ich vornehmen würde, sind:
1- Ändern Sie Ihre VARCHAR in NVARCHAR. Wenn Sie international arbeiten, möchten Sie möglicherweise Unicode.

2- Ändern Sie Ihre Int-IDs nach Möglichkeit in GUIDs (Unique Identifier) ​​(dies könnte nur meine persönliche Präferenz sein). Angenommen, Sie kommen irgendwann an den Punkt, an dem Sie mehrere Umgebungen haben (dev/test/staging/prod), möchten Sie möglicherweise Daten von einer zur anderen migrieren. Have GUID Ids erleichtert dies erheblich.

3- Drei Ebenen für Ihr Unternehmen -> Abteilung -> Abteilungsstruktur reichen möglicherweise nicht aus. Dies ist möglicherweise zu technisch, aber Sie können diese Hierarchie so verallgemeinern, dass Sie n Tiefenebenen unterstützen können. Dadurch werden einige Ihrer Abfragen komplexer, sodass sich der Kompromiss möglicherweise nicht lohnt. Es kann auch sein, dass ein Client mit mehreren Ebenen problemlos in dieses Modell eingefügt werden kann.

4- Sie haben auch einen Status in der Client-Tabelle, der ein VARCHAR ist und keine Verknüpfung zur Status-Tabelle hat. Ich würde dort etwas mehr Klarheit darüber erwarten, was der Kundenstatus darstellt.

6
Jacob G

Übrigens: Wenn Sie bereits CSVs generieren und diese in eine mySQL-Datenbank laden möchten, ist LOAD DATA LOCAL INFILE Ihr bester Freund: http://dev.mysql.com/doc/ refman/5.1/de/load-data.html . Mysqlimport ist auch einen Blick wert und ein Kommandozeilen-Tool, das im Grunde genommen einen netten Wrapper zum Laden von Daten-Dateien darstellt.

5
jrheard

Folgende Kommentare basieren auf der Rolle als Business Intelligence/Reporting-Spezialist und Strategie-/Planungsmanager:

  1. Ich stimme Larry oben zu. IMHO, es ist nicht so viel überarbeitet, manche Dinge sehen einfach ein wenig fehl am Platz aus. Um es einfach zu halten, würde ich den Kunden direkt mit einer Firmen-ID, einer Abteilungsbeschreibung, einer Abteilungsbeschreibung, einer Abteilungs-Typ-ID und einer Abteilungs-Typ-ID versehen. Verwenden Sie die Abteilungsart-ID und die Abteilungsart-ID als Verweise auf Nachschlagetabellen und interne Berichts-/Analysefelder, um eine langfristige Konsistenz zu gewährleisten.

  2. Die Packs-Tabelle enthält die Spalte "Credit". Sollte dies nicht an die Client-Basistabelle gebunden sein, sodass Sie sehen können, wie viel Credit für zukünftige Klassen noch übrig ist, wenn es sich um viele Packs handelt? Die Anwendung kann sich um die Berechnung kümmern und sie zentral in der Client-Tabelle speichern.

  3. Unternehmensinformationen könnten viel mehr Felder enthalten, einschließlich der offensichtlichen Adresse/Telefonnummer/etc. Information. Ich wäre auch bereit, in D & B "DUNs" -Spalten (Site/Branch/Ultimate) langfristig hinzuzufügen. Dun and Bradstreet (D & B) verfügt über einen riesigen Katalog von Unternehmen, und Sie werden später feststellen, dass deren Informationen sehr hilfreich sind zur Berichterstattung/Analyse. Dadurch wird das von Ihnen erwähnte Problem der Mehrfachunterteilung behoben, und Sie können deren Hierarchie für sub/division/branches/etc. Aufrollen. von großen Korps.

  4. Sie erwähnen nicht, mit wie vielen Datensätzen Sie arbeiten, was bedeuten könnte, dass Sie sich auf eine große Entwicklungsinitiative einstellen, die mit vorgefertigter "Berichterstellungs" -Software schneller und mit weitaus weniger Kopfschmerzen hätte fertig werden können. Wenn Sie nicht mit großen Datenbankzeilen (<65000) arbeiten, stellen Sie sicher, dass MS-Access, OpenOffice (Base) oder verwandte Berichts-/App-Entwicklerlösungen den Trick nicht ausführen können. Ich benutze die kostenlose APEX-Software von Oracle ziemlich oft selbst. Sie wird mit der kostenlosen Datenbank Oracle XE geliefert und kann sie einfach von der Website heruntergeladen werden.

  5. Zu Ihrer Information - Reporting Insight: Bei großen Datenbanken verfügen Sie normalerweise über zwei Datenbankinstanzen. A) Transaktionsdatenbank zum Aufzeichnen der einzelnen detaillierten Datensätze. b) Berichtsdatenbank (Data Mart/Data Warehouse) auf einem separaten Computer. Weitere Informationen finden Sie in Google Star Schema und Snowflake Schema.

Grüße.

3
Will

Die meisten Dinge wurden bereits gesagt, aber ich bin der Meinung, dass ich eines hinzufügen kann: Es ist durchaus üblich, dass sich jüngere Entwickler im Vorfeld ein wenig zu viele Sorgen um die Leistung machen, und Ihre Frage nach dem Verbinden von Tabellen scheint in diese Richtung zu gehen. Dies ist ein Anti-Pattern für die Softwareentwicklung mit dem Namen ' Premature Optimization '. Versuchen Sie, diesen Reflex aus Ihrem Kopf zu verbannen :)

Noch etwas: Glauben Sie wirklich, dass Sie die Tabellen "Städte" und "Länder" brauchen? Wäre es für Ihre Anwendungsfälle nicht ausreichend, in der Tabelle der Abteilungen die Spalten "Stadt" und "Land" anzugeben? Z.B. Muss Ihre Anwendung Abteilungen nach Stadt und Land auflisten?

3
Hans Westerbeek

Ich möchte nur auf die Sorge eingehen, dass der Beitritt zu mehreren Tischen einen Leistungseinbruch zur Folge hat. Haben Sie keine Angst, sich zu normalisieren, da Sie Joins ausführen müssen. Joins sind normal und werden in relationalen Datenbanken erwartet. Sie sind so konzipiert, dass sie gut damit umgehen. Sie müssen PK/FK-Beziehungen festlegen (für die Datenintegrität ist dies beim Entwerfen wichtig), aber in vielen Datenbanken werden FKs nicht automatisch indiziert. Da sie in den Joins verwendet werden, sollten Sie zunächst die FKS indizieren. PKs erhalten in der Regel einen Index für die Erstellung, da sie eindeutig sein müssen. Es ist richtig, dass das Data Warehouse-Design die Anzahl der Joins verringert, aber normalerweise gelangt man erst dann zum Data Warehousing, wenn in einem Bericht Millionen von Datensätzen abgerufen werden müssen. Selbst dann beginnen fast alle Data Warehouses mit einer Transaktionsdatenbank, um die Daten in Echtzeit zu erfassen, und dann werden die Daten nach einem Zeitplan (nachts oder monatlich oder nach geschäftlichen Anforderungen) in das Warehouse verschoben. Dies ist also ein guter Anfang, auch wenn Sie später ein Data Warehouse entwerfen müssen, um die Berichtsleistung zu verbessern.

Ich muss sagen, dass Ihr Design für einen CS-Studenten im ersten Jahr beeindruckend ist.

2
HLGEM

Es ist nicht überarbeitet, so würde ich das Problem angehen. Das Beitreten ist in Ordnung, es wird nicht viel Leistung bringen (es ist absolut notwendig, wenn Sie die Datenbank nicht normalisieren, was nicht empfohlen wird!). Überprüfen Sie den Status, ob Sie stattdessen einen Aufzählungsdatentyp verwenden können, um diese Tabelle zu optimieren.

1
Chris Dennett

Ich habe im Bereich Training/Schule gearbeitet und dachte, ich würde darauf hinweisen, dass es im Allgemeinen eine M: 1-Beziehung zwischen dem, was Sie "Sessions" (Instanzen eines bestimmten Kurses) nennen, und dem Kurs selbst gibt. Mit anderen Worten, Ihr Katalog bietet den Kurs an ("Spanisch 101" oder was auch immer), aber Sie können zwei verschiedene Instanzen davon während eines einzelnen Semesters haben (Di-Do unterrichtet von Smith, Mi-Fr unterrichtet von Jones).

Davon abgesehen sieht es nach einem guten Start aus. Ich wette, Sie werden feststellen, dass die Clientdomäne (Diagramme, die zu "Clients" führen) komplexer ist, als Sie es modelliert haben, aber gehen Sie nicht über Bord, bis Sie einige echte Daten haben, die Sie leiten.

1
Larry OBrien

Ein paar Dinge fielen mir ein:

  1. Die Tische schienen auf Berichterstattung ausgerichtet zu sein, aber das Geschäft nicht wirklich zu leiten. Ich denke, wenn sich ein Kunde anmeldet, wird im Wesentlichen eine Bestellung für den Kunden aufgegeben, der an einer Sitzungsliste teilnimmt, und diese Bestellung kann für mehrere Mitarbeiter in einem Unternehmen gelten. Es scheint, dass eine "Bestell" -Tabelle wirklich im Zentrum Ihres Systems steht und Ihre Datenerfassung und eventuelle Berichterstellung vorantreibt. (Vergleichen Sie die Papierdokumente, die Sie zum Ausführen des Geschäfts verwendet haben, mit Ihrem Datenbankdesign, um festzustellen, ob eine logische Übereinstimmung vorliegt.)

  2. Unternehmen haben oft keine Abteilungen. Die Mitarbeiter wechseln manchmal die Abteilungen oder sogar die Mitte der Sitzung. Firmen fügen manchmal Abteilungen/Abteilungen hinzu/löschen/benennen sie um. Stellen Sie sicher, dass der mögliche Inhalt Ihrer Tabellen, der sich in Echtzeit ändert, nachfolgende Berichte/Gruppierungen nicht erschwert. Bei so vielen Kontaktdaten, die auf so viele Tabellen verteilt sind, müssen Sie möglicherweise eine sehr strenge Dateneingabevalidierung durchführen, damit Ihre Berichte aussagekräftig und inklusiv bleiben. Wenn beispielsweise ein neuer Kunde hinzugefügt wird, muss sichergestellt werden, dass seine Firma/Abteilung/Abteilung/Stadt mit den gleichen Werten übereinstimmt wie seine Kollegen.

  3. Das "Packs" -Konzept ist überhaupt nicht klar.

  4. Da Sie angeben, dass es sich um ein kleines Unternehmen handelt, wäre es angesichts der Geschwindigkeit und Kapazität der aktuellen Computer überraschend, wenn die Leistung ein Problem darstellen würde.

0
joe snyder