# Allgemeine Frage zu Datenbanklimits



## Guest (11. Jul 2008)

Hallo Leute,

meine Aufgabe besteht darin eine Matrix mit den Ausmaßen 8000 x 8000 zu berechnen. Da Access nur 255 Spalten zulässt bin ich auf die H2 DB umgestiegen. Nur leider wird mir ab ca. 740 Spalten ein Java Heap Space Error um die Ohren geschmissen.
Demnächst werde ich versuche diese Datenmenge in mehrere Tabellen zu splitten und dann mittels eines Views diese wieder zusammenzufügen (Muss leider wegen dem Algorithmus gemacht werden). Zuvor habe ich Google wieder strapaziert und auf diversen Seiten gelesen, dass ein SQL View eine Begrenzung von 5000 Spalten hat. Somit würde das splitten ja auch nicht ganz zum Ziel führen.

Daher meine Frage: Gibt es eine generelle Beschränkung von Spalten in Datenbanken? Und wie könnte man so eine große Datenmenge organisiert am besten speichern?

Vielen Dank im Voraus!

Grüße

Kuba


----------



## SlaterB (11. Jul 2008)

z.B. als Textdatei oder einen großen String in der DB,
das kannst du doch genausogut im Programm in 8000-Teile aufspalten,
wieso diesen unendlichen Overhead?
es sei denn natürlich, du willst irgendwelche DB-Berechnungen drauf loslassen


----------



## AlArenal (11. Jul 2008)

Die jeweiligen Grenzen kann man der Dokumentation der eingesetzten RDBMS entnehmen. Hier gibt es ebenso Limits, wie überall, beispielsweise in Dateisystemen (Anzahl Dateien pro Partition, max Größe von Dateien, ...).

Ohne deinen speziellen Anwendungsfall zu kennen, kann man aber wohl schonmal sagen, dass es grundsätzlich keine gute Idee ist derartige Strukturen 1:1 auf einer Datenbanktabelle abbilden zu wollen.

Es würde auch keiner auf die Idee kommen eine SQL-Datenbank eine dritte Dimension verpassen zu wollen, um darin ein Klimamodell abzubilden.. oder gleich noch eine vierte Dimension, um den zeitlich Verlauf...


----------



## AlArenal (11. Jul 2008)

SlaterB hat gesagt.:
			
		

> z.B. als Textdatei oder einen großen String in der DB,
> das kannst du doch genausogut im Programm in 8000-Teile aufspalten,
> wieso diesen unendlichen Overhead?
> es sei denn natürlich, du willst irgendwelche DB-Berechnungen drauf loslassen



PostgreSQL und andere RDBMS lassen sich auch um eigene Datentypen erweitern, man muss also nicht zwingend auf der String-/BLOB-Serialisierungs-Krücke laufen.


----------



## SlaterB (11. Jul 2008)

eine Standard-DB-Tabelle ist im Grunde auch nur eine Serialisierungs-Krücke,
die eben gewisse DB-Operationen erlaubt


----------



## AlArenal (11. Jul 2008)

Jetzt wird es philosophisch


----------



## Guest (11. Jul 2008)

Dankeschön für die schnelle Antwort!

Die Aufgabe ist die Programmierung einer Clusteranalyse. Und dabei wird eine Matrix benötigt, die so groß ist, wie das Quadrat der zu berechnenden Objekte. (Bei 8000 Objekte eben 8000 x 8000)

Also zu den Limits steht bei der H2Database folgendes: 



> There is no limit for the following entities, except the memory and storage capacity: maximum identifier length, maximum number of tables, maximum number of columns, maximum number of indexes, maximum number of parameters, maximum number of triggers, and maximum number of other database objects.



Ist zwar nicht sehr konkret, aber gut. Natürlich hängt es auch davon ab, was man in die einzelnen Zellen speichert. 
Die Idee mit den Textfiles habe ich auch schon umgesetzt. Nur dauert das doch noch etwas länger. Auch die Umsetzung in VBA habe ich gewagt. Leider ist in Excel und Access eben diese Begrenzung. 
Excel 2007 hat 16000 Spalten und über 1 Mio. Zeilen. Theoretisch würde das sogar passen, wenn Excel 07 mir nicht den Fehler bringt, dass die Berechnungen mit den vorhandenen Ressourcen nicht zu bewerkstelligen ist (*lol* bei 2 Gig Arbeitsspeicher und einem Dual-Core 2,5 gig).

Dann werde ich eben versuchen diesen Datenwust irgendwie aufzuteilen und dann mit einem lustigen Algorithmus die nötigen Zahlen zusammenschustern.

Grüße

Kuba


----------



## byte (11. Jul 2008)

> Nur leider wird mir ab ca. 740 Spalten ein Java Heap Space Error um die Ohren geschmissen.


Hast Du denn mal die Heap Size erhöht?
Wenns Dir nur ums Speichern der Matrix geht, würde ich keine DB benutzen.


----------



## Guest (11. Jul 2008)

> > Nur leider wird mir ab ca. 740 Spalten ein Java Heap Space Error um die Ohren geschmissen.
> 
> 
> Hast Du denn mal die Heap Size erhöht?
> Wenns Dir nur ums Speichern der Matrix geht, würde ich keine DB benutzen.



Heap Size erhöhen würde ja nur etwas für die VM bringen. Das Problem wird dann sein, dass die DB so groß wird, dass es sehr lange dauert bis eine Zeile oder eine bestimmte Zelle ausgelesen wird.
Meine Idee ist nun, dass ich die Daten in einzelne Tabellen zu je 100 Spalten speichere. Dann weiß ich sofort, dass z.B. die 1000 - 1099. Spalte in Tabelle 10 liegt. Ausgestattet mit einem Primary Key sollte dann auch die Konsistenz gewährleistet sein.
Der Zugriff sollte damit auch schneller gehen. Wird von der Programmierlogik etwas kompliziert, sollte aber zu schaffen sein. Mal sehen.

Aber vielen Dank für die Anregung! ;-)

Gruß

Kuba


----------



## AlArenal (11. Jul 2008)

Bist du dir sicher, dass es überhaupt sinnvoll ist hier eine RDBMS einzusetzen? Ich habe da mehr als starke Zweifel...


----------



## Siassei (11. Jul 2008)

Hallo,

wieso nimmst du nicht MySQL für eine derartige Aufgabe? Eine MyISAM-Tabelle oder ne Inno-DB sollte  eine derartige Aufgabe bewältigen können. Natürlich muss der Algorithmus auf der DB-Seite ausgeführt werden-> dein Java-Programm wartet nur auf die Lösung  :wink: Die MyISAM-Tabelle kannst du vielleicht noch mit einer Memory-Tabelle koppeln und darin die Berechnungen durchführen und 4TB bei Win+NTFS sollten ausreichen, oder? Na, vielleicht aber auch nicht  :wink: 

Tabellengröße
MyISAM


----------



## AlArenal (11. Jul 2008)

Siassei hat gesagt.:
			
		

> Hallo,
> 
> wieso nimmst du nicht MySQL für eine derartige Aufgabe? Eine MyISAM-Tabelle oder ne Inno-DB sollte  eine derartige Aufgabe bewältigen können.



Nein, sollten sie nicht. InnoDB macht z.B. bei 1000 Spalten dicht. Andere limitierende Faktoren sind die Zeilengröße exkl. BLOB, TEXT und STRING.

In einer halbwegs  normalisierten Datenbank sollte ein solches Limit aber auch nie erreicht werden.

http://dev.mysql.com/doc/refman/5.0/en/column-count-limit.html


----------



## Guest (11. Jul 2008)

> Hallo,
> 
> wieso nimmst du nicht MySQL für eine derartige Aufgabe? Eine MyISAM-Tabelle oder ne Inno-DB sollte eine derartige Aufgabe bewältigen können. Natürlich muss der Algorithmus auf der DB-Seite ausgeführt werden-> dein Java-Programm wartet nur auf die Lösung  :wink:  Die MyISAM-Tabelle kannst du vielleicht noch mit einer Memory-Tabelle koppeln und darin die Berechnungen durchführen und 4TB bei Win+NTFS sollten ausreichen, oder? Na, vielleicht aber auch nicht  :wink:



Ok, zugegeben kenn ich MyISAM nicht genau. Aber es lässt sich ja nicht von der Hand weisen, dass eine große Tabelle immer länger braucht (zum Schreiben als auch zum Lesen) als zum Beispiel mehrere kleinere Tabellen.
Trotzdem werde ich mir das mal genauer anschauen. Vielen Dank für die Links!
Ein weiteres Problem ist, dass die Berechnungen mit Formeln berechnet werden, die es meines Wissens in SQL nicht gibt oder vielleicht über Umwege realisierbar sind, aber mein Fachwissen dazu nicht die gewünschte Reife besitzt. :wink:
Die zu berechnenden 8000 Objekte sind jetzt speziell für einen Fall genannt. Es kann durchaus sein, dass es weitaus mehr werden können.
Daher denke ich, dass es die einzige Möglichkeit ist, diese riesige Tabelle zu splitten.



> Nein, sollten sie nicht. InnoDB macht z.B. bei 1000 Spalten dicht. Andere limitierende Faktoren sind die Zeilengröße exkl. BLOB, TEXT und STRING.
> 
> In einer halbwegs normalisierten Datenbank sollte ein solches Limit aber auch nie erreicht werden.



hmm... schade, dass es hierbei auch eine limitierte Spaltenanzahl gibt.
Nun gut mit der Normalisierung dürfte das auf alle Fälle klappen. Wird eben ein wenig kompliziert, wenn man schauen muss in welcher Tabelle wo und was steht.

Dankeschön für die Vorschläge!

Gruß

Kuba


----------



## FenchelT (11. Jul 2008)

Hallo,

habe ich das richtig verstanden, dass Du eine Matrix von 8000 x 8000 hast zu der Du zu jedem Feld einen Wert speichern moechtest?

Dann wuerde Dir doch eine Tabelle mit 3 Spalten reichen (AchseX, AchseY, Wert)
Oder hab ich DIch da falsch verstanden?

Wie dem auch sei stimme ich AlArenal zu; eine Tabelle mit 8000 Spalten in einem RDBMS abbilden zu wollen ist wenig gluecklich.


Gruesse


----------



## Guest (11. Jul 2008)

Und ich hätte immer gedacht, dass extra für große Datenmengen ein RDBMS vorgezogen werden sollte.  :?  
Eine Tabelle mit 3 Spalten würde es eigentlich auch tun. Nur wäre da mein Algorithmus unbrauchbar, der jede Zeile traversiert bei der die Anfangszelle zwar konstant wäre, aber die Endzelle sich mit jeder Zeile um eins erhöht.
Oder man müsste das Zeile berechnen, welche man als nächstes lesen möchte. Hmm.. darüber werde ich mal nachdenken..  danke für den Denkanstoß :wink:
Jetzt schau ich mal, wie das mit den gesplitteten Tabellen geht.

Gruß

Kuba


----------



## AlArenal (11. Jul 2008)

FenchelT hat gesagt.:
			
		

> Dann wuerde Dir doch eine Tabelle mit 3 Spalten reichen (AchseX, AchseY, Wert)



Japp, guter Punkt!

Ich denke auch, so lange das grundlegende Problem, das durch das Programm gelöst werden soll, nicht näher bekannt gemacht wird, ist es schwer konkret Hilfestellung zu geben. Wenn man einfach nur einen Datentopf haben will, den man speichern und lesen kann, dann tun es auch die diversen Serialisierungsmechanismen. Komplexe mathematische Operationen mit einer SQL-Datenbank als Speicher auszuführen, ist jedenfalls nicht sehr clever und schon gar nicht performant.


----------



## Guest (11. Jul 2008)

Wie gesagt, es geht hier um eine Clusteranalyse. Die detaillierten Schritte einzeln aufzuzeigen würde einfach den Rahmen sprengen. Außerdem sollte nur eine Lösungsmöglichkeit gefunden werden, die große Datensätze schnell schreiben und lesen kann und das in Form einer Matrix, da sich bei einer Clusteranalyse die Matrix nach jedem Durchlauf zwei Spalten und Zwei Zeilen in jeweils eine umformen, da ein Cluster gebildet wurde.
Einen kleinen Einblick gibt Wikipedia (http://de.wikipedia.org/wiki/Clusteranalyse).
Natürlich gibt es schon vorgefertigte Programme, die das auch können, nur leider stößt man eben dabei an Grenzen, die leider zu tief liegen.

Trotzdem vielen Dank.

Gruß

Kuba


----------



## Siassei (11. Jul 2008)

Anonymous hat gesagt.:
			
		

> Natürlich gibt es schon vorgefertigte Programme, die das auch können, nur leider stößt man eben dabei an Grenzen, die leider zu tief liegen.


Grenzen gibt's überall  :wink: 

Ich habe persönlich noch nie einen derartigen Alg. umgesetzt. Doch kommt es mir so vor als müsstest du erst einmal dein DB-Design und den dazu gehörigen Algorithmus überdenken. Achja, falls du eine DB einsetzen möchtest (was ich dir dringend empfehle) wirst du deinen Horizont erweitern müssen. Da du die Berechnung auf der DB - Seite aus Performancegründen durchführen musst!


----------



## byte (14. Jul 2008)

Anonymous hat gesagt.:
			
		

> Und ich hätte immer gedacht, dass extra für große Datenmengen ein RDBMS vorgezogen werden sollte.  :?


Große Datenmengen heisst aber nicht zwangsläufig, dass diese in genau einer Tabelle abgelegt sind. Der Vorteil einer DB liegt in meinen Augen auch darin, dass viele User gleichzeitig drauf zugreifen können. Ist diese Anforderung bei Dir überhaupt gegeben? Wenn nicht, dann kannst Du doch genauso gut das Dateisystem zu speichern benutzen.


----------



## AlArenal (14. Jul 2008)

Siassei hat gesagt.:
			
		

> Da du die Berechnung auf der DB - Seite aus Performancegründen durchführen musst!



Schonmal gehört, dass jemand eine Oracle oder DB2, o.ä. einsetzt, um High Performance Computing zu betreiben? Ich jedenfalls nicht und das hat auch gute Gründe.


----------



## byte (14. Jul 2008)

Jo, bei den meisten Business-Anwendungen ist die DB das Nadelöhr. :lol:


----------



## AlArenal (14. Jul 2008)

DBs sind dazu da Daten strukturiert abzulegen und im Rahmen dieser Strukturen auslesen und bearbeiten zu können. Für rechenintensive Anwenundungen sind DBs nicht optimiert und auch praltisch kaum optimierbar (bestenfalls über eigens programmierte Erweiterungen) und wer die DB nutzt um in rechenintensiven Anwendungen ständig Daten abzufragen und abzulegen wird merken, dass seine Berechnungen gähnend langsam ist, weil die Latenzen sich hier extrem aufsummieren.

Aus demselben Grunde ist eine relationale DB nicht sinnvoll als Krücke für mangelnden Hauptspeicher zu missbrauchen. Bestenfalls kann man sie zu Beginn und Ende einer relativ langen Berechnung einsetzen um Nutzdaten einzulesen und Ergebnisse abzulegen. 

Wenn der DB Server die ganze Zeit ausgelastet ist und der HPC-Client vor sich rumidelt, hat man in der Aufgabenverteilung was falsch gemacht


----------



## Siassei (14. Jul 2008)

AlArenal hat gesagt.:
			
		

> DBs sind dazu da Daten strukturiert abzulegen und im Rahmen dieser Strukturen auslesen und bearbeiten zu können. Für rechenintensive Anwenundungen sind DBs nicht optimiert und auch praltisch kaum optimierbar (bestenfalls über eigens programmierte Erweiterungen) und wer die DB nutzt um in rechenintensiven Anwendungen ständig Daten abzufragen und abzulegen wird merken, dass seine Berechnungen gähnend langsam ist, weil die Latenzen sich hier extrem aufsummieren.
> 
> Aus demselben Grunde ist eine relationale DB nicht sinnvoll als Krücke für mangelnden Hauptspeicher zu missbrauchen. Bestenfalls kann man sie zu Beginn und Ende einer relativ langen Berechnung einsetzen um Nutzdaten einzulesen und Ergebnisse abzulegen.
> 
> Wenn der DB Server die ganze Zeit ausgelastet ist und der HPC-Client vor sich rumidelt, hat man in der Aufgabenverteilung was falsch gemacht



@AlArenal

Wie immer hast du natürlich vollkommend recht  :wink: Aber der OP möchte halt eine DB einsetzen.

Ich würde das ganze in einer eigener Anwendung + native Datei zum Auslagern umsetzen. In C++ ist es z.B. möglich eine Datei zu öffnen und mit mehreren Threads an verschiedenen Stellen gleichzeitig zu lesen und schreiben, ohne dass die Datei beschädigt wird. Zudem muss nicht die gesamte Datei beim durchsuchen, lesen oder schreiben nicht ganz geladen werden -> Verminderung des benötigten RAM.
Leider habe ich keine Anhnung, ob eine derartige Implementierung in Java möglich ist. Könntest du mir einen Ansatz hierfür in Java geben?


----------



## AlArenal (14. Jul 2008)

Multi-threaded Dateizugriff ist mir als Anforderung bisher noch nicht untergekommen. Aber vielleicht bringt dich das hier auf Ideen, oder zumindest passende Suchbegriffe:

http://forum.java.sun.com/thread.jspa?threadID=5211509&messageID=9852852

http://www.javaworld.com/javaworld/jw-01-1999/jw-01-step.html


----------



## Siassei (14. Jul 2008)

Hey, danke. Das ist in Java einfacher als ich angenommen habe


----------



## Guest (14. Jul 2008)

Als Threadersteller möchte ich mich auch nochmal dazu äußern  :wink: 
Natürlich habe ich auch schon den Versuch unternommen die Daten in eine Textdatei zu schreiben. Nur leider ist das ganze nicht so performant, wie man sich das erwünscht.
Soweit so gut. Die Idee mit dem Tabellensplitting auf Datenbankseite habe ich auch schon zum größten Teil umgesetzt und finde die Geschwindigkeit sehr gut, da während des Schreibens in die DB schon wieder der nächste Wert berechnet werden kann. (Als Datenbank benutze ich H2 / www.h2database.com)
Der Flaschenhals bzw. die Wartezeit für das Schreiben bzw. Lesen wird dann mit Rechenzeit gefüllt. Dadurch wird sowohl die DB als auch die CPU gut ausgelastet.

Möchte mich an dieser Stelle trotzdem für die Vorschläge bedanken! Der ein oder andere Gedanke hat mich weitergebracht!

Grüße

Kuba


----------



## Gast (14. Jul 2008)

> Nur leider ist das ganze nicht so performant, wie man sich das erwünscht.





> Der Flaschenhals bzw. die Wartezeit für das Schreiben bzw. Lesen wird dann mit Rechenzeit gefüllt.



ich glaub du ließt und schreibst zu viel. laden berechnen speichern, fertig. wo ist das problem? geht dir der heapspeicher aus? ja kein wunder, sind ja standardmäßig nur ein paar mb vorgesehen, gönn dir 1 GB und du wirst keine probleme mehr haben


----------



## byte (15. Jul 2008)

Anonymous hat gesagt.:
			
		

> Natürlich habe ich auch schon den Versuch unternommen die Daten in eine Textdatei zu schreiben. Nur leider ist das ganze nicht so performant, wie man sich das erwünscht.


Das "wie" ist beim Thema I/O entscheidend, wenns um Performance geht.
Erst kürzlich habe ich eine 17 MB XML-Datei in ~700ms deserialisiert, was mir zeigt, dass Java-I/O sehr schnell sein kann.


----------

