java -> array in db

Hallo zusammen,

ich habe sehr viele Datensätze verschiedener Länge, die ich in Tabellen speichern will.
Meine Hauptanforderung ist:
Auf die Daten der Tabellen will ich sehr schnell zugreifen können.

Die Daten möchte ich in Java später verarbeiten können um z.B. x-y-Diagramme erzeugen zu können.

Bisher habe ich eine Tabelle mit einer Spalte für die Id erzeugt und jeweils mit

"ALTER TABLE x[size=84][color=#2a00ff][size=84][color=#2a00ff] ADD COLUMN y[/color][/size][/color][/size][size=84][color=#2a00ff][size=84][color=#2a00ff] character varying(50)"[/color][/size][/color][/size]

[/color][/size][/color][/size]Spalten hinzugefügt und mit

[LEFT]try[size=84] {[/size]
[size=84]String strStatement = [/size][size=84][color=#2a00ff][size=84][color=#2a00ff][size=84][color=#2a00ff][size=84][color=#2a00ff]"UPDATE x[/color][/size][/color][/size][size=84][color=#2a00ff][size=84][color=#2a00ff] SET y[/color][/size][/color][/size][size=84][color=#2a00ff][size=84][color=#2a00ff]=? WHERE z=?;"[/color][/size][/color][/size][/color][/size][/color][/size][size=84];[/size][/LEFT]
[size=84][color=#0000c0][size=84][color=#0000c0][size=84]PreparedStatement [/size]pState[/color][/size][/color][/size][size=84] = [/size][size=84][color=#0000c0][size=84][color=#0000c0]verb[/color][/size][/color][/size][size=84].prepareStatement( strStatement );[/size]
[size=84][color=#0000c0][size=84][color=#0000c0]pState[/color][/size][/color][/size][size=84].setInt( 1, "EinString" );[/size]
[size=84][size=84][color=#0000c0][size=84][color=#0000c0]pState[/color][/size][/color][/size][size=84].setString( 2, [Id] );[/size]
[size=84][size=84][color=#0000c0][size=84][color=#0000c0]pState[/color][/size][/color][/size][size=84].executeUpdate();[/size]
[/size]}[/size]

[LEFT]die Werte eingetragen. Nur leider dauert das sehr lange. :angry:
Darum hatte ich überlegt, die Spalten jeweils als Array an die Db zu übergeben. Ist das möglich? Und wenn ja, wie?[/LEFT]

[LEFT]Oder gibt es - außerhalb der Db-Welt - noch anderer Möglichkeiten, die Daten so zu speichern, dass man sie später in einem Tabellenkalkulationsprogramm in der Form
Spaltenname
Wert1
Wert2

verarbeiten und daraus x-y-Diagramme zeichnen lassen kann?
Ich hatte schon mit XML rumgespielt, aber auch dort hat das Speichern relativ lange gedauert.
Wie schnell wäre den eine direkte Anbindung und Speicherung an/in einem
Tabellenkalkulationsprogramm ( OpenOffice / Excel )?[/LEFT]

[LEFT]Gruß
Thoogr[/LEFT]

Generell solltest du dich mit Normalisierung von Datenbanken beschäftigen. Das würde dir eine Menge Performance bringen.

Zum anderen: warum tust du für immer die gleiche UPDATE Anweisung das Prepared Statement jedesmal neu vorbereiten? Es genügt, das einmalig vorzubereiten und dann immer bloß mit Daten aufzufüllen.

Und letztendlich, da wir schon bei Performance sind: hast du deine Datenbank konfiguriert oder läuft die mit den Voreinstellungen?

was meinst du mit “verschiedener Länge” ?

das wollen wir alle :slight_smile:

das ist ja schonmal kein unvernünftiger Ansatz. java.sql.PreparedStatement hat eine setArray(…) methode - die hat 2 argumente:

  1. der index der Array-Spalte

  2. ein java.sql.Array Objekt. Das ist ein Interface-Typ - da würde ich dir empfehlen nachzuschauen, wie man bei dem PGJdbc-Treiber mit umgeht (habs selbst noch nie gebraucht)

  3. koenntest du deine Zahlen Werte auch ganz pragmatisch als String einem Text-Feld übergeben (z.B. durch | getrennt) und dann in einer Trigger-Funktion splitten - und entsprechend verarbeiten.

Die Langsamkeit - hast du ja bereits erkannt - scheint daher zu rühren, dass du jedes Element eines Vektors einzeln speicherst. Du könntest hier sogar noch einen Schritt weiter gehen und nicht nur Vektor-Weise die Daten schreiben - sondern vielleicht in geeigneten Packchen mehrere Vektoren zusammenfassen - vielleicht als so einen String - jeder Vector eine Zeile - das laesst sich in Pq/SQL sehr easy parsen - das nadelöhr ist die latenz der abfrage - nicht das bisschen konvertieren - es gilt also so wenig abfragen wie moeglich zu erzeugen

gruss


[nachtrag]
vielleicht lohnt es sich für dich ja auch mal PostGIS anzuschauen - ich habe so das gefühl, dass sich diese Erweiterung nicht nur für GIS eignet … da wäre aber wohl Gisman der richtigere dies abzuschaetzen

Danke erstmal für die schnellen Antworten.

Generell solltest du dich mit Normalisierung von Datenbanken beschäftigen. Das würde dir eine Menge Performance bringen.

ich glaube, das bringt nicht viel, da die Werte-Paare der Spalten einer Zeile sehr verschieden sind

Zum anderen: warum tust du für immer die gleiche UPDATE Anweisung das Prepared Statement jedesmal neu vorbereiten? Es genügt, das einmalig vorzubereiten und dann immer bloß mit Daten aufzufüllen.

ich hatte den Code schnell so zusammengestellt, um mein grundsätzliches Vorgehen darzustellen.
eigentlich sieht es eher so aus

[size=84]String strStatement = [size=84][color=#2a00ff][size=84][color=#2a00ff][size=84][color=#2a00ff][size=84][color=#2a00ff]"UPDATE x[/color][/size][/color][/size][size=84][color=#2a00ff][size=84][color=#2a00ff] SET y[/color][/size][/color][/size][size=84][color=#2a00ff][size=84][color=#2a00ff]=? WHERE z=?;"[/color][/size][/color][/size][/color][/size][/color][/size][size=84];[/size][/size][size=84]
[LEFT][/size][size=84][color=#0000c0][size=84][color=#0000c0]pState[/color][/size][/color][/size][size=84] = [/size][size=84][color=#0000c0][size=84][color=#0000c0]verb[/color][/size][/color][/size][size=84].prepareStatement( strStatement );[/size][/LEFT]
[size=84]//...[/size]
[size=84]ArrayList<String> liste = [/size][B][size=84][color=#7f0055][size=84][color=#7f0055]new[/color][/size][/color][/size][/B][size=84] ArrayList<String>();[/size]
[size=84]//... liste füllen[/size]
[B][size=84][color=#7f0055][size=84][color=#7f0055]for[/color][/size][/color][/size][/B][size=84] ( [/size][B][size=84][color=#7f0055][size=84][color=#7f0055]int[/color][/size][/color][/size][/B][size=84] i = 0; i < liste.size(); i++ ) {[/size]
[size=84][color=#0000c0]  pState[/color][size=84].setString( 1, liste.get(i) );[/size]
[size=84][size=84][color=#0000c0][size=84][color=#0000c0]  pState[/color][/size][/color][/size][size=84].setInt( 2, [Id] );[/size]
[size=84][size=84][color=#0000c0][size=84][color=#0000c0]  pState[/color][/size][/color][/size][size=84].executeUpdate();[/size]
[/size][/size][/size][size=84]}[/size]



Und letztendlich, da wir schon bei Performance sind: hast du deine Datenbank konfiguriert oder läuft die mit den Voreinstellungen?

die läuft mit den Voreinstellungen. Aber was würde denn eine Konfiguration bringen?

was meinst du mit “verschiedener Länge” ?

mal sind es 100 Daten, mal 500, mal 3000, mal 10000; und das nur bei diesem Datensatz. Bei anderen könnten es auch noch mehr sein. Außerdem sind es auch manchmal Vektoren, bei denen ich auch den Betrag errechne, wodurch allein schon vier Spalten entstehen. Ok, das könnte man dann zumindest als Array speichern und würde statt jeweils 4 nur jeweils 1 Db-Zugriff brauchen

das ist ja schonmal kein unvernünftiger Ansatz.

Lt. pg-Handbuch ( 8.11.5 -> Tip ) hat man schon beim Design der Db was falschgemacht, wenn man Arrays speichern will.
Ansonsten hatte ich mich schon mit setArray beschäftigt, aber es nicht hinbekommen. Hat da wer nen Tipp?

  1. koenntest du deine Zahlen Werte auch ganz pragmatisch als String einem Text-Feld übergeben (z.B. durch | getrennt) und dann in einer Trigger-Funktion splitten - und entsprechend verarbeiten.

Das würde wohl leider an der max. Länge des String scheitern. Bei 3000 Daten, die jeweils 10 Zeichen beinhalten können, reicht ein String glaube ich nicht aus; und wie gesagt: es können auch noch mehr Daten sein.

Du könntest hier sogar noch einen Schritt weiter gehen und nicht nur Vektor-Weise die Daten schreiben - sondern vielleicht in geeigneten Packchen mehrere Vektoren zusammenfassen

Das hatte ich mir auch schon überlegt. Nur das Nadelöhrs sind eigentlich die Zeilen, weniger die Spalten. ( Zeilen bis zu 10000, Spalten ~10 )

Gruß
Thoogr

Nun, was du da machst, ist ein Verbrechen an jeder relationalen Datenbank. Kein Wunder, dass das langsam ist.


die läuft mit den Voreinstellungen. Aber was würde denn eine Konfiguration bringen?

Mehrere Hundert Prozent Performance?

Tut mit leid; Aber eigentlich suche ich nur eine Möglichkeit, die Daten strukturiert abzulegen und möglichst einfach wieder darauf zuzugreifen. Hast Du da vielleicht eine Idee, was man als Alternative zu einer Db nehmen könnte?
Wie gesagt: XML hab ich schon ausprobiert.
Und Tabellenkalkulation würde wohl nur gehen, wenn man viele Tabellen erzeugt; dadurch erschwert sich aber eine Verdichtung der Daten. Man müßte also auf mehrere Tabellen zugreifen und da erscheint mir eine Db effektiver.

Kennst Du da eine gute Anleitung?

Gruß
Thoogr

Genau das erreichst du, wenn du dich etwas mit Normalisierung beschäftigst. Dafür sind relationale Datenbanken gedacht, du musst nur deine Daten daran ausrichten.



Kennst Du da eine gute Anleitung?

Ja, siehe meine Signatur.