Größe einer Sqlite Datenbank in bytes

  • 7 Antworten
  • Letztes Antwortdatum
Micka

Micka

Fortgeschrittenes Mitglied
1
Hallo,

ich arbeite derzeit an einer APP. Um mich zwischen verschiedenen Datenbanken zu entscheiden wollte ich mir mal angucken wie groß die Datenbanken so werden.
Gibt es eine Möglichkeit zu ermitteln wie groß eine Tabelle bzw eine ganze Datenbank in SQlite ist? Also wieviel Bytes groß?

Folgendes habe ich schon probiert, habe aber festgestellt die Größe Ändert sich nicht bei einzelnen Inserts. Erst wenn ich eine große Masse an Zeilen einfüge ändert sich der Wert.
Code:
SQLiteDatabase db = this.getWritableDatabase();
long size = new File(db.getPath()).length();
return size;
 
Das ist bei Datenbanken normal, dass die in dem darunter liegenden Datesystem "blockweise" allozieren und diesen Bereich dann stückweise füllen oder darin Daten hin und her schieben. Frage ist, was du als "Größe" wissen willst. Wenn du DBs vergleichen willst, gehört der Verwaltungsoverhaed sicher dazu und damit auch diese vorallziierten Bereiche.
 
  • Danke
Reaktionen: Micka
Hy, danke erstmal für die schnelle Antwort.
Das Problem ist das folgende. Ich entwerfe eine App mit sehr hohem Datenaufkommen. ca 10000 Bluetooth Pakete pro Sekunde. Datenmenge wird maximal 1MBaud. Nun ist die Frage welche Datenbank packt es am schnellsten das ganze wegzuschreiben geklärt, in eigenens Tests liegt eine objektorientierte Dantenbank , Perst, klar vorne.
Eine Weitere Frage ist aber wielange wir diese Bluetooth Aufzeichnung laufen lassen können. Dafür benötige ich die Größe die ein Empfangenes Objekt innerhalb der Datenbank belegt.

Mein Empfanges Objekt sieht wie folgt aus:

Code:
public class MyData extends Persistent
{
    public int VARIABLE1;
    public byte VARIABLE2;    
    public byte VARIABLE3;   
    public int VARIABLE4;
    public int VARIABLE5;
    public byte[] VARIABLE6;
    public String strKey;
    public int intKey;
    public String toString()
    {
         return intKey + ":" + strKey+ ":" + VARIABLE1 + ":" + VARIABLE2 + ":" + VARIABLE13 + ":" + VARIABLE4 + ":" + VARIABLE5;
    }
}

Durch DBMS eigene Komprimierungen und so ist die Größe ja aber eben nicht die Größe eines Java Objekts. Deshalb die Frage, wie groß ist ein Objekt in der Datenbank.
 
Ich könnte hingehen und solange inserts machen bis sich das Ergebnis der Größenabfrage ändert. Die Alte Größe geteilt durch die Anzahl an Zeilen-1 ergibt dann ungefähr die Größe die ein Objekt in der Datenbank hat. Fragt sich wie sauber das ist. der Overhead in Form von Tabellenkopf und so verfälscht das ganze natürlich minimal.
 
Sauber ist nur die Theorie. :D:D:D

Jede DB speichert ihre Daten anders, es gibt also keinen Standardweg, die Größe zu ermitteln. Wenn du ein Persistenzlayer dazwischen hast, wird auch das einen Overhead erzeugen (soll der mit zählen oder nicht?). Aber sag noch mal, warum genau du die Größe eines Objektes "innerhalb der Datenbank" wissen willst. Vllt ist ja schon die Frage "falsch" (no offence!). Momentan klingt das so, als wenn du wissen willst, wie lange du loggen kannst, bis die "Platte" voll ist. Da ist die Dateigröße die Kennzahl die du wissen musst.

Ich würde einfach mal messen.
 
Hallo,
Ja es geht hauptsächlich darum zu entscheiden wie lange mitgeloggt werden kann. Das ganze ist als Seminararbeit für die Uni gedacht und muss daher einen gewissen grad an "Sauberkeit" haben. Mir ist gestern direkt aufgefallen bei meinem Versuch die Ergebnisse fallen nach jedem durchlauf anders aus. Frage mich gerade woran das liegt.

anbei mal der Code mit dem ich versucht habe die Größe zu ermitteln. ist ein wenig kommentiert.
zu den Methoden:
getSize() liefert die Anzahl an Zeilen zurück die aktuell gepeichert sind.
getDataSize() liefert die Größe der Datei zurück
insertOneFakeData(MyData data) fügt eine Zeile in die Datenbank ein
Code:
public long getObjectSize(MyData data)
    {
        if(getSize() == 0) //verhindert das teilen durch 0 falls die Datenbank noch leer ist.
        {
            insertOneFakeData(data);
        } 
        long vorherdatasize = getDataSize();
        long checkdatasize;
        do //diese Schleife schreibt den aktuellen Block voll so das ich weiss ab dem wievielten Eintrag der neue Block begonnen hat
        {
            insertOneFakeData(data);
            checkdatasize = getDataSize();
        }while(checkdatasize == vorherdatasize);
        //Größe hat sich geändert, Size -1 nehmen um alte Anzahl an Einträgen abzurechnen
        // alte Anzahl entspricht der Anzahl die in den alten Block noch reingepasst haben.
        long vorhersize = getSize()-1;       //Anzahl der Elemente
        vorherdatasize = getDataSize();    //Größe der Datei
        do
        {
            insertOneFakeData(data);
            checkdatasize = getDataSize();
        }while(checkdatasize == vorherdatasize);
        long nachherdatasize = checkdatasize;
        long nachhersize = getSize()-1;           //Anzahl der Elemente die in die alte Größe gepasst haben, deswegen -1, quasi bevor der neue Block reserviert wurde
        long size = nachhersize - vorhersize;                        //Die Anzahl an Elementen im letzten beschriebenen Datenblock
        long datasize = nachherdatasize - vorherdatasize;     //Die Größe des letzten beschriebene Datenblocks
        long objectSize = datasize / size;                            //Mein Versuch die Größe eines Objektes (einer Zeile) auszurechnen
        return objectSize;

komischerwiese kommen immer andere Werte raus. Ich lasse das ganze beim App Start einmal ausführen und "Toaste" das Ergebnis aus. Es kommt immer 8, 16, 4096 oder 2048 raus.
 
Gibt es noch andere Vorschläge wie man die Größe ermitteln kann?
 
Micka schrieb:
Gibt es noch andere Vorschläge wie man die Größe ermitteln kann?

Im Quellcode von SQLite nachschauen wie die einzelnen (wenigen) Datentypen gespeichert werden.
Im Datenbank-Datei selbst nachschauen. https://www.sqlite.org/fileformat2.html

Optimierungen in Betracht ziehen: https://www.sqlite.org/withoutrowid.html

Auch interessant. Wenn die Häufigkeit bestimmter Werte in deiner Messung von denen im Anwendungsfall
abweichen ergibt das auch wieder unterschiedliche Größen ...

^If the affinity of a column is REAL and that column contains a value that can be converted to an integer without loss of information (if the value contains no fractional part and is not too large to be represented as an integer) then the column may be stored in the record as an integer. ^SQLite will convert the value back to floating point when extracting it from the record.
 
Zuletzt bearbeitet:
Zurück
Oben Unten