6

Questo è molto simile a another question che è stato chiuso come non una vera domanda. Ho provato a modificarlo per renderlo valido per la riapertura, ma mi è stato detto che avrei fatto meglio a fare una nuova domanda.Come archiviare datetime in SQLite

Sto sviluppando su Android e ho bisogno di memorizzare valori datetime in un database SQLite per tenere traccia degli eventi ricorrenti che generano notifiche. Dovrò anche essere in grado di interrogare il database in base agli intervalli di tempo.

Il SQLite documentation afferma che non supporta i tipi di date specifici, ma che le date possono essere rappresentati utilizzando tipi di testo, reale, o intero:

TESTO come stringhe ISO8601 ("AAAA-MM-GG HH: MM : SS.SSS ").

REALE come numeri del giorno giuliano, il numero di giorni da mezzogiorno a Greenwich il 24 novembre, 4714 a.C. secondo il calendario gregoriano prolettico.

INTEGER come ora Unix, il numero di secondi dal 1970-01-01 00:00:00 UTC.

I vantaggi di ciascuna sembrano inizialmente essere:

  • TESTO utile per migliorare la leggibilità nel database con possibilità di visualizzare direttamente dopo (nessuna trasformazione necessario), ma costoso se i calcoli devono essere eseguite su loro. Presenta possibili errori da fusi orari.
  • REALE utile per date precedenti al 1970, valido per calcoli o confronti di date. Non rappresenta l'ora del giorno, solo i giorni.
  • INTEGER utile per calcoli o confronti datetime, ottima compatibilità poiché è uno standard ampiamente supportato.

Questo suono è corretto? L'utilizzo di un INTEGER per i tempi di trasmissione delle query consente di interrogare gli intervalli di tempo in modo notevolmente più rapido rispetto a quando si utilizza TEXT? Qualcos'altro che non ho considerato?

Dato il mio caso d'uso, quale di queste soluzioni sarebbe la migliore?

+1

Che tipo di dati ci si aspetta (centinaia, migliaia, milioni di record)? SQLite è pensato per essere un piccolo db, e come tale qualsiasi cosa su poche centinaia di record è eccessivo. Ti suggerirei di utilizzare il testo per archiviare i dati. Solo se ne si vede la necessità (è necessario calcolare il datetime su migliaia di record), quindi modificare i dati sottostanti del datetime su un real o un int. –

+0

Al massimo il numero di record sarebbe nelle centinaia basse. Suppongo che ciò significhi che le prestazioni non saranno un problema, ma il testo sembra complicare i confronti e sono preoccupato dell'errore che l'ora legale potrebbe introdurre. – Matthew

risposta

4

TESTO utile per migliorare la leggibilità nel database con possibilità di visualizzare direttamente dopo (nessuna trasformazione necessario)

Il formato ISO è solitamente non utilizzato per la visualizzazione; devi trasformare anche questo. (Questo formato è più utile per il debugging.)

costoso se i calcoli devono essere eseguite su di essi

Con database, il collo di bottiglia di solito è l'I/O. Dubito che vedrete mai una query in cui il formato effettivo dei valori di data farebbe una differenza notevole.

Presenta possibili errori da fusi orari.

Il formato TESTO non ha un identificatore di fuso orario, ma nessuno degli altri formati. Se si dice che tutti i valori DB sono in UTC, non c'è differenza.

REALE utile per le date prima del 1970

Tutti i formati supportano tutti gli anni compresi tra 0 e 9999. (numeri interi possono essere negativi.)

non rappresenta ora del giorno, solo pochi giorni .

L'ora del giorno è rappresentata come un valore frazionario.

INTEGER ... ottima compatibilità poiché è uno standard ampiamente supportato.

Ma Java utilizza millisecondi, non secondi.

Qualcos'altro che non ho considerato?

Il formato di output predefinito della maggior parte del built-in date functions è TEXT.


dato il mio caso d'uso, quale di queste soluzioni sarebbe meglio?

Direi TEXT, ma non credo che ci sarebbe molta differenza.

0

Non rappresenta l'ora del giorno, solo i giorni.

Ecco a cosa serve la parte frazionaria di REAL.

L'utilizzo di un INTEGER per data/ora consente di interrogare gli intervalli di tempo in modo notevolmente più rapido rispetto all'utilizzo di TEXT?

Molto probabilmente. Non riesco a immaginare uno scenario in cui i confronti tra stringhe siano più veloci dei confronti tra interi, in particolare per le colonne indicizzate nelle query.

Qualcos'altro che non ho considerato?

Non ho idea se si è considerato the effects of gamma rays on man-in-the-moon marigolds, ma non è importante qui.:-)

Dato il mio caso d'uso, quale di queste soluzioni sarebbe la migliore?

INTEGER, IMHO.

1

Le risposte qui saranno principalmente di opinione, ma se fossi in te, userei il tipo INTEGER e memorizzerò il timestamp di unix. Sembra meno dipendente dal formato conversioni/analisi ed è lo standard più universalmente supportato.

0

Memorizza ora data UTC come numero intero a 8 byte a 64 bit in SQLite. Millis sence 1970.

long time= System.currentTimeMillis(); 

con un database indicizzato avrete risposta eccellente per circa 10k fila su ordine da e tra la lettura dei dati datetime.

Lasciare le manipolazioni del fuso orario al livello vista poiché un database con tutte le ore UTC funzionerà in tutto il mondo.

Non memorizzare date come testo così antico e che non ha posto in un'applicazione moderna.

Eviterei di memorizzare solo le date perché le app moderne prendono in considerazione quando si verifica un evento. È possibile memorizzare i dati con 8 byte. Ma se è necessario, è sufficiente inserire la data di iso in un numero intero 1999-12-31 come 19991231 e memorizzare un numero intero di 4 byte in sqllite.

Problemi correlati