Wie würden Sie die Größe der Core Data SQLite-Datei minimieren oder komprimieren?

8

Ich habe eine 215-MB-CSV-Datei, die ich analysiert und in Kerndaten gespeichert habe, die in meine eigenen benutzerdefinierten Objekte eingepackt sind. Das Problem ist meine Kerndaten sqlite Datei ist ca. 260MB. Die CSV-Datei enthält etwa 4,5 Millionen Zeilen Daten über das Transportsystem meiner Stadt (Bushaltestelle, Zeiten, Routen usw.).

Ich habe versucht, Attribute so zu modifizieren, dass Arrays von Strings, die Stop-Zeiten darstellen, stattdessen als NSData-Dateien gespeichert werden, aber aus irgendeinem Grund bleibt die Dateigröße immer bei etwa 260 MB.

Ich kann keine App dieser Größe versenden. Ich bezweifle, dass irgendjemand eine 260MB App herunterladen würde, selbst wenn dies bedeutet, dass sie den gesamten Fahrplan der Stadt darauf haben.

Gibt es Möglichkeiten, den verwendeten Speicherplatz zu komprimieren oder zu minimieren (auch wenn das bedeutet, dass keine Kerndaten verwendet werden, bin ich bereit, Vorschläge zu hören)?

BEARBEITEN: Ich möchte jetzt gerade ein Update bereitstellen, weil ich ungläubig auf die Dateigröße gestarrt habe. Mit einigen cleveren Manipulationen mit Strings, Indexierung und Datenbanknormalisierung im Allgemeinen konnte ich die Größe auf 6.5MB oder 2.6MB reduzieren, wenn sie komprimiert sind. Etwa 105.000 Objekte, die in den Kerndaten gespeichert sind und die vollständigen Details des Transportsystems der Stadt enthalten. Ich bin jetzt fast in Tränen. D ':

    
Jim T 21.10.2011, 23:29
quelle

3 Antworten

8

Wenn Ihre ursprüngliche CSV-Datei nicht wirklich doof codiert ist, ist es unwahrscheinlich, dass die Größe nicht unter 100M liegt, egal wie stark Sie sie komprimieren. Das ist immer noch sehr groß für eine App. Die Lösung besteht darin, Ihre Daten in einen Webdienst zu verschieben. Vielleicht möchten Sie wichtige Teile herunterladen und zwischenspeichern, aber wenn Sie über Millionen von Datensätzen sprechen, scheint das Abrufen von einem Server am besten zu sein. Außerdem muss ich glauben, dass sich das Transportsystem von Zeit zu Zeit ändert, und es wäre frustrierend, wenn man bei jeder Einzelanpassung eine 10-MB-App upgraden müsste.

Ich habe das gesagt, aber tatsächlich gibt es einige Dinge, die Sie in Betracht ziehen sollten:

  • Booleans in ein Bitfeld verschieben. Sie können 64 Booleans in einen NSUInteger einfügen. (Und verwenden Sie keine volle 64-Bit-Ganzzahl, wenn Sie nur 8 Bits benötigen. Speichern Sie das kleinste, was Sie können.)
  • Komprimieren Sie, wie Sie Zeiten speichern. Es gibt nur 1440 Minuten an einem Tag. Sie können das in 2 Bytes speichern. Transitzeiten sind im Allgemeinen nicht zu zweit; Sie brauchen kein CGFloat.
  • Wochentage und Daten können ebenfalls komprimiert werden.
  • Offensichtlich sollten Sie alle Zeichenfolgen normalisieren. Sehen Sie sich die CSV für doppelte String-Werte in vielen Zeilen an.
  • Ich würde generell eher sqlite als Core-Daten für diese Art von Problem empfehlen. Bei Core Data handelt es sich mehr um Objektpersistenz als um Rohdatenspeicherung. Die Tatsache, dass Sie eine 20% -ige Aufblähung gegenüber CSV sehen (die selbst nicht sehr effizient ist), ist für dieses Problem keine gute Richtung.
  • Wenn Sie noch enger werden möchten und keine sehr guten Suchfunktionen benötigen, können Sie gepackte Datenblobs erstellen. Früher habe ich das an Telefonschaltern gemacht, wo der Speicher extrem eng war. Sie erstellen eine Bitfeldstruktur und weisen 5 Bits für eine Variable und 7 Bits für eine andere usw. zu. Damit und mit etwas Zeitverschachtelung von Dingen, damit sie sich korrekt an Wortgrenzen ausrichten, können Sie ziemlich eng werden.

Da Ihnen die anfängliche Downloadgröße am meisten am Herzen liegt und Sie möglicherweise Ihre Daten später für einen schnelleren Zugriff erweitern möchten, können Sie eine sehr domänenspezifische Komprimierung in Betracht ziehen. Zum Beispiel habe ich in der obigen Diskussion erwähnt, wie man für eine Zeit auf 2 Bytes herunterkommt. Sie könnten wahrscheinlich in vielen Fällen auf 1 Byte herunterkommen, indem Sie Zeiten seit dem letzten Mal als Delta-Minuten speichern (da die meisten Ihrer Zeiten immer um ziemlich kleine Schritte zunehmen werden, wenn es Bus- und Zugfahrpläne sind). Wenn Sie die Datenbank verlassen, können Sie eine sehr eng codierte Datendatei erstellen, die Sie beim ersten Start in eine Datenbank extrahieren können.

Sie können auch domänenspezifisches Wissen verwenden, um Ihre Strings in kleinere Tokens zu codieren. Wenn ich das New Yorker U-Bahn-System kodiere, würde ich bemerken, dass einige Strings sehr auftauchen, wie "Avenue", "Road", "Street", "East" usw. Ich würde diese wahrscheinlich als nicht druckbares ASCII wie ^ kodieren A, ^ R, ^ S, ^ E usw. Ich würde wahrscheinlich "138 Street" als zwei Bytes (0x8A13) codieren. Dies basiert natürlich auf meinem Wissen, dass è (0x8a) nie in den NY U-Bahn-Haltestellen auftaucht. Es ist keine allgemeine Lösung (in Paris könnte es ein Problem sein), aber es kann verwendet werden, um Daten zu komprimieren, von denen Sie spezielle Kenntnisse haben. In einer Stadt wie Washington DC glaube ich, dass ihre Straße mit der höchsten Nummer die 38. Straße ist, und dann gibt es eine Richtung mit 4 Werten. Sie können das also in zwei Bytes codieren, zuerst ein Token mit "nummerierter Straße" und dann ein Bitfeld mit 2 Bits für den Quadranten und 6 Bits für die Straßennummer. Diese Art des Denkens kann möglicherweise Ihre Datengröße erheblich verkleinern.

    
Rob Napier 22.10.2011 00:05
quelle
0

Sie können möglicherweise eine Datenbanknormalisierung durchführen.

Suchen Sie nach etwas, das möglicherweise redundant ist oder dieselben Werte in mehreren Zeilen gespeichert sind. Wahrscheinlich müssen Sie Ihre Datenbank neu strukturieren, damit diese doppelten Werte (falls vorhanden) in separaten Tabellen gespeichert und dann anhand von IDs aus ihrer ursprünglichen Zeile referenziert werden.

    
Claus Broch 21.10.2011 23:43
quelle
0

Wie groß ist die SQLite-Datei komprimiert? Wenn es zufriedenstellend klein ist, wäre es am einfachsten, es komprimiert zu versenden und es dann zu NSCachesDirectory zu dekomprimieren.

    
rob mayoff 21.10.2011 23:53
quelle

Tags und Links