Domanda

Consiglieresti di utilizzare un datetime o un data / ora e perché (utilizzando MySQL)?

Sto lavorando con PHP sul lato server.

È stato utile?

Soluzione

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. In questo modo puoi eseguire calcoli con MySQL (" 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 desideri operare su di esso con PHP.

Altri suggerimenti

In MySQL 5 e versioni successive, i valori TIMESTAMP vengono convertiti dal fuso orario corrente a UTC per la memorizzazione e convertiti nuovamente da UTC al 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 in Supporto fuso orario 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.

Gli esempi seguenti mostrano come il tipo di data TIMESTAMP ha cambiato i valori dopo aver modificato il fuso orario in 'america / new_york' dove DATETIME è invariato.

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 vs Timestamp .

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

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 il tempo reale dell'evento nel nuovo fuso orario, mentre DATETIME rispecchierebbe comunque l'ora dell'evento nel fuso orario au .

Un ottimo esempio di DATETIME usato dove TIMESTAMP avrebbe dovuto essere usato è su Facebook, dove i loro server non sono mai abbastanza sicuri di cosa sia accaduto tra i 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, ovviamente, potrebbe anche essere stato causato da una cattiva traduzione 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 possono essere impostate e modificate arbitrariamente. Ad esempio, quando un utente può salvare gli appuntamenti di modifica successivi.

TIMESTAMP è 4 byte contro 8 byte per DATETIME.

http://dev.mysql.com/doc/ refman / 5.0 / it / 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;)

Consiglio di usare un campo DATETIME o TIMESTAMP. Se vuoi rappresentare un giorno specifico nel suo insieme (come un compleanno), quindi utilizza 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 un DATETIME o TIMESTAMP, usa un BIGINT e memorizza semplicemente il numero di millisecondi dall'epoca (System.currentTimeMillis () se stai usando Java). Ciò ha diversi vantaggi:

  1. Eviti 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" come fa 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.

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

  2. I timestamp sono anche più leggeri nel 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 in & # 8216; AAAA-MM-GG HH: MM: SS & # 8217; formato. L'intervallo supportato è & # 8217; 1000-01-01 00: 00: 00 & # 8242; a & # 8217; 9999-12-31 23: 59: 59 & # 8242 ;.

Il tipo di dati TIMESTAMP ha un intervallo di & # 8217; 1970-01-01 00: 00: 01 & # 8242; UTC a & # 8217; 2038-01-09 03: 14: 07 & # 8242; 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 del fuso orario.

Dipende dall'applicazione, davvero.

Valuta 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 i valori che rappresentano l'ora dell'utente come un appuntamento o una pianificazione, 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.

2016 + : ti 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.

In aggiunta:

(A meno che non sia probabile che cambi il fuso orario dei tuoi 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' }}

Tutti i formati di ora localizzata disponibili qui: https://docs.angularjs.org/api/ng/filter/date

Un campo timestamp è un caso speciale del campo datetime . Puoi creare colonne timestamp per avere proprietà speciali; può essere impostato per aggiornarsi su create e / o update.

In "più grande" termini del database, timestamp ha 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 (vedere SET time_zone = ... ).

Confronto tra DATETIME, TIMESTAMP e DATE

 inserisci qui la descrizione dell'immagine

Che cos'è quella [.frazione]?

  • Un valore DATETIME o TIMESTAMP può includere un frazionario finale secondi parte con precisione fino a microsecondi (6 cifre). Nel in particolare, qualsiasi parte frazionaria in un valore inserito in un DATETIME oppure la colonna TIMESTAMP viene memorizzata anziché eliminata. Questo è ovviamente facoltativo.

Fonti:

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 e talvolta è molto utile per le informazioni dell'ultima modifica memorizzate. Funziona solo con data e ora, non datetime comunque.

Userei sempre un timestamp Unix quando lavoro con MySQL e PHP. Il motivo principale per cui questo è il metodo date predefinito in PHP utilizza un data / ora come parametro, quindi non sarebbe necessario alcun analisi.

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

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, selezionare ora data .

Ad esempio, considera una tabella user con un campo DATA DI REGISTRAZIONE . In quella tabella user , se vuoi conoscere l'ora dell'ultimo accesso di un determinato utente, vai con un campo di tipo timestamp in modo che il campo venga aggiornato.

Se stai creando la tabella da phpMyAdmin l'impostazione predefinita aggiornerà il timestamp quando si verifica un aggiornamento di riga. Se il timestamp archiviato non si aggiorna con l'aggiornamento di riga, puoi utilizzare la seguente query per fare in modo che un campo timestamp venga aggiornato automaticamente.

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

Il tipo di dati timestamp 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 particolare riga è stata aggiornata.

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

Uso sempre un timestamp Unix, semplicemente per mantenere la sanità mentale quando ho a che fare con molte informazioni sul 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.

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.

Riferimenti tratti da questo articolo:

Le principali differenze:

TIMESTAMP utilizzato per tenere traccia delle modifiche ai record e aggiornarsi ogni volta che si modifica il record. 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 supportata TIMESTAMP: "1970-01-01 00:00:01 ' UTC a" 2038-01-19 03:14:07 ' UTC Intervallo supportato DATETIME: Da "1000-01-01 00:00:00" a "9999-12-31 23:59:59"

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 agli utenti da 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 .

In più, 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 di un periodo di ora legale

Per tutti questi motivi, ho scelto UTC & amp; campi data / ora ove possibile. Ed evito il mal di testa;)

La differenza principale è

  • un INDICE su Timestamp - funziona
  • a INDEX's on Datetime - Non funziona

guarda questo post per vedere problemi con l'indicizzazione Datetime

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

Ho trovato un'impareggiabile utilità 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.

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 mantenere tutto in pochi secondi.

+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
|                                       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.                                   |
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+

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);

Un TIMESTAMP richiede 4 byte, mentre un DATETIME richiede 8 byte.

TIMESTAMP è utile quando si hanno visitatori da paesi diversi con fusi orari diversi. puoi facilmente convertire TIMESTAMP in qualsiasi fuso orario del paese

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top