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?

0voto

Mike Woodhouse Punkte 50241

Wie bereits an anderer Stelle erwähnt, sollten die Indizes für die booleschen Spalten entfernt werden, da sie mit ziemlicher Sicherheit langsamer sind (wenn sie überhaupt verwendet werden) als ein Tabellenscan und unnötig Platz verbrauchen werden.

Ich würde in Erwägung ziehen, eine einfache Komprimierung der Wörter vorzunehmen, Huffman-Kodierung ist ziemlich gut für diese Art von Dingen. Außerdem würde ich mir die Signaturen ansehen: Sortieren Sie die Spalten in der Reihenfolge der Buchstabenhäufigkeit und machen Sie sich nicht die Mühe, nachstehende Nullen zu speichern, die impliziert werden können. Ich schätze, Sie könnten diese auch Huffman-kodieren.

Natürlich immer vorausgesetzt, dass Ihre kodierten Strings SQLite nicht stören.

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