# Rechnen in Datenbanken - JDBC Mittel der Wahl?



## hausmann (13. Aug 2011)

Hallo Forum,

Meine Frage ist wie man am effizientesten umfangreichere Rechnungen in Datenbanken realisiert.

Etwas genauer:
Stehe mit meinen Java Kenntnissen noch ziemlich am Anfang und bin dabei eine kleine Anwendung (nicht im Web) zu schreiben, die in erster Linie Zahlen in einer Datenbank manipuliert und die Ergebnisse auf der Oberfläche visualisiert. Es gibt in dem Program Zahlen- und Rechenmuster die sich für verschiedene Bereiche wiederholen.
Habe mir dafür in der letzten Zeit die Bausteine zusammengesammelt und ihre Funktionsweise kennengelernt (Graphische Bedienoberflächen, Datenbankanbindung an JavaDB mit JDBC, ein bisschen SQL, JFreeChart).

Problematisch ist das bei vielen Rechnungen andere Tabellen mit betroffen sind, also wenn sich eine Zahl ändert müssen auch mehrere andere Tabellen neu berechnet werden. So ähnlich wie wenn man in Excel mit einem Ergebnis immer weiterarbeitet.

Gibt es Möglichkeiten diese Schritte zu automatisieren, ähnlich wie in Excel? 
Oder ist es nötig für alle Schritte Methoden (mit ResultSets und Statements) zu schreiben die dann jedesmal aufgerufen werden?

Ist es vielleicht sinnvoll die Tabellen(sie sind nicht so umfangreich) in Arrays zu laden, die Berechnung da zu machen und später die Arrays wieder in die Datenbank packen?

Oder gibt es andere effektivere Möglichkeiten diese Problematik zu lösen???

Freue mich über eure Anregungen!
Danke,
hausmann


----------



## Deros (15. Aug 2011)

was heißt in dem Falle Rechnungen in Datenbanken? rufst du tatsächlich JavaKlassen in der Datenbank auf um die berechnungen durchzuführen? Dann würde ich zu Datenbanktriggern greifen.

Schätze aber mal eher du hast ne kleine App mit Oberfläche die ein paar Berechnungen durchführt und dann in der Db nur speichert oder? Dann sollte es doch eigentlich bei sauberer OOP kein Problem sein die Methoden zur aktualisierung der anderen tabellen, nach der Berechnung, aufzurufen oder? 
Ansonsten kannst natürlich auch mit Events arbeiten aber glaube nicht das es nötig wäre...


----------



## hausmann (16. Aug 2011)

Danke für deine Antwort, Deros.

Du hast schon recht, im Augenblick nehme ich die Daten raus aus der Datenbank, rechne mit ihnen, und lege sie dann wieder ab. 

Vielleicht sollte ich die Frage etwas anpassen. Wie ist es möglich mit möglichst wenig Aufwand mehrere Rechnungen mit voneinander abhängigen Ergbnissen zu berechnen.
Auch da kam von dir schon eine Antwort: Saubere OOP.
Das ist natürlich richtig. 
Aber wie geht das am besten innerhalb der Methoden?

Nun hatte ich das bisher mit JDBC Statements probiert, das kam mir mühsam vor und ich war/bin deswegen auf der Suche nach einer Alternative.

Nach ein bischen Recherche bin ich auf ORM (Object-Relational Mapping) gestoßen. Nachdem ich mir dieses (Java Hibernate Tutorial Part 1 - setup - YouTube) sehr gute Tutorial über hibernate angesehen habe glaube ich das dies eine möglichkeit ist mein Problem effektiever zu lösen.

Was meint ihr? 
Gibt es freie Alternativen zu hibernate?
Danke!


----------



## nrg (16. Aug 2011)

also setzt du jetzt auf eine vorhandene DB von einem erp oder ähnlichem auf und möchtest da bestimmte berechnungen für spätere auswertungen ausfühern? dafür nimmst du am besten views und sql reports .

oder ist die DB von deiner applikation selbst? wenn ja, ist es konzepzionell falsch zu sagen: "da ändert sich ein rechnungsbetrag in tabelle a, also muss ich das gesamtergebnis in tabelle b ändern". sowas macht man dann ebenfalls über abhänigkeiten, sichten/statements. am besten programmierst du auch nicht direkt in einem dialect gegen die DB sondern nimmst O/R-Mapper.


----------



## hausmann (16. Aug 2011)

Die DB ist integriert und wird mit der Anwndung erzeugt. 

In einer Tabelle sind z.B. Gewichte von verschiedenen Käsesorten: 
Gouda 7kg
Emmentaler 4 kg
Harzer Rolle 3 kg

In einer anderen sind Wurstsorten:
Salami 1 kg
Bierwurst 3 kg

In einer anderen Tabelle sind jetzt die Summen der Lebensmittel:
Käse 14 kg
Wurst 4 kg

Wenn jetzt 2 kg Bierwurst gegessen werden muss sich auch die Lebensmitteltabelle ändern:
Käse 14 kg
Wurst 2 kg

In meinem Fall gibt es noch mehrere andere Größen die geändert werden müssen wenn sich etwas in der "Wurstsorten" tabelle ändert.

Warum ist das falsch zu sagen das Ergebnisse voneiander abhängen?

Hibernate ist doch ein O/R- Mapper, oder?
Danke.


----------



## XHelp (16. Aug 2011)

Ich hoffe die Summe steht nicht *wirklich* in der Datenbank. Durch eine vernünftige Datenbankstruktur kannst du dir schon jede Menge Sachen sparen. Ich würde alle Lebensmittel in eine Tabelle Packen und mit einer ID angeben, zu welcher Kategorie die gehören. Dann brauchst du auch noch eine Tabelle mit ID der Kategorie > Kategoriename.
Und auf der Lebensmitteltabelle SELECT+SUM+GROUP BY abzufeuern ist eigentlich keine schwarze Magie


----------



## hausmann (16. Aug 2011)

Danke XHelp.
Nein, die Summe steht nicht in der Datenbank. 
Vielleicht war die Summe auch ein schlechtes Beispiel, da die Rechnungen derart sind, das z.B die Spalte einer Tabelle mit einer Spalte aus einer anderen Tabelle multipliziert wird. 
Um doch bei Wurst und Käse zu bleiben:
Alle Lebensmittel haben einen spezifischen Nährwert z.B. kcal/kg. In einer anderen Tabelle oder Spalte möchte ich den gewichtsbezogenen Näherwert, sowohl der Einzelnen Lebensmittel als auch der Gruppen berechnen.
In meinem Fall ist es dann noch so dass der Emmentaler in Holland einen gerigfügig anderen Nährwert als in der Schweiz hat. So gibt es für jedes Land Käse- und Wurstvorräte die unterschiedliche Nährwerte haben. Am ende möchte ich gern ausrechnen wie sich der "Energiehaushalt" der Länder verändert. Also in % und total und per Lebensmittel und per Lebensmittelgruppe.

Daher ist meine eigentliche Frage, wie man das möglichst effizient umsetzt.
Nach meinem jetzigen Stand würde ich es mit Hibernate probieren.


----------



## XHelp (16. Aug 2011)

Warum erklärst du nicht einfach das, was du hast, ohne abstrakte Beispiele?
"Um doch bei Wurst und Käse zu bleiben":
Am Ende möchtest du ausrechnen, wie sich der "Energiehaushalt" verändert.... in Bezug auf was?
Wie sieht denn deine jetztige Tabellenstruktur aus?


----------



## hausmann (16. Aug 2011)

Hm, das sprengt vielleicht etwas den Rahmen. 
Dachte das es vielleicht besser es zu vereinfachen und etwas abstrakter zu beschreiben. 

Ich versuche ins detail zu gehen:

In 5 Ländern werden Lebensmittel gezählt, z.B. in NL, D, AU, CH, P, GB. 
Diese sind in Lebensmittelgruppen unterteilt, z.B. Wurst und Käse

Innerhalb der Gruppen wird neben dem Gewicht auch der (feste)spezifische Nähwert und der Energiegehalt(berechnet aus Gewicht und spezifischem Nähwert) festgehalten. Außerdem muss der Prozentuale Anteil des Energiegehalts am Energiegehalt der ganzen Gruppe für jedes Lebensmittel festgehalten werden.
Der spezifischer Nährwert ist in den Ländern unterschiedlich.

"Gruppe Wurst":
Name, Gewicht,Spezifischer Nähwert, Energiegehalt, Anteil am Totalen Energiegehalt der Gruppe, Anteil des Lebensmittels am totalen Energiegehalt des Landes
Salami, 1, 2, 2, 2/5, 2/26
Bierwurst 3, 1, 3, 3/5, 3/26

"Gruppe Käse":
Name, Gewicht,Spezifischer Nähwert, Energiegehalt, Anteil am Totalen Energiegehalt der Gruppe, Anteil des Lebensmittels am totalen Energiegehalt des Landes
Gouda 7, 2, 14, 14/21, 14/26
Emmentaler 4, 1, 4, 4/21, 4/26
Harzer Rolle 3 ,1 , 3, 3/21, 3/26

Für jedes Land gibt werden dann die Gruppen zusammengefasst:
"Lebensmittel Deutschland" 
Name, Gewicht, Energiegehalt,  Anteil der Lebensmittelgruppen am Totalen Energiegehalt des Landes
Wurst, 4,  5, 5/26, 
Käse, 14, 21, 21/26


----------



## XHelp (16. Aug 2011)

Und in wie fern unterscheidet sich die Beschreibung von der vorherigen?
Die Frage nach der Tabellenstruktur ist nach wie vor offen. Wenn diese mies ist, dann bringt dir auch Hibernate nix


----------



## hausmann (16. Aug 2011)

Als du die Antwort geschrieben hast, bin ich leider noch nicht fertig mit der Beschreibung gewesen.
Aus Versehen auf den "Antworten" Knopf gekommen.

Ich denke aus der Beschreibung wird klar, wie die Tabellen aufgebaut sein können, was deren Inhalte sind, an welchen Stellen gerechnet wird und wo die Abhängigkeiten sind.

Generell führt wohl auch ein gutes Design der DB nicht drum herum alle abhängingen Werte explizit neu zu berechnen.

Werde mich wohl selber noch weiter mit Hibernate beschäftigen um herauszufinden ob und wie das wohl am effizientesten funktioniert.
Wenn ihr dazu noch Anregungen habt freu ich mich.
Danke


----------



## Deros (16. Aug 2011)

alternative zu Hibernate wäre z.b. Eclipse Link, aber ein ORM hilft dir "nur" dabei die Daten in der DB zu speichern. Die neuen Berechnungen musst du halt trotzdem anstoßen und eventl. ein update auf die DB machen.


----------



## hausmann (16. Aug 2011)

Danke Deros.

Ja so sehe ich das inzwischen auch.
Werde mir Eclipse Link mal ansehen.


----------



## maki (16. Aug 2011)

ORM (egal ob EclipseLink, Hibernate oder sonst etwas) nutzen dir nix wenn du nicht wirklich fit in Java & RDBMS bist.


----------



## XHelp (16. Aug 2011)

Der Datenbankaufbau ist immer noch ungünstig, da du irgendwelche Werte, die du eigentlich berechnen sollst, in die Tabellen speicherst. Außerdem beschreibst du immer noch was du im Endeffekt haben möchtest, und zeigst nicht deine jetztigen Tabellen.


----------



## Deros (16. Aug 2011)

ach und zu deiner Datenbankstruktur, da würde doch eine Tabelle reichen:
Name,Typ , Gewicht,Spezifischer Nähwert, Energiegehalt, Anteil am Totalen Energiegehalt der Gruppe, Anteil des Lebensmittels am totalen Energiegehalt des Landes
Salami,Wurst, 1, 2, 2, 2/5, 2/26
Bierwurst, Wurst, 3, 1, 3, 3/5, 3/26
Gouda, Käse, 7, 2, 14, 14/21, 14/26
Emmentaler, Käse, 4, 1, 4, 4/21, 4/26
Harzer Rolle, Käse, 3 ,1 , 3, 3/21,

dazu eine View die mittels einer einfachen where-clause vom Käse und Wurst irgendwas berechnet und fertig ist die geschichte. da kannst dir in der Anwendung praktisch jede logik sparen sondern musst nach dem speichern eines neuen wertes nur die Daten aus der View neu auslesen.


----------



## hausmann (16. Aug 2011)

An alle, danke für eure Anregungen!

@ Xhelp und Deros
Es ist nett das ihr versuchst mir zu helfen, allerdings habe ich bisher noch keine Tabellen. 
Das was ich versuche zu realisieren ist bischen komplizierter als das KäseWurst Beispiel und wie oben schon erwähnt würde das hier den Rahmen sprengen. Ich glaube auch bei der Struktur dafür keine Hilfe zu brauchen.
Es gibt bei mir - zum Glück -  noch kein konkretes Problem mit Tabellen.

Mir ging es um etwas anderes, aber vielleicht habe ich mich nicht klar genug ausgedrückt.
Bisher habe ich mehrere Methoden geschrieben die einige Operationen in Tabellen mit beliebingen Zahlen ausführen. Z.B. die einzelnen Elemente einer Spalte durch deren Summe teilen.
Das habe ich mit JDBC Statements gemacht und mir kam es relativ mühselig vor. Bisher habe ich Tabellen immer nur in Excel genutzt. Daher die Frage ob es etwas einfacher geht. 

Aus euren Antworten schließe ich das es keine einfachere Möglichkeit gibt. 

Die Datenbankstruktur ist ungünstig weil ich berechnete Werte in Tabellen speichere? Wo soll ich sie denn sonst speichern???

Ja, in diesem Fall könnte man alles in eine Tabelle packen, aber dann würde es unübersichtlich. Schließlich hat jedes Land seinen eigenen Nährwert für jedes Lebensmittel. 


@ maki
Es soll Leute geben die Dinge nicht von Anfang an können, sondern versuchen diese zu lernen. Manche von denen neigen dann dazu, Fragen zu stellen obwohl sie die Antworten noch nicht kennen.


----------



## maki (16. Aug 2011)

> @ maki
> Es soll Leute geben die Dinge nicht von Anfang an können, sondern versuchen diese zu lernen. Manche von denen neigen dann dazu, Fragen zu stellen obwohl sie die Antworten noch nicht kennen.


Schon klar dass es solche Leute gibt, denen muss man aber fairerweise auch sagen, dass sie erst krabbeln lernen müssen bevor sie gehen lernen und erst gehen bevor sie rennen lernen 

ORM sind sehr komplex, liegt eben daran, dass man dabei beide Seiten (Java bzw. OOP), RDBMS  und das Mapping an sich verstehen muss.

Da du noch nach Tabellenstrukturen etc,. fragst würde ich dir im Moment glatt von ORM abraten, nicht böse gemeint.


----------



## Deros (16. Aug 2011)

hausmann hat gesagt.:


> Die Datenbankstruktur ist ungünstig weil ich berechnete Werte in Tabellen speichere? Wo soll ich sie denn sonst speichern???



dafür nutzt man dann meistens views, da sie sich automatisch aktualisieren, wenn sich ein Tabellenwert ändert.



hausmann hat gesagt.:


> Ja, in diesem Fall könnte man alles in eine Tabelle packen, aber dann würde es unübersichtlich. Schließlich hat jedes Land seinen eigenen Nährwert für jedes Lebensmittel.


das wäre dann halt ein fk auf eine landesspezifische Tabelle

aber will dir da auch gar nicht reinreden, wenn du da weißt was du machst kein Problem, aber zwischen excel und einer echten db ist halt doch ein deutlicher unterschied. 



hausmann hat gesagt.:


> Bisher habe ich mehrere Methoden geschrieben die einige Operationen in Tabellen mit beliebingen Zahlen ausführen. Z.B. die einzelnen Elemente einer Spalte durch deren Summe teilen.
> Das habe ich mit JDBC Statements gemacht und mir kam es relativ mühselig vor. Bisher habe ich Tabellen immer nur in Excel genutzt. Daher die Frage ob es etwas einfacher geht.
> 
> Aus euren Antworten schließe ich das es keine einfachere Möglichkeit gibt.


wie gesagt die einfachste Möglichkeit wäre es halt die Logik in der db abzubilden, dort kommst du wahrscheinlich mit deutlich weniger Code aus


----------



## XHelp (16. Aug 2011)

hausmann hat gesagt.:


> Ich glaube auch bei der Struktur dafür keine Hilfe zu brauchen.


Nicht böse gemeint, aber nach deinen Vorschlägen bezüglich Käse und Wurst brauchst du da sehr wohl Hilfe... *vorallem* da


> Die Datenbankstruktur ist ungünstig weil ich berechnete Werte in Tabellen speichere? Wo soll ich sie denn sonst speichern???


Öhm, gar nicht. Die berechnest du.


> Ja, in diesem Fall könnte man alles in eine Tabelle packen, aber dann würde es unübersichtlich. Schließlich hat jedes Land seinen eigenen Nährwert für jedes Lebensmittel.


Ne, eine Tabelle ist mies. Alleine beim Käse-Wurst-Beispiel würde ich so um die 4 Tabellen machen. Wenn du sagst, dass dein Beispiel sich deutlich unterscheidet, dann werden da wohl ein paar mehr.


----------



## hausmann (16. Aug 2011)

Hi Leute ich bin wirklich angetan von eurer Motivation anderen zu helfen!!! 
Und das in der Geschwindigkeit!

@ maki:
Kann mir schon vorstellen das es nicht ganz leicht ist. Habe schon verschiedene andere Sachen gelernt, von denen es auch hieß sie sind nicht ganz leicht - ging auch, mal abgesehen von Rechtschreibung
Passt schon, fand den Beitrag nur überhaupt nicht hilfreich.

@ Deros
Danke für den Hinweis mit den Views, das ist neu für mich und bringt mich weiter.
Die schaue ich mir genauer an.

Zitat: hausmann	
"Ja, in diesem Fall könnte man alles in eine Tabelle packen, aber dann würde es unübersichtlich. Schließlich hat jedes Land seinen eigenen Nährwert für jedes Lebensmittel. "

Zitat: Deros
"das wäre dann halt ein fk auf eine landesspezifische Tabelle"

Genau, und so hätte man mehr als nur eine Tabelle.
Die totalen Energiegehalte für die einzelnen Lebensmittel sind dann auch Länderabhängig, daher denke ich das es sinnvoll ist zumindest für jedes Land eine eigene Tabelle zu erstellen.
Oder eben Views zu nutzen. Mal sehen.


----------



## maki (16. Aug 2011)

> @ maki:
> Kann mir schon vorstellen das es nicht ganz leicht ist. Habe schon verschiedene andere Sachen gelernt, von denen es auch hieß sie sind nicht ganz leicht - ging auch, mal abgesehen von Rechtschreibung
> Passt schon, fand den Beitrag nur überhaupt nicht hilfreich.


Dass du den Beitrag nicht hilfreich fandest liegt nur an dir, bei deinem Wissenstand wäre eine grundlegende Einführung in RDBMS wohl am besten, da brauchst du gar nicht erst an ORM zu denken.


----------



## hausmann (16. Aug 2011)

Mei, ist ja fast Chatten hier.



XHelp hat gesagt.:


> Öhm, gar nicht. Die berechnest du.



Ja aber mein Ziel ist doch die berechneten Werte wieder in die Datenbank zu bekommen!?



XHelp hat gesagt.:


> Ne, eine Tabelle ist mies. Alleine beim Käse-Wurst-Beispiel würde ich so um die 4 Tabellen machen. Wenn du sagst, dass dein Beispiel sich deutlich unterscheidet, dann werden da wohl ein paar mehr.



Genau! So sehe ich das auch, deswegen habe ich auf Deros Vorschlag mit "könnte" geantwortet. Ich denke eine einzige Tabelle würde alle Abfragen sehr kompliziert machen.


----------



## XHelp (16. Aug 2011)

hausmann hat gesagt.:


> Ja aber mein Ziel ist doch die berechneten Werte wieder in die Datenbank zu bekommen!?



Wozu? Meinst du deine Anwendung wird so mächtig, dass die ohne Caching nicht auskommt?


----------



## hausmann (16. Aug 2011)

Der Anwender sollte zu einem späteren Zeitpunkt mit den schon berechneten Werten weiterarbeiten können.


----------



## XHelp (16. Aug 2011)

Können die doch... heißt aber nicht, dass du die Ergebnisse gespeichert werden müssen. Nicht umsonst gibst es SUM, COUNT, MIN, MAX, AVG und was sonst nicht noch alles in SQL


----------



## hausmann (16. Aug 2011)

Hm. Aber wenn das Program geschlossen wird dann ist doch alles weg wenn es nicht gespreichert wird.
Da helfen doch auch die Rechenfunktionen in der SQL nichts, oder??????:L


----------



## XHelp (16. Aug 2011)

??? Wenn du die Wert 4,5,6 in der Datenbank hast, kannst du jeder Zeit die Summe (4+5+6) 15 herzaubern OHNE die gespeichert zu halten.

Naja, mach erstmal wie du denkst und schau wie weit du kommst.


----------



## hausmann (17. Aug 2011)

Hi, bin gerade auf Trigger gestoßen.
Das ist genau das was ich suchte:

Datenbanktrigger ? Wikipedia


----------



## Deros (17. Aug 2011)

*haut den kopf auf den tisch* steht das nicht schon im ersten posting von mir....


----------



## hausmann (18. Aug 2011)

Oh, tu dir nicht weh.
Hab ich übersehen:autsch:

Danke!!!

Bin jetzt auch auf PL/SQL gestoßen, und werde wohl darauf umsteigen.
PL/SQL ? Wikipedia

Ich glaube mit Triggern und den Möglichkeiten (Schleifen und Bedingungen) die damit gegeben sind, kann das ganze Problem auf Datenbankebene mit verhältnismäßig geringem Aufwand gelöst werden. 
In Java muss ich mich darum dann nicht mehr kümmern.


----------



## JohannisderKaeufer (18. Aug 2011)

Ein anderes Beispiel bezüglich berechneter Werte: Nehmen wir an du hättest eine Tabelle Personen mit Name und Geburtsdatum

Name: Hans, Geburtsdatum: 1.1.93,

und du würdest eine Altersverifikation machen wollen. Sprich Personen unter/ab 18.

Dann hättest du irgendwann gerne eine Tabelle die so aussieht.

Name: Hans, Geburtsdatum: 1.1.93, Über 18: true

Damit hast du allerdings das Problem dass du jeden Tag die momentan als unter 18 gekennzeichnet sind durchgehen mußt um zu überprüfen ob sie nun 18 sind und das dann in der DB festhalten.

Eine Abfrage sieht dann so aus

select name from people where over_18 = true;

Das ganze ist allerdings etwas blödsinnig, da du erstmal das Programm schreiben mußt dass dir täglich das Flag richtig setzt.

Vernünftigerweise würde ich hingehen und bei der Tabelle mit Name und Geb.Datum bleiben.

Eine Abfrage würde dann so aussehen.

select name from people where birthdate + 18years before "today";

Wenn sich nun herausstellt, daß die Abfrage zu kompliziert ist kann man dafür einen View erstellen

create view people_over_18 as select name from people where birthdate + 18years before "today";

Eine abfrage würde nun so aussehen

select * from people_over_18;

Zusammengefasst bei einem typischen Datenbankdesign nach Lehrbuch, haben berechnete Werte nichts in Tabellen zu suchen, sondern gehören nötigenfalls in Views.


----------



## hausmann (19. Aug 2011)

Danke für dein Beispiel.

Stimme dir da volkommen zu.

Allerdings handelt es sich bei dem was ich versuche umzusetzen nicht um eine typische Datenbank.
Ich missbrauche eine DB um ein mehr oder weniger dynamisches Modell zu erzeugen.

Bis jetzt habe ich das immer mit Excel und VBA gemacht. Da ging das gut. Jetzt soll das ganze aber mehrsprachig werden und um Elemente erweitert die mit VBA nicht mehr ohne weiteres zu machen sind.


----------

