2010-04-06 7 views
10

Problema originale: Qual è il formato di colonna corretto per un timestamp unix?SQlite: formato della colonna per timestamp unix; Tipi interi

La rete è piena di confusione: alcuni messaggi rivendicazione SQLite ha alcun tipo senza segno - o qualunque, o con eccezione del tipo int 64bit (ma ci sono (contromisure) esempi che richiamano INTEGER). La pagina dei tipi di dati lo menziona solo in un grande esempio. Suppone anche che ci sia un intero di 6 byte, ma non ne fornisce un nome. Sembra che i miei tentativi con INTEGER siano i timestamp firmati di unix firmati a 4 byte come numeri negativi. Ho sentito che alcuni sistemi restituiscono anche timestamp a 64 bit. OTOH Non mi piace troppo sprecare 4 byte per archiviare 1 bit in più (il bit più in alto del timestamp), e anche se dovessi scegliere un formato di dati più grande, preferirei quello da 6 byte. Ho persino visto un post che afferma che SQLite unix timestamp è di tipo REAL ...

Problema completo: Qualcuno potrebbe chiarire questo pasticcio?

risposta

12

Le dimensioni di un intero

Tutte le colonne nei database SQLite sono internamente a larghezza variabile. Lo file format memorizza numeri interi in 1, 2, 3, 4, 6 o 8 byte, a seconda di quanto è grande il numero, più un byte nell'intestazione per indicare la dimensione. Quindi, in totale, le date Unix memorizzate come numeri interi richiederanno 5 byte fino al 2038-01-19 e 7 byte dopo.

Dal punto di vista dell'utente dell'API C, tutti gli interi sono firmati a 64 bit.

Il tipo di colonna

Non importa se si dichiara la colonna come INTEGER, INTEGER, BIGINT, o qualsiasi altra cosa.Anything with "INT" in it has integer affinity. E, come accennato in precedenza, tutti gli interi sono firmati a 64 bit, ma di solito non vengono memorizzati in quel modo.

+0

Grazie. In realtà non aiuta che la distinzione tra i quattro nomi int "zucchero sintattico", i numeri interi C (più la rappresentazione interna) e la memorizzazione su disco dei numeri non siano chiaramente enfatizzati in vari documenti, e vari valori e nomi sono dati senza molto contesto. La tua risposta spiega la differenza e le specificità di ciascuno e mi ha permesso di capire veramente la struttura del sistema. –

0

La mia preferenza sarebbe per un numero intero a 64 bit. Il classico caso di un intero a 32 bit senza segno è con secondi dal 1970-01-01 si esaurisce nel 2038. Vedere http://en.wikipedia.org/wiki/Unix_time e http://en.wikipedia.org/wiki/Year_2038_problem. Con un numero intero senza segno a 64 bit, sei al sicuro

+0

Ancora, anche il 48 bit sarebbe molto più che adeguato, e poiché si tratta di un sistema embedded, 2-4 byte ridondanti per riga è molto più di quanto mi importi di rinunciare liberamente. –

0

Puoi dare un esempio di cosa intendi con "Sembra che i miei tentativi con INTEGER siano di firmare firmati unix firmati con un byte come numeri negativi."?

Se non l'hai già suggerisco di leggere i documenti SQLite su datatypes (sezione 1.2 Data e ora Tipo dati) e date and time functions.

+0

http://stackoverflow.com/questions/2401804/negative-dates-in-sqlite –

0

Se ci si trova su un sistema embedded in cui la situazione della memoria è critica, è possibile considerare di ridurre la precisione spostando il valore a 64 bit di diversi bit (ottenendo una precisione di 2, 4, 8 ... secondi anziché 1 secondo) e utilizzando un valore a 32 bit per memorizzarlo.

+0

In alternativa, se i tuoi dati coprono un intervallo inferiore a 194 giorni, puoi utilizzare un'epoca più recente in modo che un conteggio di secondi richieda solo 3 byte invece di 4. – dan04

11

SQLite does not hanno tipi non firmati. Questo è direttamente dall'autore principale, così come lo docs. Inoltre, non ha le larghezze delle colonne fisse per i numeri interi; la larghezza effettiva su disco è un dettaglio di implementazione.

SQLite non ha un tipo di dati data o ora. Tuttavia, ha funzioni di data che possono operare su stringhe ISO8601 (TEXT), numeri di giorno di Julian (REAL) e timestamp Unix (INTEGER).

Quindi, se si decide di rendere il vostro campo di tempo di un timestamp Unix, sa che può memorizzare fino a 64-bit interi con segno, ma i valori si memorizzano ora dovrebbe effettivamente occupare 32 bit sul disco, anche se il valore di origine è un time_t a 64 bit.

+0

Se potessi accettare due risposte, la tua e quella di Dan lo sarebbero. –