lg-regensburg / SWert

0 stars 0 forks source link

Datenverwaltung umstellen (DB-basierte Lösung) #33

Open geritwagner opened 10 years ago

bof64665 commented 10 years ago

Umstellung der Datenverwaltung auf eine DB-basierte Lösung ist nur mit einem Trade-Off möglich: die Datenbank kann nicht in die JAR-Datei gepackt werden, da dann keine Updates auf der DB mehr möglich sind

geritwagner commented 10 years ago

Wenn wir eine DB-basierte Lösung umsetzen wollen, müssten wir die Datenbank installieren/einrichten. Das wäre m.E. über einen relativ aufwendigen Packaging- & Build-Prozess möglich (z.B. Apache Ant oder Maven). Eine weitere Option wäre das Hibernate-Framework - m.E. würde es sich anbieten, das Framework mal zu testen, um herauszufinden, wie gut und wie effizient wir unsere Anforderungen damit erfüllen können. Vielleicht finden sich ja brauchbare Tutorials.

bof64665 commented 9 years ago

Das Hibernate-Framework finde ich grundsätzlich einen guten Vorschlag. Ich habe zwar noch nie persönlich damit gearbeitet, aber würde es gerne mal ausprobieren ;) Aber Hibernate behebt ja das Problem des Packaging- und Build-Prozesses nicht direkt oder? Weil Hibernate im Hintergrund ja trotzdem eine Datenbank (z.B. MySQL) nutzt und nur die Arbeit damit extrem erleichtert. Aber das Problem mit den read-only JARs bleibt m.E. trotzdem bestehen. Auch mit Hibernate dürfte es nicht möglich sein, in eine Datenbank zu schreiben, die mit in der JAR gepackt ist.

bof64665 commented 9 years ago

Nach einiger Recherche steh ich aktuell da, dass es nicht möglich ist, über welche Umwege auch immer, in einen JAR-File zu schreiben. Also können wir die Datenbank definitiv nicht da rein packen. Einzige Möglichkeit wäre, beim Programmstart zu prüfen, ob die DB auf dem Rechner vorhanden ist. Wenn nicht wird sie über ein init-Script an einen wenig frequentierten Ort auf dem Rechner geschrieben und dort persistiert. Scheint mir aktuell der einzige Weg, den wir gehen könnten, um unsere Datenverwaltung mit Hilfe einer DB umzubauen. Eure Meinung?

geritwagner commented 9 years ago

Hört sich ganz gut an - wir könnten das ja mal i.S.v. rapid prototyping testen. M.E. würde sich SQLite anbieten: serverless/no dependencies, light-weight, zero-configuration, cross-plattform und seit v3 auch mit UTF-8 Unterstützung (Overview & Tutorial). Den Ordner könnten wir ins Home-Verzeichnis legen (z.B. ".swert" - scheint eine gängige Konvention zu sein, u.A. auch von Jabref so implementiert).

bof64665 commented 9 years ago

Meines Erachtens, wäre eventuell H2 sogar besser geeignet, da SQLite in C aufgesetzt ist somit eine gewisse Plattformabhängigkeit in das Projekt mit reinkäme. H2 ist java-basiert und wir somit keine neuen Abhängigkeiten mit einbauen.

geritwagner commented 9 years ago

Stimmt. Ich habe mal aus einem Tutorial ein H2-Beispiel in den Branch eingestellt. Das scheint recht gut zu funktionieren - was haltet ihr davon? Sollten wir vor der implementierung evtl. noch das DB-Schema und die Einbettung in die Klassenstruktur besprechen?

bof64665 commented 9 years ago

Ich finde die Umsetzung mit einer H2-DB auch recht praktikabel. Das Schema dürfte wohl nicht allzu kompliziert sein, aber vor der Umsetzung bin ich auch dafür, wir das Schema sowie Einbettung und Integration mit den Models wohl noch genauer mal durchsprechen. Ich hab als Diskussionsgrundlage mal eine Schema beigefügt, welches m.E. eigentlich schon fast ausreichen müsste für unsere Anforderungen. unbenannt

geritwagner commented 9 years ago

Ich würde vorschlagen, ein paar Attribute nicht in die DB zu schreiben - damit könnten wir Inkonsistenzen verhindern. SlopeFaktor und anaerobeSchwelle ergeben sich aus den selektierten Leistungen und geschwindigkeit aus zeit und laenge. Die "berechneten" Attribute könnten dann auf Applikationsebene umgesetzt werden. Wenn wir das DB-Schema entwerfen könnten wir gleichzeitig überlegen/antizipieren, ob wir in Zukunft weitere Daten speichern wollen, z.B. athletenbezogen (frei wählbare Streckenlängen #21, Trainingspläne) oder applikationsbezogen (aktiviertes Tab beim Neustarten, Versionsnummer für Upgrades). Bzgl. der Applikation wäre im Hinblick auf unser Data-Model zu überlegen, ob wir mit einer Data Access Layer (und Data Access Objects) arbeiten sollen. Außerdem könnten wir beim Programmstart die Athleten aus der DB automatisch öffnen und die Benutzerführung dementsprechend umstellen.

d7fc564a-0ced-11e4-8adb-62d5799dd24f

bof64665 commented 9 years ago

Ja, es wäre durchaus sinnvoll, solch athleten- und applikationsbezogene Infos auch mit in der DB zu speichern. Ich würde aber vorschlagen, dass wir uns da mal treffen und das Schema usw. festlegen.

geritwagner commented 9 years ago

t.b.d.:

geritwagner commented 9 years ago

evtl. für import/export nützlich: https://github.com/kennethreitz/tablib

bof64665 commented 9 years ago

Habe mich eben etwas mit den Möglichkeiten für die Versionierung der Datenbank beschäftigt. Ist wohl ein sehr bekanntes, aber noch nicht wirklich gut gelöstest Problem. Für unseren, doch recht einfachen Fall, hätte ich mir folgende Lösung zurecht gelegt: Im Projekt liegen immer zwei .sql-Dateien (project-db.sql & updates-db.sql). Das Datenbank-Schema beinhaltet eine Tabelle "Config", in der die aktuellen Version X der Datenbank gespeichert ist. Mit der Datei project-db.sql kann eine komplett neue Datenbank (falls diese noch nicht vorhanden ist) der Version X installiert werden. In der Datei updates-db.sql werden alle Änderungen gespeichert, die die Datenbank der Version X-1 von der aktuellen Version X unterscheiden. Somit muss die Applikation am Anfang nur die Version der Datenbank prüfen und entsprechend einem der folgenden Fälle reagieren: 1) Es ist keine Datenbank vorhanden --> Die Datei project-db.sql wird ausgeführt. 2) Es ist eine Datenbank der Version X-1 vorhanden --> Die Datei updates-db.sql wird zum Updaten der Datenbank ausgeführt. 3) Es ist eine Datenbank der Version X vorhanden --> Keine Handlung nötig.

Zwei Nachteile hat das Ganze aber: 1) Wir schlittern in Probleme bei noch älteren Versionen der Datenbank (z.B. X-2). Da wissen weiß die Applikation dann nicht, welche Änderungen auf der DB durchzuführen sind. 2) Die Änderungen, die für die Datenbank entwickelt werden, müssen in beide Dateien eingebaut werden und sind somit etwas inkonsistent. Dabei darf kein Fehler unterlaufen, da sonst unterschiedliche Schemata ausgerollt werden.

geritwagner commented 9 years ago

Ich hätte mir das so vorgestellt:

switch(db_version_existing)
  default: 
    if(db_version_needed<db_version_existing)
      notify_user_to_update_application();
      break;
    else
      if(not_exists(schema))
        install_schema_version_1();
  case 2: 
    incremental_updates_from_version_1_to_version_2();
  case 3:
    incremental_updates_from_version_2_to_version_3();
  ...

d.h. ich würde nur ein vollständiges Schema (version 1) verwenden und den Rest über inkrementelle Updates machen. Was haltet ihr von der Version?

bof64665 commented 9 years ago

Find ich auch gut, grundsätzlich auch besser als mein Vorschlag ;) Kannst du mich trotzdem kurz aufklären, was du als db-version bezeichnest und was als application-version? Was bezeichnet die Version der DB, die der User evtl. schon hat und welche ist diejenige, die eigentlich benötigt wird?

geritwagner commented 9 years ago

Stimmt - das war nicht klar. Ich würde die Variablen umbenennen: db_version_needed sollte die Version der Datenbank beschreiben, die die Applikation bräuchte, db_version_existing die aktuell vorhandene.

bof64665 commented 9 years ago

Das macht die Sache klarer ^^ Aber dann müsste doch geprüft werden, ob nicht die db_version_needed GRÖßER als die db_version_existing ist, oder?

geritwagner commented 9 years ago

Der erste Pfad beschreibt doch den Fall, wenn die Applikation hinter der Datenbankversion zurückliegt, d.h. db_version_needed<db_version_existing, in dem Fall müsste die Applikation aktualisiert werden... andernfalls (deshalb ohne break) würden wir in die update pfade reinlaufen.

bof64665 commented 9 years ago

Ich habe das etwas abgeändert umgesetzt. Ich lade mal eben im issue#33 - Branch einen lauffähigen Zwischen-Commit hoch. In der Klasse DBVerbindung könnt ihr euch ansehen, wie die Update-Funktion aktuell umgesetzt ist und ob ihr das ändern würdet.

bof64665 commented 9 years ago

Die Datenbank ist soweit incl. entsprechender Tests fertig. Wir müssen jetzt das gesamte Datenhandling innerhalb der Applikation auf die DB umstellen. Dafür würde ich vorschlagen, dass wir uns wieder mal treffen, weil ich aktuell den Datenfluss innerhalb der Anwendung noch nicht ganz nachvollziehen kann.

bof64665 commented 9 years ago

Entsprechend unseren Absprachen am 25.9 hier nochmal eine Liste mit den noch umzusetzenden Schritten zur Umstellung der Datenverwaltung: 1) Anpassung des DB-Schemas (zusätzliche Boolean-Spalte für Athleten --> Geöffnet) 2) Erstellen von 2 Dummy-Athleten in der DB zu Testzwecken 3) Anpassung des ID-Handlings 4) Laden der Athletenliste aus der DB und Anzeige derselben als Tabelle im Starttab 5) Umsetzung von Methoden zum Ändern der Spalte aus 1) 6) Optimierung der Athletenliste aus 4) --> auswählbare Athleten, Öffnen der zuletzt geöffneten Athleten in eigenen Tabs (Anpassung des Observers) 7) Speichern neuer Athleten 8) Speichern von Änderungen (z.B. Leistungen mit zusätzlichem Attribut versehen, um feststellen zu können, ob sie verändert wurden).