2010-08-06 8 views
5

Ich möchte eine JVM-Datenstruktur (Java/Scala) entwerfen, die verwendet werden kann, um den Inhalt beliebiger relationaler Datenbanktabellen darzustellen und zu speichern. Die Datenstruktur sollte schnell (nicht zu gc-intensiv, Cache-freundlich) und speichereffizient sein, damit größere Tabellen in den Arbeitsspeicher passen.Datenstruktur zum Speichern von willkürlichen Datenbanktabellen

Eine speichereffiziente Lösung besteht darin, jede Spalte separat in einem primitiven Array zu speichern, aber ich mache mir Sorgen wegen der Cache-Freundlichkeit, da Elemente in derselben Zeile nicht zusammen gespeichert werden. Eine Zeile mit N Spalten führt zu N Cache-Fehlern, egal wie schmal die Spalten sind. Eine andere Lösung besteht darin, jede Zeile in einem Objektarray zu speichern, wobei jedes Element ein Feld darstellt und beim Abrufen in den richtigen Typ umgewandelt wird. Dies erfordert jedoch das Speichern numerischer Typen in der eingerahmten Form, sodass es nicht sehr speichereffizient ist. Und wahrscheinlich ist dieser Cache auch nicht effizient.

Eine andere Lösung besteht darin, die Daten jeder Zeile so in ein Byte-Array einzuordnen, wie es bei echten Datenbanken der Fall ist, wenn nur so viele Bytes wie nötig serialisiert werden. Dies ist Cache-freundlich und Speicher effizient, aber ich bin besorgt über die Kosten der Serialisierung/Deserialisierung bei jedem Zugriff.

Was ist der beste Weg?

Antwort

1

Was ist der Zweck, dies zu tun? Es ist wahrscheinlich besser, die Daten, die Sie aus Ihrer Datenbank abrufen (als die Objekte, die Sie zuordnen), einfach in einer Art Caching-Ebene wie EhCache, OSCache, Memcache usw. zu speichern - anstatt das Rad neu zu erfinden.

+0

Es ist für eine Hauptspeicherdatenbank Nebenprojekt. –

1

Warum nicht hsqldb oder h2 verwenden?

Beide unterstützen den In-Memory-Modus und sind reines Java. Sie zwingen Sie, SQL für den Zugriff zu verwenden, aber am anderen Ende müssen Sie keinen eigenen Join implementieren.

Beide sind Open Source, also können Sie dies auch als Basis für die Performance verwenden und sehen, ob die Datenstruktur nach Spalte/Zeile schneller ist und sich lohnt.

+0

HSQLdb weist für eine Tabelle mit nur einer Integerspalte (d. H. 4 Byte tatsächlicher Daten) etwa 80 Byte pro Zeile zu. Nach: http://hsqldb.org/doc/2.0/guide/deployment-chapt.html#deployment_mem_disk-sect –

1

Eine vierte Lösung wäre, die Daten jeder Zeile als Strings statt als Byte-Arrays zu speichern. Dies kann Serialisierungskosten in meisten Fällen vermeiden - sofern die meisten Daten Strings sind.

Dies ist auch einfacher zu debuggen und wird plattformunabhängig sein. Natürlich hat es einige Einschränkungen: z.B. Ein Gleitkomma kann nicht wie dargestellt dargestellt werden, sondern kann in einem SQL DECIMAL-Format gespeichert werden.

Jede Lösung wird ein Kompromiss sein.

EDIT Allerdings würde ich die Byte-Array-Lösung für Ihren Fall bevorzugen: ein Byte-Array pro Zeile. Dies sollte für Zeilen mit fester Größe am besten Cache-freundlich sein. Aber dann sollten Sie auch eine Lösung für Zeilen variabler Größe bereitstellen. Eine Sprache auf niedrigerer Ebene scheint dieser Aufgabe besser zu entsprechen, in C könnte man zwei Formate definieren: Zeilen fester Größe, in denen die Tabellenmetadaten Spaltenversätze enthalten (z. B. Spalte 1: Byte 0..31, Spalte 2: Byte 32.127) usw.), und ein zweites Zeilenformat mit variabler Größe, wobei die Zeilen selbst die Spaltengrößen enthalten (z. B. Bytes 1..3 enthalten die Größe, die folgende Anzahl von Bytes enthält die Daten, dann weitere 4 Bytes enthalten die Größe, folgende Daten) und so weiter).