Hintergrund
Ich bin ein CS-Student im ersten Jahr und arbeite Teilzeit für das kleine Unternehmen meines Vaters. Ich habe keine Erfahrung in der realen 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 weiterverfolgt. Es gibt eine Export- / "Berichts" -Funktion, die jedoch sehr allgemein gehalten ist und spezielle Berichte benötigt. Wir haben keinen Zugriff auf die eigentliche Datenbank, um die Abfragen auszuführen. Ich wurde gebeten, ein benutzerdefiniertes Berichtssystem einzurichten.
Meine Idee ist es, die generischen CSV-Exporte zu erstellen und (wahrscheinlich mit Python) in eine MySQL-Datenbank zu importieren, die jede Nacht im Büro gehostet wird, von wo aus ich die spezifischen Abfragen ausführen kann, die benötigt werden. Ich habe keine Erfahrung mit Datenbanken, verstehe aber die Grundlagen. Ich habe ein wenig über die Datenbankerstellung und normale Formulare gelesen.
Möglicherweise haben wir bald internationale Kunden, daher möchte ich, dass die Datenbank in diesem Fall nicht explodiert. Wir haben derzeit auch einige große Unternehmen als Kunden mit unterschiedlichen Abteilungen (z. B. ACME-Muttergesellschaft, ACME-Gesundheitsabteilung, ACME-Körperpflegesparte).
Das Schema, das ich mir ausgedacht habe, ist das folgende:
- Aus Kundensicht:
- Clients ist die Haupttabelle
- Kunden sind mit der Abteilung verbunden, für die sie arbeiten
- Abteilungen können über ein Land verteilt sein: HR in London, Marketing in Swansea usw.
- Abteilungen sind mit der Aufteilung eines Unternehmens verbunden
- Die Geschäftsbereiche sind mit der Muttergesellschaft verbunden
- Aus der Klassenperspektive:
- Sitzungen ist der Haupttisch
- Ein Lehrer ist mit jeder Sitzung verbunden
- Jede Sitzung erhält eine Status-ID. ZB 0 - Abgeschlossen, 1 - Abgebrochen
- Sitzungen werden in "Packs" beliebiger Größe gruppiert
- Jedes Paket ist einem Client zugeordnet
- Sitzungen ist der Haupttisch
Ich habe das Schema auf einem Blatt Papier "entworfen" (eher wie gekritzelt) und versucht, es auf die 3. Form zu normalisieren. Ich habe es dann in MySQL Workbench eingesteckt und es hat alles für mich hübsch gemacht:
( Klicken Sie hier für eine Grafik in voller Größe )
(Quelle: maian.org )
Beispielabfragen, die ich ausführen werde
- Welche Kunden mit noch verbleibendem Guthaben sind inaktiv (diejenigen ohne Unterricht in der Zukunft geplant)
- 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 Anwesenheitsquote
- Benutzerdefinierte Berichte für Personalabteilungen mit Anwesenheitsraten von Personen in ihrer Abteilung
Fragen)
- Ist das überarbeitet oder bin ich auf dem richtigen Weg?
- Wird die Notwendigkeit, für die meisten Abfragen mehrere Tabellen zu verknüpfen, zu einem großen Leistungseinbruch führen?
- Ich habe Clients eine Spalte "Lastsession" 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
quelle
divisions
hat Spalte benanntdivisionid
. Finden Sie das nicht überflüssig? Nennen Sie es einfachid
. auch Ihre Tabellennamen einschließlich_has_
: Ich würde das entfernen und es einfach zum Beispiel benennencities_departments
. IhreDATETIME
Spalten sollten vom Typ sein, esTIMESTAMP
sei denn, es handelt sich um Benutzereingabewerte. Ich denke, es ist eine gute Idee, diecities
undcountries
Tische zu haben . Möglicherweise treten Probleme bei der Beschränkung der Tabellen auf eine einzelne aufstatus
.INT
Antworten:
Weitere 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 bisher ziemlich genau ab. Gut gemacht!
2 & 3) Der Leistungseinbruch, den Sie erzielen, hängt weitgehend 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 über weit über eine Million Datensätze in Ihren Haupttabellen sprechen, scheinen Sie auf dem Weg zu einem ausreichend Mainstream-Design zu sein, sodass die Leistung bei angemessener Hardware kein Problem darstellt.
Das heißt, und dies bezieht sich auf Ihre Frage 3: Von Anfang an sollten Sie sich hier wahrscheinlich keine allzu großen Sorgen um die Leistung oder die Überempfindlichkeit gegenüber der Normalisierungsorthodoxie machen. Dies ist ein Berichtsserver, den Sie erstellen, kein transaktionsbasiertes Anwendungs-Backend, das hinsichtlich der Bedeutung der Leistung oder Normalisierung ein ganz anderes Profil aufweist. Eine Datenbank, die eine Live-Anmelde- und Planungsanwendung unterstützt, muss Abfragen berücksichtigen, deren Rückgabe Sekunden dauert. Eine Berichtsserverfunktion hat nicht nur eine größere Toleranz für komplexe und langwierige Abfragen, sondern die Strategien zur Verbesserung der Leistung sind sehr unterschiedlich.
In einer transaktionsbasierten Anwendungsumgebung können Sie beispielsweise die gespeicherten 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 beeinflussen, indem Sie einen Snapshot-Mechanismus einführen, bei dem ein geplanter Prozess ausgeführt und vorkonfigurierte Berichte gespeichert werden und Ihre Benutzer auf die Snapshot-Daten zugreifen, ohne Ihre Datenbankschicht zu belasten eine pro Anfrage Basis.
All dies ist eine langwierige Angelegenheit, um zu veranschaulichen, dass die von Ihnen verwendeten Designprinzipien und -tricks je nach der Rolle der von Ihnen erstellten Datenbank unterschiedlich sein können. Ich hoffe das ist hilfreich.
quelle
Du hast die richtige Idee. Sie können es jedoch bereinigen und einige der Zuordnungstabellen (mit *) entfernen.
Sie können in der Tabelle "Abteilungen" CityId und DivisionId hinzufügen.
Abgesehen davon denke ich, dass alles in Ordnung ist ...
quelle
Die einzigen Änderungen, die ich vornehmen würde, sind:
1- Ändern Sie Ihr VARCHAR in NVARCHAR. Wenn Sie international werden, möchten Sie möglicherweise Unicode.
2- Ändern Sie Ihre Int-IDs nach Möglichkeit in GUIDs (Uniqueidentifier) (dies könnte nur meine persönliche Präferenz sein). Angenommen, Sie erreichen irgendwann den Punkt, an dem Sie mehrere Umgebungen haben (dev / test / staging / prod), möchten Sie möglicherweise Daten von einer zur anderen migrieren. Mit GUID-IDs wird dies erheblich vereinfacht.
3- Drei Schichten für Ihr Unternehmen -> Abteilung -> Abteilungsstruktur reichen möglicherweise nicht aus. Dies ist möglicherweise überentwickelt, 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. Ferner könnte es sein, dass jeder Client, der mehr Ebenen hat, leicht in dieses Modell "gestopft" werden kann.
4- Sie haben auch einen Status in der Client-Tabelle, der ein VARCHAR ist und keinen Link zur Status-Tabelle hat. Ich würde dort etwas mehr Klarheit darüber erwarten, was der Kundenstatus darstellt.
quelle
Es sieht so aus, als würden Sie mit einem guten Detaillierungsgrad entwerfen.
Ich denke, dass Länder und Unternehmen in Ihrem Design wirklich dieselbe Einheit sind wie Städte und Abteilungen. Ich würde die Länder- und Städte-Tabellen (und Cities_Has_Departments) entfernen und bei Bedarf ein Boolesches Flag IsPublicSector zur Unternehmenstabelle hinzufügen (oder eine CompanyType-Spalte, wenn es mehr Auswahlmöglichkeiten als nur Privatsektor / Öffentlicher Sektor gibt).
Ich denke auch, dass bei der Verwendung der Abteilungstabelle ein Fehler aufgetreten ist. Es sieht so aus, als ob die Tabelle "Abteilungen" als Referenz für die verschiedenen Arten von Abteilungen dient, die jede Kundenabteilung haben kann. Wenn ja, sollte es DepartmentTypes heißen. Aber Ihre Kunden (die vermutlich Teilnehmer sind) gehören 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 zu einer Personalabteilung gehört, aber nicht zu welcher!
Mit anderen Worten, Clients sollten mit der Tabelle verknüpft sein, die Sie Divisions_Has_Departments nennen (die ich aber einfach Departments nennen würde). Wenn dies der Fall ist, müssen Sie Städte wie oben beschrieben in Abteilungen zusammenfassen, wenn Sie die standardmäßige referenzielle Integrität in der Datenbank verwenden möchten.
quelle
Ü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 ebenfalls einen Blick wert und ist ein Befehlszeilentool, das im Grunde genommen ein guter Wrapper für das Laden von Daten ist.
quelle
Die meisten Dinge wurden bereits gesagt, aber ich bin der Meinung, dass ich eines hinzufügen kann: Jüngere Entwickler sorgen sich häufig etwas zu sehr um die Leistung, und Ihre Frage zum Verbinden von Tabellen scheint in diese Richtung zu gehen. Dies ist ein Anti-Pattern für die Softwareentwicklung mit dem Namen " Vorzeitige Optimierung" ". Versuche diesen Reflex aus deinem Kopf zu verbannen :)
Noch etwas: Glauben Sie, dass Sie die Tabellen "Städte" und "Länder" wirklich brauchen? Würde es für Ihre Anwendungsfälle nicht ausreichen, eine Spalte "Stadt" und "Land" in der Abteilungstabelle zu haben? Muss Ihre Bewerbung beispielsweise Abteilungen nach Stadt und Stadt nach Land auflisten?
quelle
Folgende Kommentare basieren auf der Rolle als Business Intelligence / Reporting-Spezialist und Strategie- / Planungsmanager:
Ich stimme der obigen Anweisung von Larry zu. IMHO, es ist nicht so sehr ü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 oder einer Abteilungs-Typ-ID versehen. Verwenden Sie die Abteilungstyp-ID und die Abteilungstyp-ID als Referenz für Nachschlagetabellen und interne Berichts- / Analysefelder, um eine langfristige Konsistenz zu gewährleisten.
Die Packs-Tabelle enthält die Spalte "Credit". Sollte dies nicht tatsächlich mit der Client-Basistabelle verknüpft sein? Wenn also viele Packs vorhanden sind, können Sie sehen, wie viel Guthaben für zukünftige Klassen noch übrig ist. Die Anwendung kann sich um die Berechnung kümmern und diese zentral in der Client-Tabelle speichern.
Unternehmensinformationen könnten viel mehr Felder verwenden, einschließlich der offensichtlichen Adresse / Telefon / etc. Information. Ich wäre auch bereit, D & B-Spalten "DUNs" (Site / Branch / Ultimate) langfristig hinzuzufügen. Dun und Bradstreet (D & B) haben einen riesigen Katalog von Unternehmen, und Sie werden später feststellen, dass ihre Informationen sehr hilfreich sind zur Berichterstattung / Analyse. Dadurch wird das von Ihnen erwähnte Problem der Mehrfachaufteilung behoben, und Sie können die Hierarchie für Unterabteilung / Abteilung / Zweige / usw. Aufrollen. von großen Korps.
Sie erwähnen nicht, mit wie vielen Datensätzen Sie arbeiten werden, 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 durchgeführt werden können. Wenn Sie nicht mit einer großen Datenbankzeile (<65000) arbeiten, stellen Sie sicher, dass MS-Access, OpenOffice (Base) oder verwandte Berichts- / App-Entwicklungslö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. Laden Sie sie einfach von ihrer Website herunter.
Zu Ihrer Information - Reporting Insight: Bei großen Datenbanken verfügen Sie normalerweise über zwei Datenbankinstanzen. A) Transaktionsdatenbank zum Aufzeichnen jedes detaillierten Datensatzes. b) Berichtsdatenbank (Data Mart / Data Warehouse) auf einem separaten Computer. Für weitere Informationen suchen Sie in Google nach Star Schema und Snowflake Schema.
Grüße.
quelle
Ich möchte nur auf die Bedenken eingehen, dass das Verbinden mit mehreren Tabellen zu einem Leistungseinbruch führen wird. Haben Sie keine Angst, sich zu normalisieren, da Sie Joins durchführen müssen. Verknüpfungen sind normal und werden in relationalen Datenbanken erwartet. Sie sind so konzipiert, dass sie gut damit umgehen können. 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 mit der Indizierung des FKS beginnen. PKs erhalten im Allgemeinen einen Index für die Erstellung, da sie eindeutig sein müssen. Zwar reduziert das Datawarehouse-Design die Anzahl der Verknüpfungen, 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 (nächtlich oder monatlich oder unabhängig von den 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.
quelle
Es ist nicht überentwickelt, so würde ich das Problem angehen. Der Beitritt ist in Ordnung, es wird keinen großen Leistungseinbruch geben (dies ist unbedingt erforderlich, es sei denn, Sie de-normalisieren die Datenbank, was nicht empfohlen wird!). Überprüfen Sie für Status, ob Sie stattdessen einen Enum-Datentyp verwenden können, um diese Tabelle zu optimieren.
quelle
Ich habe im Bereich Training / Schule gearbeitet und dachte, ich würde darauf hinweisen, dass es im Allgemeinen eine M: 1-Beziehung zwischen dem gibt, was Sie "Sitzungen" (Instanzen eines bestimmten Kurses) nennen, und dem Kurs selbst. Mit anderen Worten, Ihr Katalog bietet den Kurs an ("Spanisch 101" oder was auch immer), aber Sie haben möglicherweise zwei verschiedene Instanzen davon während eines einzelnen Semesters (Tu-Th 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 modelliert haben, aber gehen Sie damit nicht über Bord, bis Sie einige echte Daten haben, die Sie leiten.
quelle
Ein paar Dinge kamen mir in den Sinn:
Die Tische schienen auf Berichterstattung ausgerichtet zu sein, führten aber das Geschäft nicht wirklich. Ich würde denken, wenn sich ein Kunde anmeldet, wird im Wesentlichen eine Bestellung für den Kunden aufgegeben, der an einer Liste von Sitzungen teilnimmt, und diese Bestellung kann für mehrere Mitarbeiter in einem Unternehmen gelten. Es scheint, dass eine "Auftragstabelle" wirklich im Zentrum Ihres Systems steht und Ihre Datenerfassung und eventuelle Berichterstellung vorantreibt. (Vergleichen Sie die Papierdokumente, mit denen Sie das Geschäft betrieben haben, mit Ihrem Datenbankdesign, um festzustellen, ob eine logische Übereinstimmung vorliegt.)
Unternehmen haben oft keine Abteilungen. Mitarbeiter wechseln manchmal Abteilungen / Abteilungen, vielleicht sogar während der Sitzung. Unternehmen fügen manchmal Abteilungen / Abteilungen hinzu / löschen / umbenennen. Stellen Sie sicher, dass die mögliche Änderung der Inhalte Ihrer Tabellen in Echtzeit die spätere Berichterstellung / Gruppierung nicht erschwert. Bei so vielen Kontaktdaten, die auf so viele Tabellen verteilt sind, müssen Sie möglicherweise eine sehr strenge Validierung der Dateneingabe erzwingen, um Ihre Berichte aussagekräftig und umfassend zu halten. Wenn beispielsweise ein neuer Kunde hinzugefügt wird, stellen Sie sicher, dass sein Unternehmen / seine Abteilung / Abteilung / Stadt den gleichen Werten entspricht wie seine Mitarbeiter.
Das "Packs" -Konzept ist überhaupt nicht klar.
Da Sie angeben, dass es sich um ein kleines Unternehmen handelt, wäre es angesichts der Geschwindigkeit und Kapazität der aktuellen Maschinen überraschend, wenn die Leistung ein Problem darstellen würde.
quelle