2012-05-30 11 views
16

Mam plik csv o wielkości 7,4 GB. Po przekonwertowaniu go do bazy danych sqlite przy pomocy python script, wyjściowy DB wynosi 4,7 Gb, około 60% pierwotnego rozmiaru.Czy program sqlite3 kompresuje dane?

Plik CSV ma około 150 000 000 wierszy. Posiada nagłówek:

tkey,ipaddr,healthtime,numconnections,policystatus,activityflag 

a każdy wiersz wyglądał

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

Skrypt wykorzystuje healthtime podzielić dane w tabelach 192 tabele

Kiedy pierwszy raz zobaczyłem te numery, Przypuszczałem I popełnił błąd w jakimś miejscu. Jak duże zmniejszenie rozmiaru pliku powinienem oczekiwać od dodatkowej skuteczności pisania tylko 192 razy czasu zdrowia zamiast 150 000 000 razy?

EDYCJA: Jak tylko to opublikowałem, uświadomiłem sobie odpowiedź. Usuwam około 40% napisu, stąd zmniejszenie rozmiaru o 40%.

Edycja 2 Policzmy różnicę w wielkości pomiędzy zwykłym tekstem:

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

a wejściem bazy danych:

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

Przede wszystkim, możemy spaść od 46 do 26 znaków w reprezentacji tekstowej.

Pozostałe znaki są:

"261846,172.10.28.15,22,1,1" 

lub 26 bajtów. Jeśli każda liczba całkowita musi być przechowywana w 32 bitach (4 bajty), to mamy:

12 bajtów (ipaddr) + 4 bajty * 4 (pola całkowite) = 28 bajtów.

Wygląda na to, że konwersja na liczby całkowite powoduje, że pamięć jest nieco mniej wydajna, a wszystkie moje zyski pochodzą od liczby znaków przechowywanych w każdym wierszu.

+6

Oczywiście sqlite jest formatem binarnym, a csv jest tekstem. Różnica w wysokości 60% może być z tego powodu spowodowana. –

+1

Przepraszam, co to jest czas na zdrowie? Szybkie wyszukiwanie google niczego nie zmieniło. –

+0

zdrowie to tylko nazwa pola. – Maus

Odpowiedz

23

SQLite nie uruchamia algorytmu kompresji, ale zapisuje dane w pliku binarnym zamiast w pliku tekstowym. Co oznacza, że ​​dane mogą być przechowywane bardziej efektywnie, na przykład przy użyciu 32-bitowej (4-bajtowej) liczby do reprezentowania 10,000,000 zamiast przechowywania jej jako 8 bajtów tekstu (lub więcej, jeśli plik jest w Unicode).

Oto więcej informacji na temat SQL Database File Format, jeśli jesteś zainteresowany.

Czy to ma sens?

+4

Warto zauważyć, że SQLite używa tylko tyle bajtów, ile potrzeba. Na przykład wartość 7 wymaga tylko jednego bajtu. –

+2

Wartość 7 potrzebuje dwóch bajtów: wariancie typu szeregowego, który w tym przypadku ma być jeden bajt, oraz wartość, która w tym przypadku byłaby jednobajtowa. Typ szeregowy jest obecny dla każdej wartości w bazie danych, jest to jeden bajt dla wartości null i liczb i jest zmienną długością do 9 bajtów dla obiektów typu blob i tekstu. Na przykład 32-bitowa liczba całkowita zajmuje 5 bajtów, a zmienna 64-bitowa 9 bajtów, ponieważ w obu przypadkach ma jednobajtowy typ szeregowy. – thomasrutter

17

SQLite domyślnie nie kompresuje danych zapisywanych na dysku; jednak SQLite ma zestaw "własnych rozszerzeń" do tego i innych celów. Szukaj ZIPVFS w linkach w następujący sposób.

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

Można osiągnąć wiele „kompresji” w danych poprzez zakodowanie pola jako liczby całkowite. Na przykład zaprojektowany został adres IP w celu dopasowania do słowa (4 bajty).Każda oś adresu może być reprezentowana w jednym bajcie słowa.

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]) 

Dodatkowo twój znacznik czasu może być reprezentowany w czasie Unix, który jest liczbą sekund od epoki.

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

See the Date and Time functions

Uwaga dyrektywa w powyższym SQL CAST: SQLite nie wymusza typ na kolumnie, więc może masz grupę cyfr zapisanych w postaci ciągu znaków; zwiększając rozmiar pola bardziej niż to konieczne (spowoduje to również, że pewne zapytania zachowują się dziwnie).

Jeszcze jedno: rozmiar pola to nie jedyna część historii. Pamiętaj, że indeksy zajmują również miejsce, a indeksy na liczbach całkowitych są bardziej wydajne - pod względem wielkości dysku i wydajności.