Vi consigliamo di utilizzare un datetime o un timestamp campo, e perché (usando MySQL)?
Sto lavorando con PHP sul lato server.
Vi consigliamo di utilizzare un datetime o un timestamp campo, e perché (usando MySQL)?
Sto lavorando con PHP sul lato server.
Risposte:
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.
DATETIME
rappresenta una data (come si trova in un calendario) e un'ora (come si può osservare su un orologio da parete), mentre TIMESTAMP
rappresenta 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].
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 .
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.
new Date().getTime()
ti dà già un valore a 64 bit.
Il sotto esempi mostrano come il TIMESTAMP
tipo 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 .
DATETIME
tempo effettivo è cambiato con il cambio di fuso orario, TIMESTAMP
non è cambiato ma la rappresentazione umana è cambiata.
set time_zone="america/new_york"
;
La differenza principale è che DATETIME è costante mentre TIMESTAMP è influenzato time_zone
dall'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.)
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.
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:
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.
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;)
TIMESTAMP è di quattro byte contro otto byte per DATETIME.
I timestamp sono anche più chiari sul database e indicizzati più velocemente.
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.
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.
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
SET time_zone = '+0:00';
per UTC.
Un timestamp
campo è un caso speciale del datetime
campo. È possibile creare timestamp
colonne per avere proprietà speciali; può essere impostato per aggiornarsi su create e / o update.
In termini di database "più grandi", timestamp
presenta un paio di trigger per casi speciali.
Qual è quello giusto dipende interamente da ciò che vuoi fare.
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 = ...
).
Confronto tra DATETIME, TIMESTAMP e DATE
Cos'è quella [.frazione]?
fonti:
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();
.
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.
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 user
tabella con un campo DATA DI REGISTRAZIONE . In quel user
tavolo, 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;
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 .
SET time_zone = '+0:00';
(UTC qui) per essere sicuro di cosa ottieni / impostare dai TIMESTAMP
valori ed evitare a seconda del server time_zone predefinito che potrebbe cambiare.
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.
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:
Per tutti questi motivi, ho scelto i campi UTC e timestamp dove possibile. Ed evito il mal di testa;)
warranties.expires_at
non potrebbe essere un timestamp di MySQL oggi.
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.
ON UPDATE CURRENT_TIMESTAMP
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 ′
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
| 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. |
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
Un'altra differenza tra Timestamp e Datetime è in Timestamp che non è possibile impostare il valore predefinito su NULL.
CREATE TABLE t2 ( ts1 TIMESTAMP NULL, ts2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP);
la prima colonna può accettare il valore NULL.
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.
La differenza principale è
guarda questo post per vedere i problemi con l'indicizzazione Datetime
Ho smesso di utilizzarlo datetime
nelle mie applicazioni dopo aver affrontato molti problemi e bug relativi ai fusi orari. L'uso di IMHO timestamp
è migliore che datetime
nella 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 datetime
e la flessibilità di mostrare lo stesso preciso punto temporale in diversi fusi orari.
Ecco alcuni casi che ti faranno pentire di aver usato datetime
e desiderato di aver archiviato i tuoi dati in timestamp.
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';
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).
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 .
date
e altri campi usano timestamp
in una tabella. Penso che causerà un nuovo problema perché i dati filtrati where
non sono conformi alle modifiche del fuso orario.
date
colonna prima di inviare la query.
A TIMESTAMP
richiede 4 byte, mentre a DATETIME
richiede 8 byte.
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);