2009-09-06 7 views
8

SQLite docs specifica che il formato preferito per l'archiviazione dei valori datetime nel DB è l'uso di Julian Day (utilizzando le funzioni integrate).Devo occuparmi di memorizzare i dati DateTime come julianday in SQLite?

Tuttavia, tutti i framework che ho visto in python (pysqlite, SQLAlchemy) memorizzano i valori datetime.datetime come stringhe con formattazione ISO. Perché stanno facendo così?

In genere sto cercando di adattare i framework per archiviare datetime come julianday, ed è piuttosto doloroso. Ho iniziato a dubitare che valga la pena.

Si prega di condividere la vostra esperienza in questo campo con me. Ha senso avere julianday?

risposta

5

Memorizzarlo in entrambe le direzioni. I framework possono essere impostati a modo loro e se il tuo è in attesa di trovare una colonna grezza con una stringa formattata ISO, è probabilmente più doloroso andare in giro che ne vale la pena.

La preoccupazione di avere due colonne è la coerenza dei dati ma sqlite dovrebbe avere tutto il necessario per farlo funzionare. La versione 3.3 supporta i vincoli di controllo e i trigger. Leggi su date and time functions. Dovresti essere in grado di fare tutto ciò di cui hai bisogno interamente nel database.

CREATE TABLE Table1 (jd, isotime); 

CREATE TRIGGER trigger_name_1 AFTER INSERT ON Table1 
BEGIN 
    UPDATE Table1 SET jd = julianday(isotime) WHERE rowid = last_insert_rowid(); 
END; 

CREATE TRIGGER trigger_name_2 AFTER UPDATE OF isotime ON Table1 
BEGIN 
    UPDATE Table1 SET jd = julianday(isotime) WHERE rowid = old.rowid; 
END; 

E se non puoi fare ciò che ti serve all'interno del DB, puoi scrivere un'estensione C per eseguire la funzionalità che ti serve. In questo modo non avrai bisogno di toccare la struttura se non quella di caricare la tua estensione.

+0

Grazie per questo suggerimento! È una grande idea e risolve tutti i miei problemi con questo problema. –

+1

Perché dovresti _want_ memorizzarlo in entrambi i modi? L'unico vero vantaggio di memorizzare i giorni giuliani su stringhe con formattazione ISO è lo spazio di archiviazione. Se il tuo framework si aspetta una stringa formattata ISO, basta usarlo. Tutte le [funzioni datetime] di SQLite (http://www.sqlite.org/lang_datefunc.html) può elaborare stringhe ISO tanto quanto i giorni giuliani. – Martijn

6

Julian Day è utile per tutti i tipi di calcoli di date, ma può memorizzare il tempo in modo decente (con ore, minuti e secondi precisi). In passato ho utilizzato sia i campi del giorno giuliano (per le date), sia i secondi dell'epoca (per le istanze datetime), ma solo quando avevo esigenze specifiche di calcolo (di date e rispettivamente di tempi). La semplicità delle date e dei dati datati ISO, penso, dovrebbe farne la scelta preferita, diciamo circa il 97% delle volte.

+1

Così continuerò con le impostazioni predefinite del quadro fino a quando non ho motivazione esplicita di non farlo. Grazie! –

+0

Potresti descrivere un po 'perché la precisione di julianday per ore, minuti e secondi non è abbastanza buona? –

+0

@Slava, pensa di rappresentare "1 secondo": 1/86400.'th di un giorno, che NON può essere rappresentato con precisione come la parte frazionaria di un float a doppia precisione perché la rappresentazione di quest'ultimo è in forma binaria e 86400 non è un potenza di due. –

0

Perché 2010-06-22 00:45:56 è molto più facile da leggere per un essere umano di 2455369.5318981484. Le date di testo sono ottime per eseguire query ad hoc in SQLiteSpy o SQLite Manager.

Lo svantaggio principale, naturalmente, è che le date di testo richiedono 19 byte invece di 8.

1

Ma in genere, l'Umano non legge direttamente dal database. tempo frazionale su un Giorno Giuliano è facilmente convertito in readible umana (per esempio)

void hour_time(GenericDate *ConvertObject) 
{ 
    double frac_time = ConvertObject->jd; 
    double hour   = (24.0*(frac_time - (int)frac_time)); 
    double minute  = 60.0*(hour - (int)hour); 
    double second  = 60.0*(minute - (int)minute); 
    double microsecond = 1000000.0*(second - (int)second); 

    ConvertObject->hour   = hour; 
    ConvertObject->minute  = minute; 
    ConvertObject->second  = second; 
    ConvertObject->microsecond = microsecond; 

}; 
Problemi correlati