2012-05-30 4 views
16

Ich habe eine 7,4 GB csv-Datei. Nach der Konvertierung in eine SQLite-Datenbank mit einer python script ist die Ausgabe-DB 4,7 GB, etwa 60% der ursprünglichen Größe.Komprimiert sqlite3 Daten?

Die CSV hat rund 150.000.000 Zeilen. Es hat Header:

tkey,ipaddr,healthtime,numconnections,policystatus,activityflag 

Und jede Zeile sieht so etwas wie

261846,172.10.28.15,2012-02-03 16:15:00,22,1,1 

Das Skript healthtime verwendet die Daten in Tabellen 192 Tabellen

Als ich diese Zahlen zu spalten sah, ich nahm ich an hatte irgendwo einen Fehler gemacht. Wie groß sollte eine Verringerung der Dateigröße sein, wenn ich die Healthtime 192 Mal anstelle von 150 Millionen Mal schreibe?

EDIT: Sobald ich das geschrieben habe, realisierte ich die Antwort. Ich entferne etwa 40% der Saite, daher die 40% ige Verringerung der Größe.

Edit 2 Lassen Sie uns den Unterschied in der Größe zwischen dem Klartext berechnen:

"261846,172.10.28.15,2012-02-03 16:15:00,22,1,1" 

und der Datenbankeintrag:

db(261846,'172.10.28.15',22,1,1) 

Zunächst einmal fallen wir 46 bis 26 Zeichen in Klartextdarstellung.

Die übrigen Zeichen sind:

"261846,172.10.28.15,22,1,1" 

oder 26 Bytes. Wenn jede ganze Zahl in 32 Bit (4 Bytes) gespeichert werden soll, dann haben wir:

12 Bytes (ipaddr) + 4 Bytes * 4 (ganze Felder) = 28 Bytes.

Es sieht also so aus, als würde die Konvertierung in Ganzzahlen den Speicher etwas weniger effizient machen, und all meine Gewinne kommen durch die Reduzierung der Anzahl der in jeder Zeile gespeicherten Zeichen.

+6

Offensichtlich ist SQLite ein Binärformat, während CSV Text ist. 60% Größenunterschied kann dadurch verursacht werden. –

+1

Sorry, was ist Healthtime? Eine schnelle Google-Suche hat nichts ausgemacht. –

+0

healthtime ist nur der Name des Feldes. – Maus

Antwort

23

SQLite führt keinen Komprimierungsalgorithmus aus, speichert jedoch Daten in einer Binärdatei anstelle einer Textdatei. Das bedeutet, dass die Daten effizienter gespeichert werden können, z. B. mithilfe einer 32-Bit-Zahl (4 Byte), um 10,000,000 darzustellen, anstatt sie als 8 Byte Text (oder mehr, wenn die Datei Unicode ist) zu speichern.

Hier sind weitere Details über die SQL Database File Format, wenn Sie interessiert sind.

Macht das Sinn?

+4

Es ist erwähnenswert, dass SQLite nur so viele Bytes wie nötig verwendet. Zum Beispiel benötigt der Wert 7 nur ein Byte. –

+2

Der Wert 7 benötigt zwei Bytes: eine serielle Varint, die in diesem Fall ein Byte lang wäre, und der Wert, der in diesem Fall ein Byte wäre. Der serielle Typ ist für jeden Wert in der Datenbank vorhanden, für Nullen und Zahlen ein Byte und für Blobs und Text eine variable Länge von bis zu 9 Byte. So benötigt z. B. eine 32-Bit-Ganzzahl 5 Byte, eine 64-Bit-Gleitkommazahl 9 Byte, da sie in beiden Fällen einen Ein-Byte-Serientyp hat. – thomasrutter

17

SQLite komprimiert standardmäßig keine Daten, die auf die Festplatte geschrieben werden; SQLite hat jedoch eine Reihe von "proprietären Erweiterungen" für diese und andere Zwecke. Suchen Sie in den Links nach ZIPVFS wie folgt.

http://www.sqlite.org/support.html und http://www.hwaci.com/sw/sqlite/prosupport.html

Sie können durch Codierung Felder als ganze Zahlen eine Menge „Kompression“ in Ihren Daten erreichen. Zum Beispiel wurde eine IP-Adresse entwickelt, um in ein Wort (4 Bytes) zu passen.Jeder Oktett der Adresse kann in einem Byte eines Wortes dargestellt werden.

string[] octets = '172.168.0.1'.split('.') 
int ip = atoi(octets[0]) << 24 
ip |= atoi(octets[1]) << 16 
ip |= atoi(octets[2]) << 8 
ip |= atoi(octets[3]) 

Zusätzlich Ihre Zeitstempel können in Unix Zeit dargestellt werden, die die Anzahl der Sekunden seit der Epoche ist.

UPDATE mytable SET healthtime = CAST(strftime('%s',healthtime) AS INTEGER); 

See the Date and Time functions

Notiere die CAST Direktive in der oben SQL: SQLite erzwingt nicht die Art auf einer Säule, so dass Sie als String gespeichert, um eine Gruppe von Ziffern aufweisen kann; Erhöhen Sie Ihre Feldgröße mehr als nötig (dies wird auch dazu führen, dass sich bestimmte Abfragen merkwürdig verhalten).

Noch eine Sache: Feldgröße ist nicht der einzige Teil der Geschichte. Denken Sie daran, dass Indizes auch Platz beanspruchen und Indizes für Ganzzahlen effizienter sind - in Bezug auf Datenträgergröße und Leistung.