7 Stimmen

Wie kann man die Größe einer sqlite3-Datenbank für das iPhone verringern?

edit: Vielen Dank für die vielen Antworten. Hier sind die Ergebnisse nach der Anwendung der Optimierungen so weit:

  • Umstellung auf Sortierung der Zeichen und Lauflängenkodierung - neue DB-Größe 42M
  • Weglassen der Indizes für die Booleschen Werte - neue DB-Größe 33M

Das Schöne daran ist, dass dafür keine Änderungen am iPhone-Code erforderlich sind.

Ich habe eine iPhone-Anwendung mit einem großen Wörterbuch im Sqlite-Format (nur Lesen). Ich bin auf der Suche nach Ideen, um die Größe der DB-Datei zu reduzieren, die derzeit sehr groß ist.

Hier ist die Anzahl der Einträge und die daraus resultierende Größe der sqlite DB:

franks-macbook:DictionaryMaker frank$ ls -lh dictionary.db
-rw-r--r--  1 frank  staff    59M  8 Oct 23:08 dictionary.db
franks-macbook:DictionaryMaker frank$ wc -l dictionary.txt
  453154 dictionary.txt

...durchschnittlich etwa 135 Bytes pro Eintrag.

Hier ist mein DB-Schema:

create table words (word text primary key, sowpods boolean, twl boolean, signature text)
create index sowpods_idx on words(sowpods)
create index twl_idx on words(twl)
create index signature_idx on words(signature)

Hier sind einige Beispieldaten:

photoengrave|1|1|10002011000001210101010000
photoengraved|1|1|10012011000001210101010000
photoengraver|1|1|10002011000001210201010000
photoengravers|1|1|10002011000001210211010000
photoengraves|1|1|10002011000001210111010000
photoengraving|1|1|10001021100002210101010000

Das letzte Feld stellt die Buchstabenhäufigkeiten für die Anagrammsuche dar (jede Position liegt im Bereich 0..9). Die beiden Booleschen Werte stehen für Unterwörterbücher.

Ich muss Abfragen wie diese durchführen:

select signature from words where word = 'foo'
select word from words where signature = '10001021100002210101010000' order by word asc
select word from words where word like 'foo' order by word asc
select word from words where word = 'foo' and (sowpods='1' or twl='1')

Eine Idee, die ich habe, ist, die Buchstabenfrequenzen effizienter zu kodieren, z. B. binär als Blob (vielleicht mit RLE, da es viele Nullen gibt?) zu kodieren. Irgendwelche Ideen, wie man das am besten erreicht, oder andere Ideen, um die Größe zu reduzieren? Ich erstelle die DB in Ruby und lese sie auf dem Telefon in Objective C.

Gibt es auch eine Möglichkeit, Statistiken über die DB zu erhalten, damit ich sehen kann, was den meisten Platz verbraucht?

5voto

Jared Punkte 38791

Haben Sie versucht, den Befehl "vacuum" einzugeben, um sicherzustellen, dass Sie keinen zusätzlichen Speicherplatz in der Datenbank haben, den Sie vergessen haben zu reclamen?

4voto

Doug Currie Punkte 39584

Entfernen Sie die Indizes auf sowpods und twl - sie sind wahrscheinlich nicht hilfreich für Ihre Abfragezeiten und nehmen definitiv viel Platz weg.

Sie können Statistiken über die Datenbank abrufen, indem Sie sqlite3_analyzer から SQLite-Download-Seite .

3voto

recursive Punkte 80517

Ein völlig anderer Ansatz ist die Verwendung einer Glockenfilter anstelle einer umfassenden Datenbank. Ein Bloom-Filter besteht im Grunde aus einer Reihe von Hash-Funktionen, die jeweils mit einem Bitfeld verbunden sind. Für jedes legale Wort wird jede Hash-Funktion ausgewertet und das entsprechende Bit im entsprechenden Bitfeld gesetzt. Der Nachteil ist, dass es theoretisch möglich ist, falsch-positive Ergebnisse zu erhalten, aber diese können mit genügend Hashes minimiert/praktisch eliminiert werden. Der Vorteil ist eine enorme Platzersparnis.

2voto

Robert Simmons Punkte 483

Ich kenne nicht alle Anwendungsfälle für das Unterschriftsfeld, aber es scheint, dass es von Vorteil wäre, stattdessen eine alphabetisierte Version des Wortes zu speichern.

1voto

Eran Galperin Punkte 84916

Am besten ist es, die Komprimierung zu verwenden, die SQLite derzeit leider nicht nativ unterstützt. Glücklicherweise hat sich jemand die Zeit genommen, ein Kompressionsverlängerung Das könnte genau das sein, was Sie brauchen.

Andernfalls würde ich empfehlen, die Daten hauptsächlich in komprimierter Form zu speichern und bei Bedarf zu dekomprimieren.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X