È buona pratica Java archiviare le date come lunghe nel database?

Il motivo per cui lo faccio è che le date memorizzate come oggetti data in qualsiasi database tendono a essere scritte in un formato specifico, che può essere molto diverso da quello che è necessario presentare all’utente sul front-end. Penso inoltre che sia particolarmente utile se la tua applicazione sta tracciando informazioni da diversi tipi di archivi di dati. Un buon esempio potrebbe essere la differenza tra un object data MongoDB e SQL.

Tuttavia, non so se questa pratica è raccomandata. Devo continuare a memorizzare date come long (tempo in millisecondi) o come oggetti data?

Non posso parlare per questo in relazione a MongoDB, ma nel database SQL no, non è la migliore pratica. Ciò non significa che potrebbe non esserci il caso d’uso occasionale, ma “best practice”, no.

Memorizzali come date, recuperale come date. La soluzione migliore è impostare il database in modo da memorizzarli come UTC (in modo approssimativo, “GMT”) in modo che i dati siano trasferibili e utilizzare orari locali diversi a seconda dei casi (ad esempio, se il database viene utilizzato da utenti geograficamente diversi) e gestire eventuali conversioni da UTC a ora locale nel livello applicazione (ad esempio, tramite Calendar o una libreria di date di terze parti).

Memorizzare le date come numeri significa che il tuo database è difficile da segnalare, eseguire query ad hoc contro, ecc. Ho fatto quell’errore una volta, non è una che ripeterò senza una buona ragione. 🙂

Dipende molto da:

  • Quale database stai usando e il suo supporto data / ora
  • Il tuo cliente ha bisogno (es. Quanto sei contento di credere che tu userai sempre Java)
  • Quali informazioni stai davvero cercando di rappresentare
  • I tuoi strumenti diagnostici

Il terzo punto è probabilmente il più importante. Pensa a cosa significano veramente i valori che stai cercando di memorizzare. Anche se chiaramente non stai usando Noda Time, si spera che la mia pagina di guida utente sulla scelta del tipo di Noda Time da utilizzare in base ai tuoi dati di input possa aiutarti a pensare chiaramente a questo.

Se usi sempre Java, e il tuo database non ha un supporto terribilmente buono per i tipi di data / ora, e stai solo cercando di rappresentare un “istante in tempo” (piuttosto che, per esempio, un istante in un particolare fuso orario, o una data / ora locale con un offset, o solo una data / ora locale, o solo una data …), e sei a tuo agio nel scrivere strumenti diagnostici per convertire i tuoi dati in forms più leggibili da umani, quindi archiviare un long è ragionevole. Ma questa è una lunga lista di “se”.

Se si desidera essere in grado di eseguire la manipolazione della data nel database, ad esempio chiedendo tutti i valori che si verificano il primo giorno del mese, è consigliabile utilizzare un tipo di data / ora, facendo attenzione ai fusi orari. (La mia esperienza è che la maggior parte dei database sono almeno scioccanti e documentati male quando si tratta dei loro tipi di data / ora.)

In generale, dovresti usare qualunque tipo sia in grado di soddisfare tutte le tue esigenze ed è la rappresentazione più naturale per quel particolare ambiente. Quindi, in un database che ha un tipo di data / ora che non ti dà problemi quando interagisci con esso (ad esempio, eseguendo conversioni arbitrarie del fuso orario in modo non richiesto), usa quel tipo. Renderà ogni cosa più facile.

Il vantaggio di utilizzare una rappresentazione più “primitiva” (ad es. Un intero a 64 bit) è proprio il fatto che il database non si scherza con esso. Stai effettivamente nascondendo il significato dei dati dai databae, con tutti i normali pro e contro (principalmente contro) di questo approccio.

Dipende da vari aspetti. Quando si usa lo standard “secondi dall’epoca” e qualcuno usa solo la precisione intera, le sue date sono limitate all’intervallo di anni 1970-2038.

Ma c’è anche un problema di precisione. Ad esempio, il tempo di unix ignora i secondi intercalari . Ogni giorno è definito avere lo stesso numero di secondi. Quindi, quando si calcolano i delta di tempo tra unix time, si ottiene un errore.

Ma la cosa più importante è che tu pensi che tutte le tue date siano completamente conosciute , poiché la tua rappresentazione non ha la possibilità di dimezzare solo le date a metà. In realtà, ci sono molti eventi che non conosci ad una precisione di secondo (o persino di ms). Quindi è una caratteristica se una rappresentazione consente di specificare, ad esempio, solo una precisione del giorno . Idealmente, memorizzeresti le date con le loro informazioni di precisione.

Inoltre, dì che stai costruendo un’applicazione per il calendario. C’è tempo, ma c’è anche l’ora locale. Molto spesso, hai bisogno di entrambe le informazioni disponibili. Quando si pianifica di sovrapposizioni, puoi ovviamente farlo al meglio in un tempo sincronizzato, quindi i lunghi saranno buoni qui. Se tuttavia si desidera anche assicurarsi di non pianificare eventi al di fuori delle 9-20 ora locale , è inoltre necessario conservare le informazioni sul fuso orario . Per tutto ciò che riguarda più di una posizione, è davvero necessario includere il fuso orario nella rappresentazione della data. Supponendo che tu possa semplicemente convertire tutte le date che vedi nell’ora locale corrente è abbastanza ingenuo.

Si noti che le date in SQL possono portare a situazioni strane. Uno dei miei preferiti è la seguente assurdità MySQL :

 SELECT * FROM Dates WHERE date IS NULL AND date IS NOT NULL; 

può restituire record che hanno la data 0000-00-00 00:00:00 , anche se questo viola la comprensione popolare della logica.

Poiché questa domanda è etichettata con MongoDB: MongoDB non memorizza le date in String o cosa no, in realtà lo memorizzano a lungo ( http://www.mongodb.org/display/DOCS/Dates ):

Un valore BSON Date memorizza il numero di millisecondi dall’epoca Unix (1 gennaio 1970) come numero intero a 64 bit. v2.0 +: questo numero è firmato in modo che le date precedenti al 1970 siano memorizzate come numeri negativi.

Dato che MongoDB non ha piani immediati per utilizzare le complesse funzioni di gestione delle date (come ottenere solo un anno per le query ecc.) Che SQL ha all’interno delle query standard non c’è un vero svantaggio, potrebbe infatti ridurre le dimensioni degli indici e della memoria.

C’è una cosa da tenere in considerazione qui, il framework di aggregazione: http://docs.mongodb.org/manual/reference/aggregation/#date-operators ci sono cose strane e meravigliose che puoi solo con il tipo di data BSON supportato MongoDB, tuttavia, se ciò che ti interessa dipende dalle tue domande.

Ti vedi come se avessi bisogno delle funzioni dei framework di aggregazione? Oppure l’alloggiamento dell’object extra in testa sarebbe un dolore?

La mia opinione personale è che il tipo di data BSON è un object talmente piccolo che per archiviare un documento senza esso sarebbe determentale per l’intero sistema e la sua compatibilità futura senza un motivo apparente. Quindi, sì, userei il tipo di data BSON piuttosto che un lungo e considererei buona pratica farlo.

Non penso che sia una buona pratica archiviare le date tanto a lungo perché, ciò significherebbe che non si sarebbe in grado di fare nessuna delle query specifiche della data. piace :

 where date between 

Inoltre, non saremo in grado di ottenere la data dell’anno dalla tabella utilizzando facilmente query SQL.

È meglio utilizzare un convertitore di formato data singolo nel livello java e convertire la data in quello e utilizzare un unico formato nell’intera applicazione.

IMHO, la memorizzazione delle date in DB sarà la migliore se puoi usare le stringhe. Evita quindi che i dati non necessari salgano e scendano al server, se non hai bisogno di tutti i campi in Calendar. C’è un sacco di dati in Calendar e ogni istanza di Calender è abbastanza pesante.

Quindi memorizzalo come String, con solo i dati richiesti e convertilo nuovamente in Calendar, quando ne hai bisogno e usali.