Array Datentyp

Themen rund um den praktischen Einsatz von Firebird. Fragen zu SQL, Performance, Datenbankstrukturen, etc.

Moderator: thorben.braun

Antworten
Groffy
Beiträge: 78
Registriert: Do 12. Apr 2018, 23:14

Guten Morgen Zusammen,

ich hatte schon in einem anderen Thread beschrieben, daß wir Messdaten binär in BLOBS speichern. Wäre hier auch ein Array Datentyp möglich um z.B. Floats direkt zu speichern? Wäre hier auch die maximale Feldgröße Größe (float = 4 byte) von 4GB für einen BLOB die Grenze? Da die Feldgrößen nicht dynamisch sind, müßte ich von vorne herein die Felder sehr groß dimensionieren, was bedeutet das für den Speicherplatzbedarf wenn ich die Array Größe nicht vollständig brauche?

Oder ist das alles keine wirkliche Alternative?


Vielen Dank und beste Grüße - Ulrich
Benutzeravatar
martin.koeditz
Beiträge: 443
Registriert: Sa 31. Mär 2018, 14:35

Hallo Ulrich,

aus der Sprachreferenz:
Array werden in Firebird mittels speziellen BLOB-Typen gespeichert. Arrays können ein- und multidimensional sein. Sie dürfen aus beliebigen Datentypen, außer BLOB und ARRAY bestehen.
Die maximale BLOB-Größe liegt bei ca 32 GB, sofern das Dateisystem dies zulässt. Unter FAT 32 gibt es die 4 GB-Beschränkung.

Gruß
Martin
Martin Köditz
it & synergy GmbH
Groffy
Beiträge: 78
Registriert: Do 12. Apr 2018, 23:14

Hallo Martin,

die deutsche Doku gibt keinen Hinweis darauf, dass die Blobgröße auch vom Dateisystem abhängt :

https://firebirdsql.org/file/documentat ... es-more-de
3.6.2. BLOB Specifics
Größe
Die Maximalgröße eines BLOB-Feldes ist auf 4GB begrenzt, unanhängig vom darunterliegenden 32- oder 64-Bit-Server. (Die internen Strukturen im Zusammenhang mit BLOBs nutzen ihre eigenen 4-Byte-Zähler.) Für Seitengrößen (page size) von 4 KB (4096 Bytes) ist die Maximalgröße geringer — etwas weniger als 2 GB.
Mittlerweile habe ich ein kleines Testprogramm gebaut, welches aber gezeigt hat, daß die Performance um ca Faktor 100 schlechter ist. Für einen Messdatensatz von 1200 x 1200 = 1440000 Messpunkte liegen die Speicherzeiten im Binärformat bei ca 50mS, wenn ich direkt float Arrays speichern möchte, bei 5 Sekunden. Ob das ein Treiberproblem ist, oder der Firebird 2.5.9 Server wirklich solange braucht die Arrays in Binärdaten zu konvertieren weiß ich nicht.


Vielen Dank und beste Grüße - Ulrich
Benutzeravatar
martin.koeditz
Beiträge: 443
Registriert: Sa 31. Mär 2018, 14:35

Ok, es ist tatsächlich so, dass die maximale BLOB-Größe von der Page Size abhängt. Bei 16 KB (ab FB 3.0) sind dies etwas weniger als 32 GB. Für FB 2.5 ist die maximale Page Size allerdings 8 KB.

Gruß
Martin
Martin Köditz
it & synergy GmbH
Groffy
Beiträge: 78
Registriert: Do 12. Apr 2018, 23:14

Für FB 2.5 ist die maximale Page Size allerdings 8 KB
Bist Du da sicher? Ich bin bislang von einer maximalen pagesize von 16k ausgegangen (FB 2.5)


Gruß Ulrich
bfuerchau
Beiträge: 485
Registriert: Mo 7. Mai 2018, 18:09
Kontaktdaten:

16KB ist korrekt und aus Performancesicht optimal (Indizes).
Ab 3.0 gehts dann wohl auch höher.
Arrays sind aus SQL-Sicht eher kontraproduktiv, da sie sich nicht einfach in der Whereklausel durchsuchen und indizieren lassen.
Eine Normierung der Datenbank (also 2. Tabelle mit Rownumber) wäre da sinnvoller.
Bei den Massenwerten, die du da speicherst sind BLOB's wohl wirklich das sinnvollste. Allerdings lohnt sich da auch durchaus eine Komprimierung der Daten vor der Speicherung. Damit umgehst du die Größeneinschränkung ein wenig. Das Komprimieren/Dekomprimieren geht noch schneller als das Speichern in die DB.
Benutzeravatar
martin.koeditz
Beiträge: 443
Registriert: Sa 31. Mär 2018, 14:35

Code: Alles auswählen

 Bist Du da sicher? Ich bin bislang von einer maximalen pagesize von 16k ausgegangen (FB 2.5)
Stimmt, habe nochmals nachgelesen. Bin mit einem anderen Parameter durcheinander gekommen. 16 KB gab es bereits in 2.5.

Gruß
Martin
Martin Köditz
it & synergy GmbH
Groffy
Beiträge: 78
Registriert: Do 12. Apr 2018, 23:14

bfuerchau hat geschrieben: Do 23. Jul 2020, 15:49 Bei den Massenwerten, die du da speicherst sind BLOB's wohl wirklich das sinnvollste. Allerdings lohnt sich da auch durchaus eine Komprimierung der Daten vor der Speicherung. Damit umgehst du die Größeneinschränkung ein wenig. Das Komprimieren/Dekomprimieren geht noch schneller als das Speichern in die DB.
Vielen Dank für den Hinweis, ich hatte früher schon einmal an Datenkompression gedacht, aber dann aus den Augen verloren. Der Kompressionsgrad bei Messdaten schwankt je nach Inhalt stark, aber mit einem Probe Datensatz erreiche ich momentan den Faktor 1.8. Das finde ich schon beachtlich. Das heißt, nicht nur die Menge der Daten in der Datenbank werden reduziert, sondern auch die Menge der Daten die zum Server geschickt werden müssen.

Vielen Dank und ein schönes Wochenende
bfuerchau
Beiträge: 485
Registriert: Mo 7. Mai 2018, 18:09
Kontaktdaten:

Allerdings wird das in der DB nicht viel ausmachen, da die Firebird grundsätzlich die Daten sowieso komprimiert und komprimierte Daten u.U. zu einer minimalen Verlängerung führen.
Der Effekt ist aber, dass du den Blob mit dem 1,8-Fachen füllen kannst.
Beachte auch, dass es verschieden effektive Komprimierungen gibt.

Beispiel:
Wenn du 1,4 Millionen Werte zu speichern hast, wieviele Distinct-Values hast du dann?
Bis 256 = 1-Byte-Speicherung => 1,4MB
bis 65536 = 2 Byte-Speicherung => 2,8MB
Rest 4-Byte-Speicherung => 2^32 verschiedene Werte
Zusätzlich benötigst du eine Mapping-Tabelle
Distict-Wert => Speicherwert

Somit kannst du via Dictionary durchaus noch mehr Werte effektiv in 2GB unterbringen. Und dann noch Komprimierung (wobei das u.U. keinen Effekt mehr hat).
Antworten