Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Delphi Firebird Datenbankgröße (https://www.delphipraxis.net/180224-firebird-datenbankgroesse.html)

haentschman 2. Mai 2014 10:19

Datenbank: Firebird • Version: 2.5 • Zugriff über: IBDAC

Firebird Datenbankgröße
 
Hallo,

in Anlehnung an mein anderes Problem (http://www.delphipraxis.net/180221-f...index-max.html) noch folgende Frage:

Ich bin mit der Datenbankgröße auf der Platte nicht wirklich zufrieden.


Gegeben:
Delphi-Quellcode:
CREATE TABLE T_RECORD_DATA (
    F_PARAMETER_ID   ID /* ID = INTEGER NOT NULL */,
    F_TIMESTAMP_UNIX INTEGER_NORMAL /* INTEGER_NORMAL = INTEGER NOT NULL */,
    F_POWER_STATE    INTEGER_NORMAL /* INTEGER_NORMAL = INTEGER NOT NULL */,
    F_VALUE          STRING10 /* STRING10 = VARCHAR(10) NOT NULL */
21000000 Datensätze in Tabelle
1,65 GB Plattenplatz

Datenquelle:
Technisches Gerät mit (angeblich) 128MB internem Speicher und 25% Belegung :shock:

Wo kommen die extremen Größendifferenzen her? Der Index belegt nicht wirklich viel. Etwa 5% der Gesamtgröße geschätzt nach 2 Versuchen in leere DB (3,6 MB) sowohl mit Index als auch ohne.

Wie kann ich die Datenbankgröße verkleinern?

Betroffen von der Datenflut ist nur diese Tabelle. Dies ist nur ein Gerät. Max 500 sollen möglich sein. Das wären
1,65*4(Belegung 100%)*500 = 3,3 TB (größte bekannte FB Datenbank hat rund 980 GB)...Klar gibt es da wieder Möglichkeiten (1 DB je Gerät etc.). Mir ist nur diese Ausgangsbasis zu viel.

Danke für Info´s... 8-)

mkinzler 2. Mai 2014 10:26

AW: Firebird Datenbankgröße
 
1.)Bei Updates eines Datensatzes wird eine neue Kopie des Datensatzes (neue Version) angelegt.
2.)Gelöschte Datensätze werden nicht gelöscht sondern markiert.
zu 1.) Bei einem Sweep werden die Versionen bereinigt.
zu 2.) Backup/Restore

Union 2. Mai 2014 10:26

AW: Firebird Datenbankgröße
 
Geht das nicht mit
Code:
gfix -sweep
?

mkinzler 2. Mai 2014 10:28

AW: Firebird Datenbankgröße
 
Ja:

Code:
gfix -user SYSDBA -password masterkey dbserver:/db/mydb.fdb -sweep

haentschman 2. Mai 2014 10:28

AW: Firebird Datenbankgröße
 
Danke. 8-)

Die Datensätze werden nur per Insert eingefügt. Eine Bearbeitung (update) ist nicht vorgesehen. Die Datenbankgröße ist die nach den 21 Mio Insert incl Index.

Dejan Vu 2. Mai 2014 10:36

AW: Firebird Datenbankgröße
 
Hast Du mal nachgerechnet?
21 Mio Datensätze in 25% von 128MB Speicher sind irgendwie nicht ganz so viele Bytes pro Datensatz. Genauer gesagt: 1.6 Bytes.
Zitat:

Zitat von haentschman (Beitrag 1257678)
Datenquelle:Technisches Gerät mit (angeblich) 128MB internem Speicher und 25% Belegung :shock:

Wenn im Gerät keine Dimensionsfaltenkompression eingebaut ist, würde ich hier annehmen, das das 'angeblich' nicht 100% korrekt ist.

Was wir hier haben sind ca. 23 Bytes reine Nutzdaten. Das ergibt dann schon mal in Summe 460 MB (21 Mio recs # 23 Bytes). Pro Index über einen 4-Byte-Integer kommen da dann noch 84 MB + Overhead hinzu. Ich kenne FB jetzt nicht, aber ich würde pro Record einen Overhead von ca 10-15 Bytes annehmen, das wären dann also ca. 40 Bytes Brutto ohne Index, also ungefähr 800MB. Dann noch der Index mit 80MB + X Overhead und wir sind schon nahe am GB. Na, vielleicht ist der Overhead doch etwas höher.

haentschman 2. Mai 2014 10:55

AW: Firebird Datenbankgröße
 
Danke für deine Berechnungen. :P

Zitat:

Hast Du mal nachgerechnet?
...nicht exakt. Es ist nur unglaublich wie die Values da rein passen. Die Belegung kann ich nur aus der Weboberfläche des Gerätes wiedergeben.
Zitat:

21 Mio Datensätze in 25% von 128MB Speicher sind irgendwie nicht ganz so viele Bytes pro Datensatz. Genauer gesagt: 1.6 Bytes.
... und die haben je Value auch den Unix Timestamp. Selbst damit wären wir schon drüber. (128MB)
Zitat:

Was wir hier haben sind ca. 23 Bytes reine Nutzdaten. Das ergibt dann schon mal in Summe 460 MB (21 Mio recs # 23 Bytes). Pro Index über einen 4-Byte-Integer kommen da dann noch 84 MB + Overhead hinzu. Ich kenne FB jetzt nicht, aber ich würde pro Record einen Overhead von ca 10-15 Bytes annehmen, das wären dann also ca. 40 Bytes Brutto ohne Index, also ungefähr 800MB.
...damit könnte ich leben. Wir liegen aber ca. beim Doppelten.
Ich habe schon mit varchar(1) statt Integer für den PowerState experimentiert... ohne nennenswerte Platzgewinne. :?

Dejan Vu 2. Mai 2014 11:26

AW: Firebird Datenbankgröße
 
Ich sage ja: FB hat eben noch einen höheren Record-Overhead. Auch bei den Indexen ist es doch etwas mehr als die reinen Nutzdaten.

Heutzutage ist ja Performance wichtiger als Speicher und wenn das bei FB eben so ist, dann ist es doch gut.

Ich hab mal eben eine Test-DB auf einem SQL-Server erzeugt. Das verbrät mit einem Index so ziemlich genau ein GB.

Lemmy 2. Mai 2014 11:27

AW: Firebird Datenbankgröße
 
werden nach dem Insert keine Änderungen an den Daten vorgenommen und keine weiteren Inserts durchgeführt? Bzw. wenn dann erst ein Delete * from... bzw. ein großer Insert mit Massendaten?

Dann könnte folgendes was bringen: Firebird speichert die Daten ja auf "Pages" die aber nicht zu 100% gefüllt werden, um Lücken für spätere Inserts zu lassen um wegen dem Index nicht alles umsortieren zu müssen.

Macht man aber nur einmal einen großen Insert und ändert die Daten hier kaum noch, kann man auch die Seiten komplett füllen und damit wir die Datei an sich kleiner.

Mach mal ein gstat -data <Database>. Dann sollte so was raus kommen:

Code:
CONFIGREVISIONSTORE (213)
    Primary pointer page: 572, Index root page: 573
    Data pages: 2122, data page slots: 2122, average fill: 82%
    Fill distribution:
         0 - 19% = 1
        20 - 39% = 0
        40 - 59% = 0
        60 - 79% = 79
        80 - 99% = 2042
Wenn hier viele Seiten nur 60-80% gefüllt sind, verlierst Du entsprechend Platz.

Ändern kannst Du das über gfix:

http://www.firebirdsql.org/manual/gfix-pagespace.html

gfix -use FULL database_name

[edit]: Vorteil ist, dass im Grunde die Lesegeschwindigkeit steigt, da weniger Pages gelesen werden müssen, nachteil: Inserts dauern auf grund der Index-Optimierung länger. Bei großen Inserts daher besser den Index deaktivieren und anschließend wieder neu aufbauen...

Weiterhin kann die PageSize an sich auch ein Problem sein, wenn diese nicht mit der Sektorengröße auf der Platte zusammen passt - hier sollte aber der Windows-Explorer in neueren WIndows-Versionen die entsprechenden Informationen auch ausgeben können.

tsteinmaurer 2. Mai 2014 11:34

AW: Firebird Datenbankgröße
 
@Lemmy: Das würde ich nur bei einer Read-Only Datenbank machen.

Lemmy 2. Mai 2014 11:43

AW: Firebird Datenbankgröße
 
@Thomas: ich habe das ehrlich gesagt noch nie gemacht - aber wo ist der Unterschied zwischen einer (eingestellten) Read-Only DB und einer DB in die ich keine Inserts mache? Sortiert FB hier dennoch immer wieder Daten um?

mkinzler 2. Mai 2014 11:44

AW: Firebird Datenbankgröße
 
Er macht ja Inserts

Dejan Vu 2. Mai 2014 12:24

AW: Firebird Datenbankgröße
 
Und die sind immer am Ende? So von wegen Timestamp und Index drauf. Weiß jetzt nicht, wie FB das macht, aber die Daten werden ja wohl ans Ende gepackt,

mkinzler 2. Mai 2014 12:30

AW: Firebird Datenbankgröße
 
Nein. Wenn vorher ein datensatz gelöscht wurde, wird der Speicherplatz für neue Inserts wieder verwendet.

Dejan Vu 2. Mai 2014 12:38

AW: Firebird Datenbankgröße
 
Zitat:

Zitat von mkinzler (Beitrag 1257703)
Nein. Wenn vorher ein datensatz gelöscht wurde, wird der Speicherplatz für neue Inserts wieder verwendet.

Werden hier Datensätze gelöscht? Soweit wie ich das bisher verfolgt habe: Nein. Und dann stimmt meine Annahme ja wohl, das die neuen Datensätze automatisch und immer ans Ende kommen. Und wenn das so ist, kann man die Seiten auch mit einem Fillfactor von 100% füllen, oder nicht?

hstreicher 2. Mai 2014 12:46

AW: Firebird Datenbankgröße
 
Zitat:

Zitat von Dejan Vu (Beitrag 1257685)
Hast Du mal nachgerechnet?
21 Mio Datensätze in 25% von 128MB Speicher sind irgendwie nicht ganz so viele Bytes pro Datensatz. Genauer gesagt: 1.6 Bytes.
Zitat:

Zitat von haentschman (Beitrag 1257678)
Datenquelle:Technisches Gerät mit (angeblich) 128MB internem Speicher und 25% Belegung

Was wir hier haben sind ca. 23 Bytes reine Nutzdaten. Das ergibt dann schon mal in Summe 460 MB (21 Mio recs # 23 Bytes). Pro Index über einen 4-Byte-Integer kommen da dann noch

nur mal so :
128MB durch 21 Mio = 6 Bytes

der Index besteht auf 4 Byte Nutzdaten
Aufbau eines Index Records:

http://ibexpert.net/ibe/index.php?n=Doc.IndexB-treePage

struct btree_nod
{
UCHAR *nodePointer;
USHORT btn_prefix;
USHORT btn_length;
SLONG pageNumber;
UCHAR *data;
RecordNumber recordNumber;
bool isEndBucket;
bool isEndLevel;

1+2+2+4+4+4+1+1 = 19 Byte bei 4 Byte Nutzlast

sind dann 400 MB , dazu kommt dass die Indexe in Pages verwaltet werden die meist nicht ganz gefüllt werden
Plus Overhead um die Pages zu verwalten ,

2 Indizes laut dem anderen Thread also über 800MB

Record Header : (auch von der IBexpert seite)
struct rhd {
SLONG rhd_transaction;
SLONG rhd_b_page;
USHORT rhd_b_line;
USHORT rhd_flags;
UCHAR rhd_format;
UCHAR rhd_data[1];
};

4+4+2+2+1+ Nutzlast
36 Bytes bei 21 Mio Record 756 MB

Plus 800 MB Index


so dass das mit den 1.65 GB schon hinkommt

mfg Hannes

tsteinmaurer 2. Mai 2014 12:49

AW: Firebird Datenbankgröße
 
Ich kann mir nicht vorstellen, dass niemals gelöscht wird, sprich die Tabelle ins Unendliche wachsen darf/kann.

Firebird hat auch keinen Clustered Index wie in SQL Server bzw. eine Index-Organized Table wie in Oracle.

haentschman 2. Mai 2014 13:34

AW: Firebird Datenbankgröße
 
Zitat:

Ich kann mir nicht vorstellen, dass niemals gelöscht wird, sprich die Tabelle ins Unendliche wachsen darf/kann.
Das ist schon richtig. Das ganze sind Meßdaten welche mindestens 10 Jahre aufbewahrt werden müssen / sollen. In den internen Speicher (128 MB) gehen, je nach Speicherzyklus (1m / 15m) zwischen 1 Jahr bis zu 3 Jahren Daten.
Die sollen in der DB verbleiben. Quasi die letzten 10 Jahre. Wenn die DB an dieser Stelle ankommt werden die ersten entfernt.

Beim aktuellen Beispiel wären das 1,6GB zu 0,75 = x zu 10 -> 21,3GB
(0,75 Jahre im Gerät bei 10 Jahre gesamt)

Inzwischen ist die Entscheidung gefallen, daß jedes Gerät seine eigene DB für die Record Daten bekommt. Damit sind ein paar Probleme vom Tisch (Gesamtgröße)

PS: Ich rechne lieber mit dem WorstCase als später in Probleme zu laufen weil man sich nicht richtig Gedanken gemacht hat.

Zitat:

nur mal so :
128MB durch 21 Mio = 6 Bytes
...angeblich erst 25% Auslastung. Das wären dann 1,5 Byte je DS.

tsteinmaurer 2. Mai 2014 13:56

AW: Firebird Datenbankgröße
 
In welcher Granularität musst du die Messdaten aufbewahren?

Bei Timeseries Anwendungsfällen geht man in der Regel so vor, dass periodisch Daten von einer höheren Auflösung in kleinere Auflösungen aggregiert wird und im selben Kontext Daten der höheren Auflösung gelöscht werden. Außer du bist im Bereich Garantie wo du die feingranularen Daten zur Nachvollziehbarkeit benötigst.

Bzgl. Datenbank je Gerät. Im Prinzip musst du dann X Datenbanken bzgl. Schemastruktur auf einem entsprechenden Stand halten, jede Datenbank sichern etc., bei einem Firebird/ODS Upgrade diese sichern/wiederherstellen etc. Dann hast du vielleicht auch Stammdaten, die jedem Gerät gemein sind. Wie machst du das?

Je nach Datenvolumen and Anwendungsfall haben hier (für Zeitreihen) BigData-Lösungen ala Cassandra absolut ihre Daseinsberechtigung. Aber das ist eine ganz andere Welt ...

p80286 2. Mai 2014 14:08

AW: Firebird Datenbankgröße
 
Zitat:

Zitat von Lemmy (Beitrag 1257696)
@Thomas: ich habe das ehrlich gesagt noch nie gemacht - aber wo ist der Unterschied zwischen einer (eingestellten) Read-Only DB und einer DB in die ich keine Inserts mache? Sortiert FB hier dennoch immer wieder Daten um?

Du hast Die Updates übersehen! Je nach indizierten Feldern, kannst Du einige Änderungen in den Indizies bekommen, auch wenn der RecordCount stabil bleibt. Eine Readonly-DB ist eigentlich tot.

Gruß
K-H

haentschman 2. Mai 2014 14:11

AW: Firebird Datenbankgröße
 
Hallo Thomas...

ich bin ein wenig von der Größe überfahren worden. Im Leben hätte ich (Bauchgefühl) nicht mit der Größe gerechnet.

Zum Thema Statistik:
Delphi-Quellcode:
T_RECORD_DATA (153)
    Primary pointer page: 150, Index root page: 172 
    Data pages: 82929, data page slots: 82929, average fill: 63% 
    Fill distribution:
         0 - 19% = 0 
        20 - 39% = 1 
        40 - 59% = 0 
        60 - 79% = 82928 
        80 - 99% = 0 
 
    Index FK_T_RECORD_DATA_1 (0)
        Depth: 3, leaf buckets: 8073, nodes: 21680580 
        Average data length: 0.00, total dup: 21679353, max dup: 19155 
        Fill distribution:
             0 - 19% = 1 
            20 - 39% = 0 
            40 - 59% = 2451 
            60 - 79% = 0 
            80 - 99% = 5621 
 
    Index T_RECORD_DATA_IDX1 (2)
        Depth: 3, leaf buckets: 7010, nodes: 21680580 
        Average data length: 0.06, total dup: 20624315, max dup: 87 
        Fill distribution:
             0 - 19% = 0 
            20 - 39% = 0 
            40 - 59% = 1 
            60 - 79% = 0 
            80 - 99% = 7009
... bedeutet ja, daß reichlich Platz verschwendet wird. Die Inserts laufen als Block wie hier empfohlen
http://www.delphipraxis.net/1256983-post42.html
Delphi-Quellcode:
execute block as begin //25Kb je Block
insert into T_RECORD_DATA... // 200x je Block. Änderung der Menge machte keinen Unterschied.
end
Alle Blöcke laufen in einer Transaktion. Wo läßt sich da noch was rausholen.

Zitat:

Bzgl. Datenbank je Gerät. Im Prinzip musst du dann X Datenbanken bzgl. Schemastruktur auf einem entsprechenden Stand halten, jede Datenbank sichern etc., bei einem Firebird/ODS Upgrade diese sichern/wiederherstellen etc. Dann hast du vielleicht auch Stammdaten, die jedem Gerät gemein sind. Wie machst du das?
Ich würde nur diese eine Tabelle auslagern. Der Rest ist zusammengenommen, auch bei 500 Geräten, unter 30MB. Denkst du eher an eine Aufsplittung ab X GB? Geht das automatisch? Wo kann man das nachlesen?

Union 2. Mai 2014 15:10

AW: Firebird Datenbankgröße
 
Vielleicht kannst Du Deine Speicherung auch der auf dem Gerät angleichen. Wenn ich mir die Struktur aus dem OP ansehe, habe ich da so Vermutungen:
  • F_PARAMETER_ID ID /* ID = INTEGER NOT NULL */,
    Wie groß wird diese ID maximal? Wenn es z.b. so etwas wie max. 127 oder 255 wäre, könnte man das in einem Nibble, Byte oder Word zusammen mit z.b. POWER_STATE speichern
  • F_TIMESTAMP_UNIX INTEGER_NORMAL /* INTEGER_NORMAL = INTEGER NOT NULL */,
    Wenn man die Basis des Timestamp (den Offset 0) in die nähere Vergangenheit setzt, kommt man auch mit weniger Platz aus.
  • F_POWER_STATE INTEGER_NORMAL /* INTEGER_NORMAL = INTEGER NOT NULL */,
    Siehe Anmerkung zu Parameter-ID
  • F_VALUE STRING10 /* STRING10 = VARCHAR(10) NOT NULL */
    Sind das wirklich individuelle Werte oder sind das Fixtexte? Je nach Anzahl der möglichen Fixtexte könnte man das dann als Index auf ein konstantes Fixtext-Array bzw. eine entsprechende normalisierte Fixtext-Tabelle verkleinern.

Nachteil wäre die Rechnerei die Du beim Auswerten hättest. Immer das Selbe: Platzersparnis <> Performance.

Dejan Vu 2. Mai 2014 15:17

AW: Firebird Datenbankgröße
 
Ist das mit dem Platz im Jahr 2014 wirklich ein Problem?

Lemmy 2. Mai 2014 15:24

AW: Firebird Datenbankgröße
 
Zitat:

Zitat von p80286 (Beitrag 1257716)
Zitat:

Zitat von Lemmy (Beitrag 1257696)
@Thomas: ich habe das ehrlich gesagt noch nie gemacht - aber wo ist der Unterschied zwischen einer (eingestellten) Read-Only DB und einer DB in die ich keine Inserts mache? Sortiert FB hier dennoch immer wieder Daten um?

Du hast Die Updates übersehen! Je nach indizierten Feldern, kannst Du einige Änderungen in den Indizies bekommen, auch wenn der RecordCount stabil bleibt. Eine Readonly-DB ist eigentlich tot.

Gruß
K-H


Übersehen nicht, nur nicht explizit drauf eingegangen. Aufgrund der Beschreibung bin ich davon ausgegangen, dass die Daten einmal importiert werden um dann für Auswertungen vorgehalten werden bzw. bei Aktualisierungen die Daten als "Masseninserts" rein kommen und nicht individuell von den Anwendern geändert werden können / sollen. Und hier würde ich (wenn die DB-Größe wirklich ein Thema sein sollte) ggf. die beschrieben Dinge anwenden.

Unter 2.5 soll es ja auch möglich sein über StoredProcedures auf anderen DBs zugreifen zu können. Somit könnten diese Gerätedaten in eigene, ggf. auch als Read-OnlyDBs ausgelagert werden und die Pages voll gemacht werden.

Aber hier müsste der Threadstarter vielleicht noch Licht ins Dunkel bringen...

Union 2. Mai 2014 15:25

AW: Firebird Datenbankgröße
 
Zitat:

Zitat von Dejan Vu (Beitrag 1257730)
Ist das mit dem Platz im Jahr 2014 wirklich ein Problem?

Von Anfang an Platz zu sparen und die Performance zu optimieren zeugt immer von zukunftsorientiertem Denken. Irgendwann ist nämlich 2015 oder es sollen noch mehr Geräte eingebunden werden oder der Zugriff erfolgt in eine Cloud mit begrenzeter Bandbreite oder...

Leider ist das Denken "wieso Performance? Ich hab unendlich viel Speicher und Dutzende von Prozessorkernen." genau so weit verbreitet wie die Verwechselung einer IDE mit einem Point-And-Click-Adventure.

haentschman 2. Mai 2014 15:34

AW: Firebird Datenbankgröße
 
Danke an Alle...:thumb:

@Union: interessante Ansätze.
Zitat:

Wie groß wird diese ID maximal?
unbekannt. Vermute 6 stellig. Für einen SmallInt zu groß. Außerdem benötige ich später sowohl den Timestamp als auch den Parameter im SQL bei den Auswertungen. Da bleibt nicht mehr viel übrig. :(
Zitat:

Wenn man die Basis des Timestamp (den Offset 0) in die nähere Vergangenheit setzt, kommt man auch mit weniger Platz aus.
Du meinst so nah, daß der Rest in einen SmallInt paßt? Geht nicht.
Im Beispiel: letzter DS = 1398999942 erster = 1381299573
Zitat:

Sind das wirklich individuelle Werte oder sind das Fixtexte?
Kann sowohl ein Zeichen ('+'), ein digitaler Wert ('0'/'1') oder ein analoger Wert ('-999.99' bis '999.99') sein. In der ersten Version waren das sogar getrennte Felder. Varchar(10) soll das absolute Maximum darstellen. Der Platzbedarf sollte ja nur so groß sein wie die Daten oder? Der Timestamp könnte auch ein TDateTime sein. Was braucht weniger Platz?

Zitat:

Ist das mit dem Platz im Jahr 2014 wirklich ein Problem?
Da macht es die Masse über die Dauer. Im Maximum könnten 500 Geräte für 10 Jahre gespeichert werden. (rechnerisch derzeit ca. 11 TB) Im Normalfall reden wir über 1 - 3 Geräte. Da ist das natürlich kein Problem... :zwinker:

PS: Es geht um Temperaturaufzeichnungen in der Lebensmittelbranche und Pharmaciebranche. Die genauen Speicherzeiträumen per Gesetzt sind mir unbekannt. Da aber das Finanzamt 10 Jahre Aufbewahrung hat ging ich mal ebenso davon aus.
Rein theoretisch hat das Gerät einen Speicherzyklus von 1-3 Jahren je nach Auflösung. Dann werden die ersten Daten wieder überschrieben. Per Gesetz sind die so zugelassen und man könnte die DB Speicherung auch darauf begrenzen. Ich will aber einen Mehrwert für den Kunden. Quasi das was die Hardware nicht leistet.

Zitat:

Übersehen nicht, nur nicht explizit drauf eingegangen. Aufgrund der Beschreibung bin ich davon ausgegangen, dass die Daten einmal importiert werden um dann für Auswertungen vorgehalten werden bzw. bei Aktualisierungen die Daten als "Masseninserts" rein kommen und nicht individuell von den Anwendern geändert werden können / sollen. Und hier würde ich (wenn die DB-Größe wirklich ein Thema sein sollte) ggf. die beschrieben Dinge anwenden.

Unter 2.5 soll es ja auch möglich sein über StoredProcedures auf anderen DBs zugreifen zu können. Somit könnten diese Gerätedaten in eigene, ggf. auch als Read-OnlyDBs ausgelagert werden und die Pages voll gemacht werden.
Im Prinzip sind die Daten als ReadOnly zu betrachten und werden nur für Auswertungen etc. vorgehalten. Um aber die Größe nicht bis ins unendliche wachsen zu lassen sollen die Ältesten nach einem Zeitraum X entfernt werden.

Dejan Vu 2. Mai 2014 16:52

AW: Firebird Datenbankgröße
 
Zitat:

Zitat von Union (Beitrag 1257733)
Zitat:

Zitat von Dejan Vu (Beitrag 1257730)
Ist das mit dem Platz im Jahr 2014 wirklich ein Problem?

Von Anfang an Platz zu sparen und die Performance zu optimieren zeugt immer von zukunftsorientiertem Denken.
Zitat:

Zitat von Union (Beitrag 1257728)
Vielleicht kannst Du Deine Speicherung auch der auf dem Gerät angleichen.
Sind das wirklich individuelle Werte oder sind das Fixtexte? Je nach Anzahl der möglichen Fixtexte könnte man das dann als Index auf ein konstantes Fixtext-Array bzw. eine entsprechende normalisierte Fixtext-Tabelle verkleinern.
Nachteil wäre die Rechnerei die Du beim Auswerten hättest. Immer das Selbe: Platzersparnis <> Performance.


Das deckt sich jetzt nicht direkt mit 'Performance optimieren', sondern mit 'Speicherplatz sparen à la 1970'.

Das man Fehler speziell am Anfang vermeiden soll, ist mir auch klar, nur baut man manchmal eben auch am Anfang Fehler ein. Und wenn man schon überlegt, mit sparse-array Techniken hier Platz zu sparen, dachte ich mir, ich hebe mal einen Zeigefinger.

Wir leben im Jahr 2014, wo Festplattenspeicherplatz in Tera- und Petabytes gemessen wird. Wir sollten uns nicht darüber über Gebühr Gedanken machen, eine Datenbank von 1.6GB auf vielleicht 800GB zu komprimieren. Da spart man an Festplatten eigentlich kaum was (ok, sagen wir: alle 500 Jahre eine TB-Platte, oder bei 500 Geräten 1x pro Jahr 1 TB).

Wenn es ein Bug oder eine Fehleinstellung ist: Ja, natürlich muss man das in Ordnung bringen. Wenn ich signifikant Geld spare, auch ok. Aber das muss man immer wieder neu überlegen. Ich persönlich würde mich hüten, hier zu viel Energie hineinzustecken.

p80286 2. Mai 2014 17:07

AW: Firebird Datenbankgröße
 
Zitat:

Zitat von haentschman (Beitrag 1257735)
.
Zitat:

Wie groß wird diese ID maximal?
unbekannt. Vermute 6 stellig. Für einen SmallInt zu groß. Außerdem benötige ich später sowohl den Timestamp als auch den Parameter im SQL bei den Auswertungen. Da bleibt nicht mehr viel übrig. :(

6Stellig halte ich für arg wenig. Bei 10 Geräten über 10 Jahre und 300 Tagen sind das gerade mal 33 Meßwerte am Tag.

Zitat:

F_VALUE STRING10
Zitat:

Kann sowohl ein Zeichen ('+'), ein digitaler Wert ('0'/'1') oder ein analoger Wert ('-999.99' bis '999.99') sein. In der ersten Version waren das sogar getrennte Felder. Varchar(10) soll das absolute Maximum darstellen. Der Platzbedarf sollte ja nur so groß sein wie die Daten oder?
Das kommt mir sehr seltsam vor. Ist es vllt. so daß ein Gerät nur 0/1 und ein anderes -999.99...+999.999 liefert?
aber wieso dann 10 Stellen?
wäre es da nicht vllt. besser ein Char (0,1,A..z..) und ein float-Feld zu nutzen?
(ich kenn die FB-Typen nicht sooo genau)

Noch ein Nachsatz zum Platzsparen. es ist Blödsinn Informationen so zu verstümmeln, daß sie u.U. wertlos werden - die Erhöhung eines Basidatums gehört für mich dazu. Aber die Einstellung Festplattenkapazität mißt sich in TByte da kann ich auch mal ein paar GByte über die Leitung schicken baut beim Anwender gewaltig Frust auf wenn er, weil sein Netzanschluß unterdimensioniert ist, wieder einmal 2 Minuten auf eine Antwort/Sendung warten darf.
(nichts für ungut, aber heute war unser Firmennetz wieder vollkommen zu ...)

Gruß
K-H

Gruß
K-H

Dejan Vu 2. Mai 2014 17:29

AW: Firebird Datenbankgröße
 
Zitat:

Zitat von p80286 (Beitrag 1257738)
... ich auch mal ein paar GByte über die Leitung schicken baut beim Anwender gewaltig Frust auf wenn er, weil sein Netzanschluß unterdimensioniert ist, wieder einmal 2 Minuten auf eine Antwort/Sendung warten darf.
(nichts für ungut, aber heute war unser Firmennetz wieder vollkommen zu ...)

Das ist ärgerlich. Wenn die Daten durch eine Leitung sollen, würde ich auch überlegen, wie ich das optimieren kann (sparse array), aber in einer DB achtet man auf korrekte Datengrößen. Bei einer Produktions-DB achtet man auf 3NF, aber bei einem Datengrab achtet man auf performante Auswertbarkeit.

Wenn also die Messdaten wirklich nur abgelegt werden sollen, ist eine Einzelspeicherung u.U. auch ein Overkill. Du könntest die Daten einfach in ein 'Array Of TRecord' ablegen und z.B. jeweils Arrays a 1000 Werte mit Zeitstempel ablegen. Ist zwar ziemlich bescheuert, aber mit SQL willst Du an die Einzeldaten dann ja eh nicht. Man kann auch zippen, um Redundanzen herauszuziehen und so z.B. eine ganze Stunde Messdaten eines temperierten Raumes (da ändert sich dann nicht viel) ziemlich platzsparend unterbringen. Die Daten sind in einem BLOB und der ist in einer separaten Datei und bis auf den Header in der Tabelle ist alles andere dynamisch.

haentschman 2. Mai 2014 18:04

AW: Firebird Datenbankgröße
 
Liste der Anhänge anzeigen (Anzahl: 1)
Gut, ich drösel das mal auf: :P

1 Gerät, 1-100 Devices(Busadressen) im 485er Bus. Jedes Device hat unterschiedliche Parameter (F_PARAMETER_ID) (Anzahl und Typ) welche von mir vor dem Datenabholen eine eindeutige ID bekommen. Diese wird dann in den RecordDaten den Bezug zum Gerät/Adresse herstellen.
Im Schnitt hat jedes Device(Busadresse) 13 Parameter, mal mehr mal weniger. Jeder Parameter kann entweder einen String (*, +), einen Index (0-4), einen Boolean (0,1) oder einen Float Wert (-999.99 - 999.99) haben. Deshalb die Speicherung als Char was alles abdeckt.
Beispiel: Bild 1

Zitat:

...aber mit SQL willst Du an die Einzeldaten dann ja eh nicht
Doch allerdings. Bsp. "Alle Daten der Parameter 100 und 101 im Zeitraum von bis" -> als Grafik

Zitat:

6Stellig halte ich für arg wenig
Damit war die ParameterID gemeint. 100 Adressen * 13 Parameter = 1300 bei Autoinc. :zwinker: Meine Aussage "unbekannt. Vermute 6 stellig." war eine Verwechslung. Es gibt noch eine ParameterID innerhalb des Devices(Busadresse) welche nur innerhalb der Adresse eindeutig ist.

Zitat:

Bei 10 Geräten über 10 Jahre und 300 Tagen sind das gerade mal 33 Meßwerte am Tag.
Im aktuellen Fall wird jeder Parameter 15 sekündlich aufgezeichnet. Dies kann auf sekündlich verringert werden.
damit ergeben sich pro Minute 100 Adressen * 13 Parameter * 4 = 5200 Datensätze/ Meßwerte

Zitat:

wäre es da nicht vllt. besser ein Char (0,1,A..z..) und ein float-Feld zu nutzen?
Deswegen habe ich ja als Datenbankfeld den "kleinsten gemeinsamen Nenner". Aktuell probiere ich als Value Char(7) und als PowerState Char(1) aus. Ich tippe auf 1,2GB statt 1,6GB wie vorher

hstreicher 2. Mai 2014 19:07

AW: Firebird Datenbankgröße
 
Firebird verwendet eine RLE Komprimierung mit einem Byte für die Länge, es ist also für den Speicherbedarf egal ob das Feld als
Varchar(10) oder Varchar(100) definiert wird, wenn es meist weniger sind wie 8 Char im Varchar

das Varchar hat ein Integer(?16Bit?) als Länge das Varchar(10) belegt also maximal 12 Byte (Single Byte Charset vorrausgesetzt)

Auf der anderen Seite hat ein CHAR Feld immer nur die angegebene Länge also Char(10) hat eine Länge von 10
wird aber mit Spaces gepadded

zu beachten ist hier natuerlich auch der definierte Zeichensatz

IBExpert 3. Mai 2014 11:34

AW: Firebird Datenbankgröße
 
zum vor und nachteil von char oder varchar bei Firebird:

Beim Speichern braucht Firebird für ein varchar mit gleichem Inhalt 2 Byte mehr als wenn es in einem Char gleicher maximallänge gespeichert wäre. Darin speichert Firebird die Datenlänge. Bei x Millionen Records also schon ein Vorteil, wenn man den char nimmt, der braucht diese beiden Bytes nicht. Abgesehen von den beiden Längenbytes speichert Firebird Inhalte von char und varchar in gleicher Länge, d.h. nahezu immer die reinen benutzten bytes plus ein wenig Overhead (lange chars/varchars mal ausgenommen).

Leider kein Vorteil ohne Nachteil, denn während varchars im Netzwerk als reine Nutzdaten + overhead übertragen werden, werden chars mit Leerzeichen aufgefüllt, leider auch + overhead. Bei den Beispieldaten hier sind das mit 3 Records 20 Byte (188 zu 168 Byte) weniger, also ca. 10 % weniger netzwerktraffic, wenn man den varchar nimmt. Da das Netzwerk meistens wesentlich langsamer ist als der Zugriff auf die Festplatte bzw der bereits im Ram gecachten Daten, ist bei netzwerkintensiven Programmen meistens der varchar vorteilhaft, bei archivierten Daten, die selten abgefragt werden oder wirklich festen Längen aber manchmal eben auch der char.
Dann bringt es dann ggf. wesentlich mehr, die von dir beschriebenen Varianten der Messwerte über Nachschlagetabellen mit einem 4 Byte integer als Foreign Key zu verbinden, wenn man schon um jedes Byte kämpfen will.

Datenpaket mit varchar

Code:
 
CREATE TABLE T1 (
    ID  BIGINT NOT NULL,
    TXT VARCHAR(20)
);

Daten

ID    TXT
1    ABC
2    ABCDEF
3    ABCDEFGHIJKLMNOP

SQL

select * from T1

Netzwerkprotokoll Ausschnitt mit tcpipexpert erstellt

## 12:06:16:597 Channel 2; DATA (Server -> Client): Length= 168
00 00 00 09 00 00 00 01 00 00 00 00 00 00 00 00                 
00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00                 
00 00 00 42 00 00 00 00 00 00 00 01 00 00 00 00     B          
00 00 00 01 00 00 00 00 00 00 00 03 41 42 43 00              ABC
00 00 00 00 00 00 00 42 00 00 00 00 00 00 00 01         B      
00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 06                 
41 42 43 44 45 46 00 00 00 00 00 00 00 00 00 42  ABCDEF        B
00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 03                 
00 00 00 00 00 00 00 10 41 42 43 44 45 46 47 48          ABCDEFGH
49 4A 4B 4C 4D 4E 4F 50 00 00 00 00 00 00 00 42  IJKLMNOP      B
00 00 00 64 00 00 00 00                             d

Datenpaket mit char

Code:
CREATE TABLE T2 (
    ID  BIGINT NOT NULL,
    TXT CHAR(20)
);

ID   TXT
1   ABC
2   ABCDEF
3   ABCDEFGHIJKLMNOP

SQL

select * from T2

Netzwerkprotokoll Ausschnitt mit tcpipexpert erstellt

12:06:29:002 Channel 2; DATA (Server -> Client): Length= 188
00 00 00 09 00 00 00 01 00 00 00 00 00 00 00 00                 
00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00                 
00 00 00 42 00 00 00 00 00 00 00 01 00 00 00 00     B          
00 00 00 01 00 00 00 00 41 42 43 20 20 20 20 20          ABC    
20 20 20 20 20 20 20 20 20 20 20 20 00 00 00 00                 
00 00 00 42 00 00 00 00 00 00 00 01 00 00 00 00     B          
00 00 00 02 00 00 00 00 41 42 43 44 45 46 20 20          ABCDEF
20 20 20 20 20 20 20 20 20 20 20 20 00 00 00 00                 
00 00 00 42 00 00 00 00 00 00 00 01 00 00 00 00     B          
00 00 00 03 00 00 00 00 41 42 43 44 45 46 47 48          ABCDEFGH
49 4A 4B 4C 4D 4E 4F 50 20 20 20 20 00 00 00 00  IJKLMNOP      
00 00 00 42 00 00 00 64 00 00 00 00                 B  d

mkinzler 3. Mai 2014 12:00

AW: Firebird Datenbankgröße
 
Zitat:

Beim Speichern braucht Firebird für ein varchar mit gleichem Inhalt 2 Byte mehr als wenn es in einem Char gleicher maximallänge gespeichert wäre.
Da in diesem Fall die Maximallänge als absolutes Maxiumium zu sehen ist, und im Durchschnitt viel kürze Daten vorliegen, ist VARCHAR wohl die richtige Wahl.


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:00 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz