Dovrei usare il tipo di dati datetime o timestamp in MySQL?


Risposte:


1829

I timestamp in MySQL vengono generalmente utilizzati per tenere traccia delle modifiche ai record e vengono spesso aggiornati ogni volta che il record viene modificato. Se si desidera memorizzare un valore specifico, è necessario utilizzare un campo datetime.

Se intendevi decidere di utilizzare un timestamp UNIX o un campo datetime MySQL nativo, scegli il formato nativo. Puoi eseguire calcoli all'interno di MySQL in questo modo ("SELECT DATE_ADD(my_datetime, INTERVAL 1 DAY)")ed è semplice cambiare il formato del valore in un timestamp UNIX ("SELECT UNIX_TIMESTAMP(my_datetime)")quando richiedi il record se vuoi operare su di esso con PHP.


981
Una differenza importante è che DATETIMErappresenta una data (come si trova in un calendario) e un'ora (come si può osservare su un orologio da parete), mentre TIMESTAMPrappresenta un punto temporale ben definito. Questo potrebbe essere molto importante se l'applicazione gestisce i fusi orari. Quanto tempo è stato "2010-09-01 16:31:00"? Dipende dal fuso orario in cui ti trovi. Per me è stato solo pochi secondi fa, per te potrebbe rappresentare un momento nel futuro. Se dico 1283351460 secondi da "1970-01-01 00:00:00 UTC", sai esattamente di che momento parlo. (Vedi l'eccellente risposta di Nir di seguito). [Unico inconveniente: intervallo valido].
MattBianco,

121
Un'altra differenza: le query con datetime "nativo" non verranno memorizzate nella cache, ma le query con data / ora - lo saranno.
OZ_

39
"I timestamp in MySQL generalmente vengono utilizzati per tenere traccia delle modifiche ai record" Non pensare che sia una buona risposta. I timestamp sono molto più potenti e complicati di così, come affermano MattBianco e Nir. Tuttavia, la seconda parte della risposta è molto buona. È vero quello che ha detto Blivet ed è un buon consiglio.
santiagobasulto,

10
Inoltre 1 nota importante, DATETIME e TIMESTAMP possono usare CURRENT_TIMESTAMP, NOW () rispettosamente come valore predefinito, ma DATE ad esempio no, perché usa "registrazione" per impostazione predefinita, quindi per risolvere la questione U dovrebbe scrivere Il tuo trigger per quella tabella, per inserire la data corrente (senza ora) nel campo / col con il tipo mysql DATA.
Arthur Kushman,

14
@DavidHarkness: la documentazione dice "Per specificare le proprietà automatiche, utilizzare le clausole DEFAULT CURRENT_TIMESTAMP e ON UPDATE CURRENT_TIMESTAMP" dev.mysql.com/doc/refman/5.0/en/timestamp-initialization.html
Plap

916

In MySQL 5 e versioni successive, i valori TIMESTAMP vengono convertiti dal fuso orario corrente in UTC per l'archiviazione e convertiti nuovamente da UTC nel fuso orario corrente per il recupero. (Ciò si verifica solo per il tipo di dati TIMESTAMP e non per altri tipi come DATETIME.)

Per impostazione predefinita, il fuso orario corrente per ogni connessione è l'ora del server. Il fuso orario può essere impostato in base alla connessione, come descritto nel supporto del fuso orario del server MySQL .


11
questa presentazione di OReilly è molto utile per questo argomento (scusate il PDF) cdn.oreillystatic.com/en/assets/1/event/36/…
gcb

13
Riguarda anche la natura dell'evento: - Una videoconferenza (TIMESTAMP). Tutti gli operatori dovrebbero vedere un riferimento a un istante di tempo assoluto adeguato al suo fuso orario. - A tempo di attività locale (DATETIME), dovrei fare questo compito al 31/03/2014 alle 9:00 AM, non importa se quel giorno lavoro a New York o Parigi. Inizierò a lavorare alle 8:00 ora locale del luogo in cui sarò quel giorno.
yucer

1
Quindi se cambio il fuso orario del server, il valore di TIMESTAMP rimarrà lo stesso o cambierà anche ??
Andrew

3
@Andrew dal momento che è UTC, rimarrà UTC. Tuttavia, la conversione all'indietro passerà al "nuovo" fuso orario del server.
nembleton,

@yucer - Non consiglio di pensarlo in quel modo. L'utilizzo più coerente in un'economia globale è la conversione di tutti i tempi in UTC per l'archiviazione. Per convenzione, considera Datetime come un campo UTC. Ciò comporta un onere per tutte le attività che inseriscono i tempi dei dati per effettuare la conversione in UTC, ma è un progetto più pulito a lungo termine. Naturalmente, presentare le informazioni all'utente in base alle loro impostazioni correnti. Se l'utente desidera inserire "09:00 a Parigi", quindi impostare l'ora di Parigi, quindi immettere 09:00. Quindi chiunque si trovi a New York può facilmente trovare a che ora devono essere svegli a loro volta, alla teleconferenza.
ToolmakerSteve

524

Uso sempre i campi DATETIME per qualsiasi cosa diversa dai metadati di riga (data di creazione o modifica).

Come menzionato nella documentazione di MySQL:

Il tipo DATETIME viene utilizzato quando sono necessari valori che contengono sia la data che l'ora. MySQL recupera e visualizza i valori DATETIME nel formato "AAAA-MM-GG HH: MM: SS". L'intervallo supportato è compreso tra '1000-01-01 00:00:00' e '9999-12-31 23:59:59'.

...

Il tipo di dati TIMESTAMP ha un intervallo compreso tra '1970-01-01 00:00:01' UTC e '2038-01-09 03:14:07' UTC. Ha proprietà diverse, a seconda della versione di MySQL e della modalità SQL in cui è in esecuzione il server.

È molto probabile che tu raggiunga il limite inferiore di TIMESTAMP in uso generale, ad es. Memorizzazione della data di nascita.


195
puoi anche raggiungere facilmente il limite superiore se sei nel settore bancario o immobiliare ... I mutui trentennali vanno oltre il 2038 ora
Kip

16
Naturalmente, usa i timestamp Unix a 64 bit. Ad esempio, in Java, new Date().getTime()ti dà già un valore a 64 bit.
osa

5
+1 per DATETIME: nel nostro flusso di dati, da SQL Server del Physical Store per l'acquisto e la fattura, trasferito a MySQL Server per il Virtual Store sulla pagina Web, DATETIME è migliore per la modifica Data-Ora poiché questo tipo di dati esiste anche in Transact -SQL. Ma TIMESTAMP significa altra cosa in Transact-SQL, è binario come ROWVERSION, sebbene MySQL TIMESTAMP sia simile a DateTime. Quindi evitiamo l'uso di TIMESTAMP per la compatibilità dei due DB.
jacouh,

10
Nessuna idea. È un problema molto più grande del semplice MySQL e non esiste una soluzione semplice: en.wikipedia.org/wiki/Year_2038_problem Non credo che MySQL possa semplicemente dichiarare che i timestamp sono ora a 64 bit e supporre che tutto vada bene. Non controllano l'hardware.
scronide,

5
Una data di nascita può essere un DATETIME se conosci l'ora della nascita, come faccio io per la mia.
Kris Craig,

322

Il sotto esempi mostrano come il TIMESTAMPtipo data cambia i valori dopo la modifica time-zone to 'america/new_york'dove DATETIMEè immutato.

mysql> show variables like '%time_zone%';
+------------------+---------------------+
| Variable_name    | Value               |
+------------------+---------------------+
| system_time_zone | India Standard Time |
| time_zone        | Asia/Calcutta       |
+------------------+---------------------+

mysql> create table datedemo(
    -> mydatetime datetime,
    -> mytimestamp timestamp
    -> );

mysql> insert into datedemo values ((now()),(now()));

mysql> select * from datedemo;
+---------------------+---------------------+
| mydatetime          | mytimestamp         |
+---------------------+---------------------+
| 2011-08-21 14:11:09 | 2011-08-21 14:11:09 |
+---------------------+---------------------+

mysql> set time_zone="america/new_york";

mysql> select * from datedemo;
+---------------------+---------------------+
| mydatetime          | mytimestamp         |
+---------------------+---------------------+
| 2011-08-21 14:11:09 | 2011-08-21 04:41:09 |
+---------------------+---------------------+

Ho convertito la mia risposta in articolo in modo che più persone possano trovare questo utile MySQL: tipi di dati Datetime e data / ora .


55
Bene, in realtà il DATETIMEtempo effettivo è cambiato con il cambio di fuso orario, TIMESTAMPnon è cambiato ma la rappresentazione umana è cambiata.
Flindeberg,

3
Sembra che questo comando non funzioni in MySQL 5.6 set time_zone="america/new_york";
Manjunath Reddy,

Ecco la risposta per il problema del fuso orario impostato. stackoverflow.com/questions/3451847/mysql-timezone-change
Manjunath Reddy

2
Concordo con @flindeberg. Il timestamp rappresenta l'ora corretta, non il datetime, dopo il cambio del fuso orario
Nitin Bansal,

193

La differenza principale è che DATETIME è costante mentre TIMESTAMP è influenzato time_zonedall'impostazione.

Quindi importa solo quando hai - o potresti avere in futuro - cluster sincronizzati tra i fusi orari.

In parole più semplici: se ho un database in Australia e prendo un dump di quel database per sincronizzare / popolare un database in America, il TIMESTAMP si aggiornerà per riflettere l'ora reale dell'evento nel nuovo fuso orario, mentre DATETIME riflette ancora l'ora dell'evento nel fuso orario au .

Un ottimo esempio di DATETIME in cui TIMESTAMP avrebbe dovuto essere usato è su Facebook, in cui i loro server non sono mai abbastanza sicuri di cosa sia accaduto nei fusi orari. Una volta avevo una conversazione in cui il tempo diceva che stavo rispondendo ai messaggi prima che il messaggio fosse effettivamente inviato. (Questo, naturalmente, potrebbe anche essere stato causato da una traduzione errata del fuso orario nel software di messaggistica se i tempi fossero stati pubblicati anziché sincronizzati.)


83
Non penso sia un buon modo di pensare. Memorizzerei ed elaborerei tutte le date in UTC e mi assicurerei che il front-end lo visualizzi in base al fuso orario specificato. Questo approccio è semplice e prevedibile.
Kos

8
@Kos: non è la memorizzazione e l'elaborazione di tutte le date in UTC esattamente ciò che TIMESTAMP sta facendo internamente? (Quindi convertirlo per visualizzare il fuso orario locale?)
carbocation

10
il mio fuso orario locale? Come fa il tuo DB a conoscere il mio fuso orario? ;-) Di solito c'è abbastanza elaborazione tra il database e l'interfaccia utente. Faccio la localizzazione solo dopo l'intera elaborazione.
Kos,

3
@Koz: il mio database non conosce il fuso orario dei tuoi database:! Ma conosce il timestamp. Il database conosce le proprie impostazioni del fuso orario e le applica nell'interpretazione / rappresentazione del timestamp. 1:01 dell'11 dicembre 2013 a Pechino, in Cina, non è lo stesso momento temporale dell'01: 01 dell'11 dicembre 2013 a Sydney, in Australia. Google: "fusi orari" e "meridiano principale".
ekerner,

2
MySQL converte i valori TIMESTAMP dal fuso orario corrente in UTC per l'archiviazione e torna da UTC al fuso orario corrente per il recupero. (Ciò non si verifica per altri tipi come DATETIME.) Dev.mysql.com/doc/refman/5.5/en/datetime.html
Mahdyfo

125

Prendo questa decisione su base semantica.

Uso un timestamp quando devo registrare un punto fisso (più o meno) nel tempo. Ad esempio, quando un record è stato inserito nel database o quando sono state eseguite alcune azioni dell'utente.

Uso un campo datetime quando la data / ora può essere impostata e modificata in modo arbitrario. Ad esempio, quando un utente può salvare gli appuntamenti di modifica successivi.


data / ora- punto fisso nel tempo, tempo universale coordinato datetime - relativo a un punto di vista, a un riferimento temporale (ej ora locale fuso orario), potrebbe essere .. Ora locale coordinata?
yucer

110

Consiglio di non utilizzare un campo DATETIME o TIMESTAMP. Se vuoi rappresentare un giorno specifico nel suo insieme (come un compleanno), usa un tipo DATE, ma se sei più specifico di quello, probabilmente sei interessato a registrare un momento reale invece di un'unità di ora (giorno, settimana, mese, anno). Invece di usare DATETIME o TIMESTAMP, usa un BIGINT e memorizza semplicemente il numero di millisecondi dall'epoca (System.currentTimeMillis () se stai usando Java). Questo ha diversi vantaggi:

  1. Si evita il blocco del fornitore. Praticamente ogni database supporta numeri interi in modo relativamente simile. Supponiamo di voler passare a un altro database. Vuoi preoccuparti delle differenze tra i valori DATETIME di MySQL e come Oracle li definisce? Anche tra le diverse versioni di MySQL, TIMESTAMPS ha un diverso livello di precisione. Solo di recente MySQL ha supportato i millisecondi nei timestamp.
  2. Nessun problema di fuso orario. Ci sono stati alcuni commenti approfonditi qui su ciò che accade con i fusi orari con i diversi tipi di dati. Ma è questa conoscenza comune e tutti i tuoi colleghi si prenderanno del tempo per impararla? D'altra parte, è piuttosto difficile sbagliare cambiando un BigINT in un java.util.Date. L'uso di un BIGINT fa cadere molti problemi con i fusi orari.
  3. Nessun problema di distanza o precisione. Non devi preoccuparti di ciò che sarà tagliato dagli intervalli di date future (TIMESTAMP va solo al 2038).
  4. Integrazione di strumenti di terze parti. Utilizzando un numero intero, è banale che strumenti di terze parti (ad esempio EclipseLink) si interfacciano con il database. Non tutti gli strumenti di terze parti avranno la stessa comprensione di un "datetime" di MySQL. Vuoi provare a capire in Hibernate se dovresti usare un oggetto java.sql.TimeStamp o java.util.Date se stai usando questi tipi di dati personalizzati? L'uso dei tipi di dati di base rende banale l'utilizzo di strumenti di terze parti.

Questo problema è strettamente correlato al modo in cui è necessario archiviare un valore in denaro (ovvero $ 1,99) in un database. Dovresti usare un decimale o il tipo di denaro del database o, peggio ancora, un doppio? Tutte e 3 queste opzioni sono terribili, per molte delle stesse ragioni sopra elencate. La soluzione è archiviare il valore del denaro in centesimi usando BIGINT, quindi convertire i centesimi in dollari quando si visualizza il valore per l'utente. Il compito del database è archiviare i dati e NON interpretarli. Tutti questi fantasiosi tipi di dati che vedi nei database (in particolare Oracle) aggiungono poco e ti fanno strada lungo il cammino verso il blocco dei fornitori.


12
Mi piace questa soluzione. La scadenza di TIMESTAMP nel 2038 è un grosso problema. Non è poi così lontano!
Charlie Dalsass,

4
@CharlieDalsass Pensi che il software attuale ci sarà quella volta :-P
Habeeb Perwad,

13
Rende difficile interrogare i dati per data se sono memorizzati come numero di millisecondi
Ali Saeed,

4
Questa è davvero la soluzione migliore se ti interessa la portabilità e la gestione degli utenti in più fusi orari o database in fusi orari diversi dagli utenti. TIMESTAMP potrebbe essere la strada da percorrere se non ha difetti di progettazione. Peccato che le soluzioni rotte abbiano ottenuto più voti perché sono state pubblicate in anticipo (anni!).
Tedesco

4
Ottima soluzione! E hai esattamente ragione di essere "bloccato". Quando hai l'abitudine di lasciare che gli altri "facciano il lavoro per te", allora inizi a perdere i pezzi che ti rendono programmatore.
fmc

98

TIMESTAMP è di 4 byte contro 8 byte per DATETIME.

http://dev.mysql.com/doc/refman/5.0/en/storage-requirements.html

Ma come scronide ha detto che ha un limite inferiore dell'anno 1970. È ottimo per tutto ciò che potrebbe accadere in futuro;)


186
Il futuro termina alle 2038-01-19 03:14:07 UTC.
MattBianco,

5
Questo è stupido. Ho pensato che il tipo TIMESTAMP sarebbe "pronto per il futuro" perché è relativamente nuovo. Non puoi preoccuparti di convertire datetime in UTC e viceversa ogni volta che lavori con diversi fusi orari. Avrebbero dovuto ingrandire TIMESTAMP .. almeno 1 byte in più. aggiungerà 68 * 255 = 17340 altri anni ... anche se non sarà allineato a 32 bit.
NickSoft,

10
Sai perché TIMESTAMP termina nel 2038? Perché è un numero intero e i numeri interi hanno un limite che è 2147483647. Penso che questo sia il motivo. Può essere se cambiano il suo tipo in varchar e cambiano il modo in cui manipolarlo, sarà "pronto per il futuro".
vinsa,

6
@vinsa, non credo che sarà pronto per il futuro per allora. Ricordi ancora il bug Y2K? Il 2038 sta arrivando.
Pacerier,

2
Entro il 2038, MySQL (se esiste ancora) aggiornerà semplicemente il campo TIMESTAMP per utilizzare più di 4 byte e consentire un intervallo più ampio
the_nuts

95
  1. TIMESTAMP è di quattro byte contro otto byte per DATETIME.

  2. I timestamp sono anche più chiari sul database e indicizzati più velocemente.

  3. Il tipo DATETIME viene utilizzato quando sono necessari valori che contengono sia la data che l'ora. MySQL recupera e visualizza i valori DATETIME nel formato "AAAA-MM-GG HH: MM: SS". L'intervallo supportato è compreso tra '1000-01-01 00:00:00 ′ e' 9999-12-31 23:59:59 ′.

Il tipo di dati TIMESTAMP ha un intervallo compreso tra '1970-01-01 00:00:01 ′ UTC e' 2038-01-09 03:14:07 ′ UTC. Ha proprietà diverse, a seconda della versione di MySQL e della modalità SQL in cui è in esecuzione il server.

  1. DATETIME è costante mentre TIMESTAMP viene effettuato dall'impostazione time_zone.

6
È necessario chiarire n. 4: il timestamp memorizzato è costante e non relativo (completamente agnostico) al fuso orario, mentre l'output visualizzato al momento del recupero è influenzato dal fuso orario della sessione richiedente. DATETIME è sempre relativo al fuso orario in cui è stato registrato e deve sempre essere considerato in quel contesto, una responsabilità che ora ricade sull'applicazione.
Christopher McGowan,

1
Bella risposta. Per aggiungere a questa risposta, se proviamo a memorizzare valori oltre a "2038-01-09 03:14:07", viene visualizzato un errore o viene archiviato come "registrazione 00:00:00". Stavo ottenendo questo errore per il mio database in quanto ha valori temporizzati (ai fini della crittografia).
KarthikS,

Inoltre, c'è un problema con DATETIME con valore DEFAULT su versioni di mysql inferiori a 5.5. dba.stackexchange.com/questions/132951/…
Velaro

47

Dipende dall'applicazione, davvero.

Considera di impostare un timestamp da un utente su un server a New York, per un appuntamento a Sanghai. Ora, quando l'utente si connette a Sanghai, accede allo stesso timestamp degli appuntamenti da un server con mirroring a Tokyo. Vedrà l'appuntamento all'ora di Tokyo, compensato dall'orario originale di New York.

Quindi per valori che rappresentano il tempo dell'utente come un appuntamento o un programma, il datetime è migliore. Consente all'utente di controllare la data e l'ora esatte desiderate, indipendentemente dalle impostazioni del server. L'ora impostata è l'ora impostata, non influenzata dal fuso orario del server, dal fuso orario dell'utente o dai cambiamenti nel modo in cui viene calcolata l'ora legale (sì, cambia).

D'altra parte, per i valori che rappresentano l'ora del sistema come le transazioni di pagamento, le modifiche alla tabella o la registrazione, utilizzare sempre i timestamp. Il sistema non sarà interessato dallo spostamento del server in un altro fuso orario o durante il confronto tra server in fusi orari diversi.

I timestamp sono anche più chiari sul database e indicizzati più velocemente.


L'applicazione non deve fare affidamento sul fuso orario del server. Un'applicazione dovrebbe SEMPRE selezionare il fuso orario nella sessione della connessione al database che utilizza prima di inviare qualsiasi query. Se una connessione è condivisa tra più utenti (ad es. Webapp), utilizzare UTC ed eseguire la conversione del fuso orario sul lato rendering.
dolmen,

42

2016 + : consiglio di impostare il fuso orario di Mysql su UTC e utilizzare DATETIME:

Qualsiasi framework front-end recente (Angular 1/2, reazioni, Vue, ...) può convertire facilmente e automaticamente il tuo datetime UTC in ora locale.

Inoltre:

(A meno che non sia probabile che modifichi il fuso orario dei server)


Esempio con AngularJs

// back-end: format for angular within the sql query
SELECT DATE_FORMAT(my_datetime, "%Y-%m-%dT%TZ")...

// font-end Output the localised time
{{item.my_datetime | date :'medium' }}

Tutto il formato dell'ora localizzata disponibile qui: https://docs.angularjs.org/api/ng/filter/date


8
I tuoi dati non devono essere collegati alle impostazioni del fuso orario dei tuoi server. Forse funzionerà per te se hai una sola scatola MySql sotto la scrivania
Jin

@Jin UTC significa nessun fuso orario come TIMESTAMP. Se tutti i tuoi server sono in UTC non ci sono problemi. Forse non funziona per te se hai una configurazione del 2000.
Sebastien Horin,

TIMESTAMP potrebbe essere aggiornato a un valore a 64 bit in futuro. Quindi non ci sono più problemi.
volte il

Caricare intere librerie di terze parti per catturare qualcosa del genere non può essere altrettanto eccezionale per le prestazioni, vero? Dato che è lato client e non influisce sul database ... Tuttavia, tutto ciò che fai front-end richiederà controlli sul server. Quindi, pensando al quadro completo , aiuta davvero con il problema della velocità? - A proposito, quei benchmark sono un po 'strani, credo. Anche l'uso di una stringa in una query per confrontare i campi di data e ora è abbastanza strano. Anche questo deve danneggiare le prestazioni, giusto?
NoobishPro,

1
Non fare affidamento nella tua applicazione sul fuso orario del server. Definisci invece il fuso orario da utilizzare su ogni connessione al database: SET time_zone = '+0:00';per UTC.
dolmen,

37

Un timestampcampo è un caso speciale del datetimecampo. È possibile creare timestampcolonne per avere proprietà speciali; può essere impostato per aggiornarsi su create e / o update.

In termini di database "più grandi", timestamppresenta un paio di trigger per casi speciali.

Qual è quello giusto dipende interamente da ciò che vuoi fare.


6
No, la differenza non è solo "un caso speciale". Poiché i fusi orari della sessione che imposta / interroga i valori sono coinvolti in modo diverso.
dolmen,

Sono contento che tu abbia inserito "Qual è quello giusto dipende interamente da ciò che vuoi fare". Ci sono troppe risposte su SE che affermano, senza una giustificazione sufficiente, "Non devi mai fare X" o "Devi sempre fare Y".
Agi Hammerthief

37

TIMESTAMP è sempre in UTC (ovvero, secondi trascorsi dal 1970-01-01, in UTC) e il tuo server MySQL lo converte automaticamente nella data / ora per il fuso orario della connessione. A lungo termine, TIMESTAMP è la strada da percorrere perché sai che i tuoi dati temporali saranno sempre in UTC. Ad esempio, non rovinerai le date se esegui la migrazione a un altro server o se modifichi le impostazioni del fuso orario sul tuo server.

Nota: il fuso orario di connessione predefinito è il fuso orario del server, ma questo può (dovrebbe) essere modificato per sessione (vedi SET time_zone = ...).


29

Confronto tra DATETIME, TIMESTAMP e DATE

inserisci qui la descrizione dell'immagine

Cos'è quella [.frazione]?

  • Un valore DATETIME o TIMESTAMP può includere una parte di secondi frazionari finali in precisione fino a microsecondi (6 cifre). In particolare, qualsiasi parte frazionaria in un valore inserito in una colonna DATETIME o TIMESTAMP viene memorizzata anziché scartata. Questo è ovviamente facoltativo.

fonti:


24

Userei sempre un timestamp Unix quando lavoro con MySQL e PHP. Il motivo principale per questo è la data predefinita metodo di in PHP utilizza un timestamp come parametro, quindi non ci sarebbe bisogno di analisi.

Per ottenere l'attuale timestamp Unix in PHP, basta fare time();
e in MySQL SELECT UNIX_TIMESTAMP();.


6
-1 In realtà penso che la risposta qui sotto sia migliore: l'uso di datetime ti consente di spingere più logica per l'elaborazione della data in MySQL stesso, il che può essere molto utile.
Toby Hede,

Non ci sono stati benchmark che mostrano che l'ordinamento in MySQL è più lento che in php?
sdkfasldf,

bene dipende, a volte è bene usarlo quando ci piace non usare lo strtotime. (php5.3 dep)
Adam Ramadhan,

puoi spingere la logica in mysql semplicemente usando FROM_UNIXTIME se necessario
inarilo,

Usavo tutti i timestamp Unix nelle mie applicazioni PHP e in MySQL, tuttavia ho scoperto che è molto più conveniente memorizzare date e orari in MySQL come tipi di data / ora nativi. Ciò è particolarmente utile per scopi di reportistica e solo per la ricerca di set di dati. Nel corso del tempo, quando mi sono frustrato dover copiare / oltre i timestamp di Unix, ho iniziato a cambiare. Sono abbastanza certo che ci sono prestazioni e altri vantaggi / svantaggi, ma a seconda del caso d'uso, la praticità può essere più importante delle micro ottimizzazioni.
DavidScherer,

24

Vale la pena notare in MySQL che è possibile utilizzare qualcosa seguendo le linee di seguito durante la creazione delle colonne della tabella:

on update CURRENT_TIMESTAMP

Ciò aggiornerà l'ora in ogni istanza in cui si modifica una riga ed è talvolta molto utile per le informazioni dell'ultima modifica memorizzate. Funziona solo con data / ora, non datetime comunque.


17

Dalle mie esperienze, se si desidera un campo data in cui l'inserimento avviene una sola volta e non si desidera avere alcun aggiornamento o altra azione su quel determinato campo, andare con data e ora .

Ad esempio, considera una usertabella con un campo DATA DI REGISTRAZIONE . In quel usertavolo, se si vuole conoscere l'ultima volta in volta di un particolare utente, andare con un campo di timestamp tipo in modo che il campo viene aggiornato.

Se si crea la tabella da phpMyAdmin predefinita aggiornerà il timestamp campo quando un aggiornamento di riga succede. Se il timestamp archiviato non viene aggiornato con l'aggiornamento di fila, è possibile utilizzare la seguente query per fare un timestamp campo di recupero automatico aggiornato.

ALTER TABLE your_table
      MODIFY COLUMN ts_activity TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;

15

Il tipo di dati data / ora memorizza la data e l'ora, ma nel formato UTC, non nel formato del fuso orario corrente come fa il datetime. E quando recuperi i dati, il timestamp li converte nuovamente nell'ora del fuso orario corrente.

Supponiamo quindi di essere negli Stati Uniti e di ottenere dati da un server che ha un fuso orario negli Stati Uniti. Quindi otterrai la data e l'ora in base al fuso orario USA. La colonna del tipo di dati data / ora viene sempre aggiornata automaticamente quando viene aggiornata la sua riga. Quindi può essere utile tenere traccia dell'ultima volta in cui una riga specifica è stata aggiornata.

Per maggiori dettagli puoi leggere il post sul blog Timestamp Vs Datetime .


Puoi (dovresti) definire sempre il fuso orario a livello di sessione con SET time_zone = '+0:00';(UTC qui) per essere sicuro di cosa ottieni / impostare dai TIMESTAMPvalori ed evitare a seconda del server time_zone predefinito che potrebbe cambiare.
dolmen,

14

Uso sempre un timestamp Unix, semplicemente per mantenere la sanità mentale quando ho a che fare con molte informazioni relative al datetime, specialmente quando eseguo aggiustamenti per fusi orari, aggiungendo / sottraendo date e simili. Quando si confrontano i timestamp, questo esclude i complicanti fattori del fuso orario e consente di risparmiare risorse nell'elaborazione lato server (sia che si tratti di codice dell'applicazione o query di database) in quanto si utilizza l'aritmetica leggera anziché aggiungere / sottrarre data-ora più pesante funzioni.

Un'altra cosa da considerare:

Se stai creando un'applicazione, non sai mai come i tuoi dati potrebbero dover essere utilizzati in futuro. Se finisci per dover confrontare, per esempio, un mucchio di record nel tuo set di dati, con, diciamo, un mucchio di elementi da un'API di terze parti e dire, metterli in ordine cronologico, sarai felice di avere Timestamp Unix per le tue righe. Anche se decidi di utilizzare i timestamp MySQL, archivia un timestamp Unix come assicurazione.


14

Nel mio caso, ho impostato UTC come fuso orario per tutto: il sistema, il server di database, ecc. Ogni volta che posso. Se il mio cliente richiede un altro fuso orario, lo configuro sull'app.

Preferisco quasi sempre i timestamp piuttosto che i campi datetime, perché i timestamp includono implicitamente il fuso orario. Quindi, dal momento in cui l'app sarà accessibile dagli utenti di diversi fusi orari e si desidera che vedano le date e gli orari nel loro fuso orario locale, questo tipo di campo rende abbastanza facile farlo rispetto a se i dati fossero salvati in campi datetime .

Inoltre, nel caso di una migrazione del database verso un sistema con un altro fuso orario, mi sentirei più sicuro usando i timestamp. Per non dire possibili problemi quando si calcolano le differenze tra due momenti con un tempo di sumer che cambia tra e che richiede una precisione di 1 ora o meno.

Quindi, per riassumere, apprezzo questi vantaggi del timestamp:

  • pronto per l'uso su app internazionali (multi fuso orario)
  • facili migrazioni tra fusi orari
  • abbastanza facile da calcolare le differenze (basta sottrarre entrambi i timestamp)
  • nessuna preoccupazione per le date in / out un periodo di ora legale

Per tutti questi motivi, ho scelto i campi UTC e timestamp dove possibile. Ed evito il mal di testa;)


i dati di data e ora saranno divertenti per la persona che supporta la tua domanda quando arriverà il 20 gennaio 2038. tick tock tick tock
Wilson Hauck,

Il tipo di data / ora potrebbe quindi essere aumentato di un po 'e raddoppiare i possibili valori.
Roger Campanera,

Metti alla prova la tua teoria per "aumentare di un po '" e vedere se riesci a memorizzare con successo l'1 febbraio 2038 e recuperarlo con MySQL. Vediamo la definizione della tabella al termine, per favore. Probabilmente avrai molte infelici conoscenze passate nel febbraio 2038.
Wilson Hauck,

1
@WilsonHauck Dovrai comunque aggiornare la versione di MySQL molto prima del 2038. E che TIMESTAMP esteso sarà gestito dalla migrazione. Inoltre, poche applicazioni oltre a gestire i mutui hanno davvero bisogno di preoccuparsi per il 2038 in questo momento.
dolmen,

@dolmen molti strumenti e materiali di livello professionale hanno una garanzia di oltre 20 anni. Quindi qualcosa del genere warranties.expires_atnon potrebbe essere un timestamp di MySQL oggi.
alexw,

13

Fai attenzione alla modifica del timestamp quando esegui un'istruzione UPDATE su una tabella. Se hai una tabella con le colonne 'Nome' (varchar), 'Età' (int) e 'Date_Added' (timestamp) ed esegui la seguente istruzione DML

UPDATE table
SET age = 30

quindi ogni singolo valore nella colonna "Date_Added" verrebbe modificato nel timestamp corrente.


3
in base a come imposti la tabella puoi controllare questo comportamento. guarda dev.mysql.com/doc/refman/5.5/it/timestamp-initialization.html
Charles Faiga

5
@CharlesFaiga Il comportamento predefinito è l'aggiornamento del timestamp quando viene aggiornata qualsiasi altra colonna. Devi disattivarlo esplicitamente se vuoi che il timestamp mantenga il suo valore originale
Lloyd Banks

Cos'è quello ?! devi impostare la colonna timstamp suON UPDATE CURRENT_TIMESTAMP
Accountant م

Questa è una funzione che devi abilitare esplicitamente durante la creazione della tabella.
dolmen,

13

Riferimento tratto da questo articolo:

Le principali differenze:

TIMESTAMP utilizzato per tenere traccia delle modifiche ai record e aggiornarsi ogni volta che il record viene modificato. DATETIME utilizzato per archiviare un valore specifico e statico che non è influenzato da alcuna modifica nei record.

TIMESTAMP è influenzato anche dalle diverse impostazioni relative a TIME ZONE. DATETIME è costante.

TIMESTAMP ha convertito internamente il fuso orario corrente in UTC per l'archiviazione e durante il recupero è stato riconvertito nel fuso orario corrente. DATETIME non può farlo.

Gamma TIMESTAMP supportata: da '1970-01-01 00:00:01 ′ UTC a' 2038-01-19 03:14:07 ′ DATETIME UTC intervallo supportato: da '1000-01-01 00:00:00 ′ a' 9999 -12-31 23:59:59 ′


11
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
|                                       TIMESTAMP                                       |                                 DATETIME                                 |
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
| TIMESTAMP requires 4 bytes.                                                           | DATETIME requires 8 bytes.                                               |
| Timestamp is the number of seconds that have elapsed since January 1, 1970 00:00 UTC. | DATETIME is a text displays 'YYYY-MM-DD HH:MM:SS' format.                |
| TIMESTAMP supported range: 1970-01-01 00:00:01 UTC to 2038-01-19 03:14:07 UTC.    | DATETIME supported range: 1000-01-01 00:00:00 to 9999-12-31 23:59:59 |
| TIMESTAMP during retrieval converted back to the current time zone.                   | DATETIME can not do this.                                                |
| TIMESTAMP is used mostly for metadata i.e. row created/modified and audit purpose.    | DATETIME is used mostly for user-data.                                   |
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+

10

Un'altra differenza tra Timestamp e Datetime è in Timestamp che non è possibile impostare il valore predefinito su NULL.


8
È ovviamente sbagliato. Ecco un esempio: CREATE TABLE t2 ( ts1 TIMESTAMP NULL, ts2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP); la prima colonna può accettare il valore NULL.
Ormoz,

10

Ho trovato un'utilità senza pari nella capacità di TIMESTAMP di aggiornarsi automaticamente in base all'ora corrente senza l'uso di trigger non necessari. Sono solo io, sebbene TIMESTAMP sia UTC come è stato detto.

Può tenere traccia di diversi fusi orari, quindi se è necessario visualizzare un orario relativo, ad esempio, l'ora UTC è ciò che si desidera.



9

Ho smesso di utilizzarlo datetimenelle mie applicazioni dopo aver affrontato molti problemi e bug relativi ai fusi orari. L'uso di IMHO timestampè migliore che datetimenella maggior parte dei casi .

Quando chiedi che ore sono? e la risposta arriva come qualcosa di simile a '2019-02-05 21:18:30', che non è una risposta completata, non definita perché manca un'altra parte, in quale fuso orario? Washington? Mosca? Pechino?

L'uso di periodi di tempo senza il fuso orario significa che l'applicazione ha a che fare solo con 1 fuso orario, tuttavia i timestamp ti offrono i vantaggi datetimee la flessibilità di mostrare lo stesso preciso punto temporale in diversi fusi orari.

Ecco alcuni casi che ti faranno pentire di aver usato datetimee desiderato di aver archiviato i tuoi dati in timestamp.

  1. Per il comfort dei tuoi clienti, vuoi mostrare loro i tempi in base ai loro fusi orari preferiti senza farli fare la matematica e convertire il tempo nel loro fuso orario significativo. tutto ciò che serve è cambiare il fuso orario e tutto il codice dell'applicazione sarà lo stesso. (In realtà è sempre necessario definire il fuso orario all'inizio dell'applicazione o richiedere l'elaborazione in caso di applicazioni PHP)

    SET time_zone = '+2:00';
  2. hai cambiato il Paese in cui ti trovi e continui il tuo lavoro di conservazione dei dati mentre li vedi in un fuso orario diverso (senza modificare i dati effettivi).

  3. accetti i dati di diversi clienti in tutto il mondo, ognuno inserisce l'ora nel suo fuso orario.

In breve

datetime = l'applicazione supporta 1 fuso orario (sia per l'inserimento che per la selezione)

timestamp = l'applicazione supporta qualsiasi fuso orario (sia per l'inserimento che per la selezione)


Questa risposta è solo per mettere in evidenza la flessibilità e la facilità dei timestamp quando si tratta di fusi orari, non copre altre differenze come la dimensione della colonna o l'intervallo o la frazione .


cosa succede se ci sono campi che usano datee altri campi usano timestampin una tabella. Penso che causerà un nuovo problema perché i dati filtrati wherenon sono conformi alle modifiche del fuso orario.
Erlang P,

@ErlangP In tal caso, l'applicazione dovrebbe risolvere il problema del fuso orario nella datecolonna prima di inviare la query.
Ragioniere م

7

Preferisco usare il timestamp in modo da mantenere tutto in un formato raw comune e formattare i dati nel codice PHP o nella tua query SQL. Ci sono casi in cui è utile nel tuo codice per conservare tutto in pochi secondi.



6

Mi piace un timestamp Unix, perché puoi convertire in numeri e preoccuparti solo del numero. Inoltre aggiungi / sottrai e ottieni durate, ecc. Quindi converti il ​​risultato in Data in qualunque formato. Questo codice rileva la quantità di tempo in minuti trascorsa tra un timestamp da un documento e l'ora corrente.

$date  = $item['pubdate']; (etc ...)
$unix_now = time();
$result = strtotime($date, $unix_now);
$unix_diff_min = (($unix_now  - $result) / 60);
$min = round($unix_diff_min);

4
Oppure, utilizza un datetime MySQL nativo leggibile e utilizza le funzioni MySQL native per aggiungere / sottrarre i tempi dei dati.
Julien Palard,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.