Sollte ich in MySQL den Datentyp datetime oder timestamp verwenden?


2686

Würden Sie empfehlen, ein Datum / Uhrzeit- oder ein Zeitstempelfeld zu verwenden, und warum (mit MySQL)?

Ich arbeite mit PHP auf der Serverseite.


1
Dies hat einige relevante Informationen codeproject.com/Tips/1215635/MySQL-DATETIME-vs-TIMESTAMP
Waqleh

Wenn Sie möchten, dass Ihre Anwendung im Februar 2038 unterbrochen wird, verwenden Sie den Zeitstempel. Überprüfen Sie den Datumsbereich.
Wilson Hauck

Antworten:


1829

Zeitstempel in MySQL werden im Allgemeinen verwendet, um Änderungen an Datensätzen zu verfolgen. Sie werden häufig jedes Mal aktualisiert, wenn der Datensatz geändert wird. Wenn Sie einen bestimmten Wert speichern möchten, sollten Sie ein Datum / Uhrzeit-Feld verwenden.

Wenn Sie sich zwischen einem UNIX-Zeitstempel oder einem nativen MySQL-Datum / Uhrzeit-Feld entscheiden möchten, wählen Sie das native Format. Auf diese Weise können Sie Berechnungen in MySQL durchführen, ("SELECT DATE_ADD(my_datetime, INTERVAL 1 DAY)")und es ist einfach, das Format des Werts in einen UNIX-Zeitstempel zu ändern, ("SELECT UNIX_TIMESTAMP(my_datetime)")wenn Sie den Datensatz abfragen, wenn Sie ihn mit PHP bearbeiten möchten.


981
Ein wichtiger Unterschied besteht darin, dass DATETIMEer ein Datum (wie in einem Kalender angegeben) und eine Uhrzeit (wie auf einer Wanduhr zu sehen) darstellt, während TIMESTAMPer einen genau definierten Zeitpunkt darstellt. Dies kann sehr wichtig sein, wenn Ihre Anwendung Zeitzonen verarbeitet. Wie lange ist '2010-09-01 16:31:00' her? Es hängt davon ab, in welcher Zeitzone Sie sich befinden. Für mich war es erst ein paar Sekunden her, für Sie könnte es eine Zeit in der Zukunft darstellen. Wenn ich 1283351460 Sekunden seit '1970-01-01 00:00:00 UTC' sage, wissen Sie genau, über welchen Zeitpunkt ich spreche. (Siehe Nirs ausgezeichnete Antwort unten). [Nachteil: gültiger Bereich].
MattBianco

121
Ein weiterer Unterschied: Abfragen mit "nativer" Datumszeit werden nicht zwischengespeichert, Abfragen mit Zeitstempel jedoch.
OZ_

39
"Zeitstempel in MySQL werden im Allgemeinen verwendet, um Änderungen an Datensätzen zu verfolgen." Das ist keine gute Antwort. Zeitstempel sind viel leistungsfähiger und komplizierter als das, wie MattBianco und Nir sagten. Der zweite Teil der Antwort ist jedoch sehr gut. Es ist wahr, was Blivet gesagt hat, und es ist ein guter Rat.
Santiagobasulto

10
1 wichtiger Hinweis: DATETIME und TIMESTAMP können CURRENT_TIMESTAMP, NOW () respektvoll als Standardwert verwenden, DATE jedoch beispielsweise nicht, da standardmäßig '0000-00-00' verwendet wird. Um diese Angelegenheit zu lösen, sollte U schreiben Ihr eigener Auslöser für diese Tabelle, um das aktuelle Datum (ohne Uhrzeit) in das Feld / die Spalte mit dem Datums-Datums-MySQL-Typ einzufügen.
Arthur Kushman

14
@DavidHarkness: In der Dokumentation heißt es: "Um automatische Eigenschaften anzugeben, verwenden Sie die Klauseln DEFAULT CURRENT_TIMESTAMP und ON UPDATE CURRENT_TIMESTAMP." Dev.mysql.com/doc/refman/5.0/de/timestamp-initialization.html
Plap

917

In MySQL 5 und höher werden TIMESTAMP- Werte zum Speichern von der aktuellen Zeitzone in UTC und zum Abrufen von UTC zurück in die aktuelle Zeitzone konvertiert. (Dies tritt nur für den TIMESTAMP-Datentyp und nicht für andere Typen wie DATETIME auf.)

Standardmäßig ist die aktuelle Zeitzone für jede Verbindung die Zeit des Servers. Die Zeitzone kann pro Verbindung festgelegt werden, wie in MySQL Server Time Zone Support beschrieben .


11
Diese OReilly Präsentation ist sehr gut für dieses Thema (PDF sorry) cdn.oreillystatic.com/de/assets/1/event/36/…
gcb

13
Es geht auch um die Art der Veranstaltung: - Eine Videokonferenz (TIMESTAMP). Alle Teilnehmer sollten einen Verweis auf einen absoluten Zeitpunkt sehen, der an ihre Zeitzone angepasst ist. - Eine lokale Arbeitszeit (DATETIME), ich sollte diese Aufgabe am 31.03.2014 um 9:00 Uhr erledigen, egal ob ich an diesem Tag in New York oder Paris arbeite. Ich werde um 8:00 Uhr Ortszeit an diesem Tag mit der Arbeit beginnen.
Yucer

1
Wenn ich also die Zeitzone des Servers ändere, bleibt der Wert von TIMESTAMP gleich oder ändert er sich auch?
Andrew

3
@ Andrew, da es UTC ist, bleibt es UTC. Die Rückwärtskonvertierung ändert sich jedoch in die "neue" Server-Zeitzone.
Nembleton

@yucer - Ich empfehle nicht, so darüber nachzudenken. Die konsistenteste Verwendung in einer globalen Wirtschaft besteht darin, alle Datenzeiten zur Speicherung in UTC umzuwandeln. Behandeln Sie Datetime standardmäßig als UTC-Feld. Dies belastet zwar alle Aufgaben, die Daten eingeben, um die Konvertierung in UTC durchzuführen, ist jedoch langfristig sauberer. Präsentieren Sie die Informationen dem Benutzer natürlich anhand seiner aktuellen Einstellungen. Wenn der Benutzer "09:00 in Paris" eingeben möchte, lassen Sie ihn die Pariser Zeit einstellen und geben Sie dann 09:00 ein. Dann kann jeder, der in New York ist, leicht herausfinden, wann er zu seiner Zeit wach sein muss, um eine Telefonkonferenz abzuhalten.
ToolmakerSteve

524

Ich verwende DATETIME-Felder immer für andere als Zeilenmetadaten (Erstellungsdatum oder Änderungsdatum).

Wie erwähnt in der MySQL - Dokumentation:

Der Typ DATETIME wird verwendet, wenn Sie Werte benötigen, die sowohl Datums- als auch Zeitinformationen enthalten. MySQL ruft DATETIME-Werte im Format 'JJJJ-MM-TT HH: MM: SS' ab und zeigt sie an. Der unterstützte Bereich ist "1000-01-01 00:00:00" bis "9999-12-31 23:59:59".

...

Der Datentyp TIMESTAMP hat einen Bereich von '1970-01-01 00:00:01' UTC bis '2038-01-09 03:14:07' UTC. Es hat unterschiedliche Eigenschaften, abhängig von der MySQL-Version und dem SQL-Modus, in dem der Server ausgeführt wird.

Es ist sehr wahrscheinlich, dass Sie die Untergrenze für TIMESTAMPs im allgemeinen Gebrauch erreichen - z. B. das Speichern des Geburtsdatums.


195
Sie können auch die Hit obere Grenze leicht , wenn Sie in Bank- oder Immobilien sind ... 30-jährige Hypotheken über 2038 gehen jetzt
Kip

16
Verwenden Sie natürlich 64-Bit-Unix-Zeitstempel. In Java erhalten Sie beispielsweise new Date().getTime()bereits einen 64-Bit-Wert.
osa

5
+1 für DATETIME: In unserem Datenfluss von SQL Server des physischen Speichers zum Kauf und zur Rechnung, übertragen auf MySQL Server für den virtuellen Speicher auf der Webseite, ist DATETIME besser für das Änderungsdatum und die Änderungszeit, da dieser Datentyp auch in Transact vorhanden ist -SQL. Aber TIMESTAMP bedeutet in Transact-SQL etwas anderes, es ist binär wie ROWVERSION, obwohl MySQL TIMESTAMP DateTime ähnlich ist. Daher vermeiden wir die Verwendung von TIMESTAMP, um die Kompatibilität der beiden DBs zu gewährleisten.
Jacouh

10
Keine Ahnung. Es ist ein viel größeres Problem als nur MySQL und es gibt keine einfache Lösung: en.wikipedia.org/wiki/Year_2038_problem Ich glaube nicht, dass MySQL nur erklären kann, dass Zeitstempel jetzt 64-Bit sind und davon ausgehen, dass alles in Ordnung ist. Sie kontrollieren die Hardware nicht.
Scronide

5
Ein Geburtsdatum kann ein Datum sein, wenn Sie den Zeitpunkt der Geburt kennen, wie ich es für meine tue.
Kris Craig

322

Die folgenden Beispiele zeigen, wie der TIMESTAMPDatumstyp die Werte geändert hat, nachdem das time-zone to 'america/new_york'Where DATETIMEunverändert geändert wurde .

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

Ich habe meine Antwort in einen Artikel umgewandelt, damit mehr Benutzer diese nützlichen MySQL: Datetime Versus Timestamp-Datentypen finden können .


55
Nun, tatsächlich DATETIMEänderte sich die effektive Zeit mit der Zeitzonenänderung TIMESTAMPnicht, aber die menschliche Repräsentation tat es.
Flindeberg

3
Dieser Befehl scheint in MySQL 5.6 nicht zu funktionieren set time_zone="america/new_york".
Manjunath Reddy

Hier ist die Antwort auf das Problem mit der eingestellten Zeitzone. stackoverflow.com/questions/3451847/mysql-timezone-change
Manjunath Reddy

2
Stimmen Sie mit @flindeberg überein. Der Zeitstempel repräsentiert die korrekte Zeit, nicht die Uhrzeit, nach dem Zeitzonenwechsel
Nitin Bansal,

193

Der Hauptunterschied besteht darin, dass DATETIME konstant ist, während TIMESTAMP von der time_zoneEinstellung beeinflusst wird.

Es ist also nur wichtig, wenn Sie Cluster über Zeitzonen hinweg synchronisiert haben oder in Zukunft haben könnten.

In einfacheren Worten: Wenn ich eine Datenbank in Australien habe und einen Speicherauszug dieser Datenbank nehme, um eine Datenbank in Amerika zu synchronisieren / zu füllen, wird der TIMESTAMP aktualisiert, um die Echtzeit des Ereignisses in der neuen Zeitzone wiederzugeben, während DATETIME dies tun würde spiegeln immer noch die Zeit des Ereignisses in der Au-Zeitzone wider .

Ein gutes Beispiel für die Verwendung von DATETIME dort, wo TIMESTAMP hätte verwendet werden sollen, ist Facebook, wo die Server nie ganz sicher sind, welche Zeit in verschiedenen Zeitzonen passiert ist. Einmal hatte ich ein Gespräch, in dem die Zeit sagte, dass ich auf Nachrichten antwortete, bevor die Nachricht tatsächlich gesendet wurde. (Dies könnte natürlich auch durch eine schlechte Zeitzonenübersetzung in der Messaging-Software verursacht worden sein, wenn die Zeiten nicht synchronisiert, sondern gebucht wurden.)


83
Ich denke nicht, dass dies eine gute Denkweise ist. Ich würde einfach alle Daten in UTC speichern und verarbeiten und sicherstellen, dass das Front-End sie entsprechend der angegebenen Zeitzone anzeigt. Dieser Ansatz ist einfach und vorhersehbar.
Kos

8
@Kos: Speichern und verarbeiten nicht alle Daten in UTC genau das, was TIMESTAMP intern tut? (Dann konvertieren Sie es, um Ihre lokale Zeitzone anzuzeigen?)
Carbocation

10
meine lokale Zeitzone? Wie würde Ihre DB meine Zeitzone kennen? ;-) Normalerweise gibt es eine gewisse Verarbeitung zwischen der Datenbank und der Benutzeroberfläche. Ich mache die Lokalisierung erst nach der gesamten Verarbeitung.
Kos

3
@Koz: Meine Datenbank kennt Ihre Datenbank nicht Zeitzone :! Aber es kennt den Zeitstempel. Ihre Datenbank kennt ihre eigene Zeitzoneneinstellung und wendet diese bei der Interpretation / Darstellung des Zeitstempels an. 01:01 Uhr am 11. Dezember 2013 in Peking China ist nicht der gleiche Zeitpunkt wie 01:01 Uhr am 11. Dezember 2013 in Sydney, Australien. Google: "Zeitzonen" und "Nullmeridian".
ekerner

2
MySQL konvertiert TIMESTAMP-Werte von der aktuellen Zeitzone zum Speichern in UTC und zum Abrufen von UTC zurück in die aktuelle Zeitzone. (Dies tritt nicht für andere Typen wie DATETIME auf.) Dev.mysql.com/doc/refman/5.5/en/datetime.html
Mahdyfo

125

Ich treffe diese Entscheidung auf semantischer Basis.

Ich verwende einen Zeitstempel, wenn ich einen (mehr oder weniger) festen Zeitpunkt aufzeichnen muss. Zum Beispiel, wenn ein Datensatz in die Datenbank eingefügt wurde oder wenn eine Benutzeraktion stattgefunden hat.

Ich verwende ein Datum / Uhrzeit-Feld, wenn Datum / Uhrzeit beliebig eingestellt und geändert werden können. Zum Beispiel, wenn ein Benutzer spätere Änderungstermine speichern kann.


Zeitstempel - fester Zeitpunkt, koordinierte Weltzeit datetime - relativ zu einem Gesichtspunkt, zu einer Zeitreferenz (ej Zeitzone Ortszeit), könnte sein. Koordinierte Ortszeit?
Yucer

110

Ich empfehle, weder ein DATETIME- noch ein TIMESTAMP-Feld zu verwenden. Wenn Sie einen bestimmten Tag als Ganzes darstellen möchten (z. B. einen Geburtstag), verwenden Sie einen DATE-Typ. Wenn Sie jedoch spezifischer sind, sind Sie wahrscheinlich daran interessiert, einen tatsächlichen Moment im Gegensatz zu einer Einheit von aufzuzeichnen Zeit (Tag, Woche, Monat, Jahr). Verwenden Sie anstelle von DATETIME oder TIMESTAMP einen BIGINT und speichern Sie einfach die Anzahl der Millisekunden seit der Epoche (System.currentTimeMillis (), wenn Sie Java verwenden). Dies hat mehrere Vorteile:

  1. Sie vermeiden eine Lieferantenbindung. Nahezu jede Datenbank unterstützt Ganzzahlen auf relativ ähnliche Weise. Angenommen, Sie möchten in eine andere Datenbank wechseln. Möchten Sie sich über die Unterschiede zwischen den DATETIME-Werten von MySQL und deren Definition durch Oracle Gedanken machen? Selbst unter verschiedenen Versionen von MySQL haben TIMESTAMPS eine unterschiedliche Genauigkeit. Erst kürzlich unterstützte MySQL Millisekunden in den Zeitstempeln.
  2. Keine Zeitzonenprobleme. Es gab hier einige aufschlussreiche Kommentare dazu, was mit Zeitzonen mit den verschiedenen Datentypen passiert. Aber ist das allgemein bekannt, und werden sich Ihre Mitarbeiter alle die Zeit nehmen, es zu lernen? Auf der anderen Seite ist es ziemlich schwierig, einen BigINT in einen java.util.Date zu verwandeln. Die Verwendung eines BIGINT führt dazu, dass viele Probleme mit Zeitzonen auf der Strecke bleiben.
  3. Keine Sorge um Reichweite oder Präzision. Sie müssen sich keine Gedanken darüber machen, was durch zukünftige Datumsbereiche gekürzt wird (TIMESTAMP geht nur bis 2038).
  4. Tool-Integration von Drittanbietern. Durch die Verwendung einer Ganzzahl ist es für Tools von Drittanbietern (z. B. EclipseLink) trivial, eine Schnittstelle zur Datenbank herzustellen. Nicht jedes Tool von Drittanbietern wird das gleiche Verständnis von "datetime" haben wie MySQL. Möchten Sie im Ruhezustand herausfinden, ob Sie ein Objekt java.sql.TimeStamp oder java.util.Date verwenden sollten, wenn Sie diese benutzerdefinierten Datentypen verwenden? Die Verwendung Ihrer Basisdatentypen macht die Verwendung mit Tools von Drittanbietern trivial.

Dieses Problem hängt eng damit zusammen, wie Sie einen Geldwert (dh 1,99 USD) in einer Datenbank speichern sollten. Sollten Sie eine Dezimalzahl oder den Geldtyp der Datenbank oder am schlimmsten ein Double verwenden? Alle drei Optionen sind aus vielen der oben genannten Gründe schrecklich. Die Lösung besteht darin, den Wert des Geldes mit BIGINT in Cent zu speichern und dann Cent in Dollar umzurechnen, wenn Sie dem Benutzer den Wert anzeigen. Die Aufgabe der Datenbank besteht darin, Daten zu speichern und diese Daten NICHT zu interpretieren. All diese ausgefallenen Datentypen, die Sie in Datenbanken (insbesondere Oracle) sehen, tragen wenig dazu bei und bringen Sie auf den Weg zur Lieferantenbindung.


12
Ich mag diese Lösung. Der Ablauf des TIMESTAMP im Jahr 2038 ist ein großes Problem. Das ist nicht wirklich so weit weg!
Charlie Dalsass

4
@CharlieDalsass Glauben Sie, dass die aktuelle Software dieses Mal da sein wird :-P
Habeeb Perwad

13
Es macht es schwierig, Daten nach Datum abzufragen, wenn sie in Millisekunden gespeichert sind
Ali Saeed

4
Dies ist wirklich die beste Lösung, wenn Sie Wert auf Portabilität und den Umgang mit Benutzern in mehreren Zeitzonen oder auf Datenbanken in anderen Zeitzonen als Benutzer legen. TIMESTAMP könnte der richtige Weg sein, wenn es keine Designfehler gibt. Schade, dass defekte Lösungen mehr Stimmen erhielten, weil sie früh (Jahre!) Veröffentlicht wurden.
Deutsch

4
Hervorragende Lösung! Und Sie sind genau richtig, wenn Sie "eingesperrt" sind. Wenn Sie es sich zur Gewohnheit machen, andere "die Arbeit für Sie erledigen" zu lassen, verlieren Sie die Teile, die SIE zum Programmierer machen.
FMC

98

TIMESTAMP ist 4 Bytes gegenüber 8 Bytes für DATETIME.

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

Aber wie Scronide sagte, hat es eine Untergrenze des Jahres 1970. Es ist großartig für alles, was in Zukunft passieren könnte;)


185
Die Zukunft endet um 2038-01-19 03:14:07 UTC.
MattBianco

5
Das ist blöd. Ich dachte, der TIMESTAMP-Typ wäre "zukunftsfähig", weil er relativ neu ist. Sie können Datums- und Uhrzeitangaben nicht jedes Mal in UTC und zurück konvertieren, wenn Sie mit verschiedenen Zeitzonen arbeiten. Sie hätten TIMESTAMP größer machen sollen. Mindestens 1 Byte größer. es werden 68 * 255 = 17340 weitere Jahre hinzugefügt ... obwohl es nicht 32-Bit-ausgerichtet sein wird.
NickSoft

10
Wissen Sie, warum TIMESTAMP 2038 endet? Weil es eine ganze Zahl ist und ganze Zahlen ein Limit von 2147483647 haben. Ich denke, das ist der Grund. Wenn sie den Typ in varchar ändern und die Art und Weise der Manipulation ändern, ist er möglicherweise "zukunftsfähig".
Vinsa

6
@vinsa, ich glaube nicht, dass es bis dahin zukunftsfähig sein wird. Erinnerst du dich noch an den Y2K-Fehler? 2038 kommt.
Pacerier

2
Bis 2038 aktualisiert MySQL (falls es noch vorhanden ist) einfach das TIMESTAMP-Feld, um mehr als 4 Bytes zu verwenden und einen größeren Bereich
zuzulassen

95
  1. TIMESTAMP ist vier Bytes gegenüber acht Bytes für DATETIME.

  2. Zeitstempel sind auch leichter in der Datenbank und werden schneller indiziert.

  3. Der Typ DATETIME wird verwendet, wenn Sie Werte benötigen, die sowohl Datums- als auch Zeitinformationen enthalten. MySQL ruft DATETIME-Werte im Format 'JJJJ-MM-TT HH: MM: SS' ab und zeigt sie an. Der unterstützte Bereich ist '1000-01-01 00:00:00' bis '9999-12-31 23:59:59'.

Der Datentyp TIMESTAMP hat einen Bereich von '1970-01-01 00:00:01' UTC bis '2038-01-09 03:14:07' UTC. Es hat unterschiedliche Eigenschaften, abhängig von der MySQL-Version und dem SQL-Modus, in dem der Server ausgeführt wird.

  1. DATETIME ist konstant, während TIMESTAMP durch die Einstellung time_zone beeinflusst wird.

6
Sie müssen # 4 klarstellen: Der gespeicherte Zeitstempel ist konstant und nicht relativ (vollständig agnostisch) zur Zeitzone, während die beim Abrufen angezeigte Ausgabe von der Zeitzone der anfordernden Sitzung beeinflusst wird. DATETIME bezieht sich immer auf die Zeitzone, in der es aufgezeichnet wurde, und muss in diesem Zusammenhang immer berücksichtigt werden. Diese Verantwortung liegt nun bei der Anwendung.
Christopher McGowan

1
Gute Antwort. Wenn wir versuchen, Werte über '2038-01-09 03:14:07' hinaus zu speichern, erhalten wir entweder einen Fehler oder es wird als '0000-00-00 00:00:00' gespeichert. Ich habe diesen Fehler für meine Datenbank erhalten, da sie zeitversetzte Werte enthält (zu Verschlüsselungszwecken).
KarthikS

Außerdem gibt es ein Problem mit DATETIME mit dem Wert DEFAULT bei Versionen von MySQL unter 5.5. dba.stackexchange.com/questions/132951/…
Velaro

47

Kommt wirklich auf die Anwendung an.

Ziehen Sie in Betracht, einen Zeitstempel eines Benutzers für einen Termin in Sanghai auf einem Server in New York festzulegen. Wenn der Benutzer eine Verbindung in Sanghai herstellt, greift er von einem gespiegelten Server in Tokio auf denselben Terminzeitstempel zu. Er wird den Termin in Tokio sehen, versetzt von der ursprünglichen New Yorker Zeit.

Für Werte, die die Benutzerzeit wie einen Termin oder einen Zeitplan darstellen, ist die Datumszeit besser. Damit kann der Benutzer unabhängig von den Servereinstellungen das genaue Datum und die gewünschte Uhrzeit steuern. Die eingestellte Zeit ist die eingestellte Zeit, die nicht von der Zeitzone des Servers, der Zeitzone des Benutzers oder von Änderungen in der Berechnung der Sommerzeit beeinflusst wird (ja, sie ändert sich).

Verwenden Sie für Werte, die die Systemzeit darstellen, wie Zahlungstransaktionen, Tabellenänderungen oder Protokollierung, immer Zeitstempel. Das System ist nicht betroffen, wenn der Server in eine andere Zeitzone verschoben wird oder wenn Server zwischen verschiedenen Zeitzonen verglichen werden.

Zeitstempel sind auch leichter in der Datenbank und werden schneller indiziert.


Ihre Anwendung sollte sich nicht auf die Zeitzone des Servers verlassen. Eine Anwendung sollte IMMER die Zeitzone in der Sitzung der von ihr verwendeten Datenbankverbindung auswählen, bevor eine Abfrage ausgegeben wird. Wenn eine Verbindung von mehreren Benutzern gemeinsam genutzt wird (z. B. webapp), verwenden Sie UTC und führen Sie auf der Rendering-Seite eine Zeitzonenkonvertierung durch.
Dolmen

42

2016 + : Ich rate Ihnen, Ihre MySQL-Zeitzone auf UTC einzustellen und DATETIME zu verwenden:

Jedes aktuelle Front-End-Framework (Angular 1/2, React, Vue, ...) kann Ihre UTC-Datums- und Uhrzeitangabe einfach und automatisch in Ortszeit umwandeln.

Zusätzlich:

(Es sei denn, Sie ändern wahrscheinlich die Zeitzone Ihrer Server.)


Beispiel mit 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' }}

Alle lokalisierten Zeitformate finden Sie hier: https://docs.angularjs.org/api/ng/filter/date


8
Ihre Daten sollten nicht an die Zeitzoneneinstellungen Ihrer Server angehängt werden. Vielleicht funktioniert es für Sie, wenn Sie eine einzelne MySql-Box unter Ihrem Schreibtisch haben
Jin

@ Jin UTC bedeutet keine Zeitzone wie TIMESTAMP. Wenn sich alle Ihre Server in UTC befinden, gibt es keine Probleme. Vielleicht funktioniert es bei Ihnen nicht, wenn Sie eine 2000er-Konfiguration haben.
Sebastien Horin

TIMESTAMP kann in Zukunft auf einen 64-Bit-Wert aktualisiert werden. Dann gibt es kein Problem mehr.
zweimal

Das Laden ganzer Bibliotheken von Drittanbietern, um so etwas zu fangen, kann auch nicht so gut für die Leistung sein, oder? Angesichts der Tatsache, dass es clientseitig ist und sich nicht auf Ihre Datenbank auswirkt ... Für alles, was Sie im Front-End tun, sind serverseitige Überprüfungen erforderlich. Also, der das Denken kompletten Bildes, ist es wirklich mit der Geschwindigkeit Problem helfen? - Diese Benchmarks sind übrigens etwas seltsam, finde ich. Die Verwendung einer Zeichenfolge in einer Abfrage zum Vergleichen von Zeitstempelfeldern fühlt sich ebenfalls ziemlich seltsam an. Das muss auch die Leistung beeinträchtigen, oder?
NoobishPro

1
Verlassen Sie sich in Ihrer Anwendung nicht auf die Zeitzone des Servers. Definieren Sie stattdessen die Zeitzone, die für jede Datenbankverbindung verwendet werden soll: SET time_zone = '+0:00';für UTC.
Dolmen

37

Ein timestampFeld ist ein Sonderfall des datetimeFeldes. Sie können timestampSpalten mit speziellen Eigenschaften erstellen . Es kann so eingestellt werden, dass es sich beim Erstellen und / oder Aktualisieren selbst aktualisiert.

In "größeren" Datenbankbegriffen timestampenthält es einige Sonderfallauslöser.

Was das Richtige ist, hängt ganz davon ab, was Sie tun möchten.


6
Nein, der Unterschied ist nicht nur "ein Sonderfall". Da die Zeitzonen der Sitzung, in der die Werte festgelegt / abgefragt werden, unterschiedlich betroffen sind.
Dolmen

Ich bin froh, dass Sie eingegeben haben: "Was das Richtige ist, hängt ganz davon ab, was Sie tun möchten." Es gibt zu viele Antworten auf SE, die ohne ausreichende Begründung "Sie dürfen niemals X tun" oder "Sie müssen immer Y tun" angeben.
Agi Hammerthief

37

TIMESTAMP ist immer in UTC (dh Sekunden seit dem 01.01.1970 in UTC), und Ihr MySQL-Server konvertiert es automatisch in das Datum / die Uhrzeit für die Verbindungszeitzone. Langfristig ist TIMESTAMP der richtige Weg, da Sie wissen, dass Ihre zeitlichen Daten immer in UTC vorliegen. Zum Beispiel werden Sie Ihre Daten nicht vermasseln, wenn Sie auf einen anderen Server migrieren oder wenn Sie die Zeitzoneneinstellungen auf Ihrem Server ändern.

Hinweis: Die Standardverbindungszeitzone ist die Serverzeitzone, diese kann (sollte) jedoch pro Sitzung geändert werden (siehe SET time_zone = ...).


29

Vergleich zwischen DATETIME, TIMESTAMP und DATE

Geben Sie hier die Bildbeschreibung ein

Was ist das [.fraktion]?

  • Ein DATETIME- oder TIMESTAMP-Wert kann einen nachlaufenden Sekundenbruchteil mit einer Genauigkeit von bis zu Mikrosekunden (6 Stellen) enthalten. Insbesondere wird jeder Bruchteil eines Werts, der in eine DATETIME- oder TIMESTAMP-Spalte eingefügt wird, gespeichert und nicht verworfen. Dies ist natürlich optional.

Quellen:


24

Ich würde immer einen Unix-Zeitstempel verwenden, wenn ich mit MySQL und PHP arbeite. Der Hauptgrund dafür ist, dass die Standard- Datumsmethode in PHP einen Zeitstempel als Parameter verwendet, sodass keine Analyse erforderlich ist.

Um den aktuellen Unix-Zeitstempel in PHP zu erhalten, tun Sie dies einfach time();
und in MySQL SELECT UNIX_TIMESTAMP();.


6
-1 Ich denke tatsächlich, dass die Antwort unten besser ist. Wenn Sie datetime verwenden, können Sie mehr Logik für die Datumsverarbeitung in MySQL selbst übertragen, was sehr nützlich sein kann.
Toby Hede

Gab es keine Benchmarks, die zeigten, dass das Sortieren in MySQL langsamer ist als in PHP?
SDKFASldF

Nun, es kommt darauf an, manchmal ist es gut, es zu verwenden, wenn wir strtotime nicht verwenden möchten. (php5.3 dep)
Adam Ramadhan

Sie können die Logik in MySQL verschieben, indem Sie bei Bedarf einfach FROM_UNIXTIME verwenden
inarilo

Früher habe ich alle Unix-Zeitstempel in meinen PHP-Anwendungen und in MySQL verwendet. Ich habe jedoch festgestellt, dass es viel bequemer ist, Datum und Uhrzeit in MySQL als native Datums- / Zeittypen zu speichern. Dies ist besonders nützlich für Berichtszwecke und zum Durchsuchen von Datensätzen. Mit der Zeit, als ich frustriert war, Unix-Zeitstempel kopieren / hinter mir lassen zu müssen, begann ich zu wechseln. Ich bin mir ziemlich sicher, dass es Leistung und andere Vor- und Nachteile gibt, aber je nach Anwendungsfall kann Bequemlichkeit wichtiger sein als ziemlich Mikrooptimierungen.
DavidScherer

24

Es ist erwähnenswert, dass Sie in MySQL beim Erstellen Ihrer Tabellenspalten Folgendes verwenden können:

on update CURRENT_TIMESTAMP

Dies aktualisiert die Zeit bei jeder Instanz, in der Sie eine Zeile ändern, und ist manchmal sehr hilfreich für gespeicherte Informationen zur letzten Bearbeitung. Dies funktioniert nur mit Zeitstempel, nicht jedoch mit Datum / Uhrzeit.


17

Wenn Sie nach meinen Erfahrungen ein Datumsfeld wünschen, in das das Einfügen nur einmal erfolgt und Sie keine Aktualisierung oder andere Aktion für dieses bestimmte Feld wünschen, gehen Sie zur Datums- und Uhrzeitangabe .

Betrachten Sie beispielsweise eine userTabelle mit einem Feld REGISTRIERUNGSDATUM . userWenn Sie in dieser Tabelle die zuletzt angemeldete Zeit eines bestimmten Benutzers wissen möchten, verwenden Sie ein Feld vom Typ Zeitstempel, damit das Feld aktualisiert wird.

Wenn Sie die Tabelle aus phpMyAdmin erstellen, aktualisiert die Standardeinstellung das Zeitstempelfeld , wenn eine Zeilenaktualisierung erfolgt. Wenn Ihr Zeitstempel nicht mit Zeilenaktualisierung aktualisiert wird, können Sie die folgende Abfrage verwenden, um ein Zeitstempelfeld automatisch zu aktualisieren.

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

15

Der Zeitstempeldatentyp speichert Datum und Uhrzeit, jedoch im UTC-Format, nicht im aktuellen Zeitzonenformat wie datetime. Und wenn Sie Daten abrufen, konvertiert der Zeitstempel diese erneut in die aktuelle Zeitzonenzeit.

Angenommen, Sie befinden sich in den USA und erhalten Daten von einem Server mit einer Zeitzone von USA. Dann erhalten Sie Datum und Uhrzeit gemäß der Zeitzone USA. Die Spalte mit dem Zeitstempeldatentyp wird immer automatisch aktualisiert, wenn ihre Zeile aktualisiert wird. Daher kann es nützlich sein zu verfolgen, wann eine bestimmte Zeile das letzte Mal aktualisiert wurde.

Weitere Informationen finden Sie im Blog-Beitrag Timestamp Vs Datetime .


Sie können (sollten) immer die Zeitzone auf Sitzungsebene mit SET time_zone = '+0:00';(UTC hier) definieren, um sicherzugehen, was Sie von den TIMESTAMPWerten erhalten / festlegen , und vermeiden, dass sich die Standardeinstellung des Servers time_zone ändert.
Dolmen

14

Ich verwende immer einen Unix-Zeitstempel, um die Vernunft beim Umgang mit vielen Datums- / Uhrzeitinformationen zu gewährleisten, insbesondere beim Anpassen von Zeitzonen, Hinzufügen / Subtrahieren von Datumsangaben und dergleichen. Wenn Sie Zeitstempel vergleichen, schließt dies die komplizierenden Faktoren der Zeitzone aus und ermöglicht es Ihnen, Ressourcen in Ihrer serverseitigen Verarbeitung (ob Anwendungscode oder Datenbankabfragen) zu schonen, indem Sie eher eine leichte Arithmetik als eine schwerere Addition / Subtraktion von Datum und Uhrzeit verwenden Funktionen.

Eine weitere erwägenswerte Sache:

Wenn Sie eine Anwendung erstellen, wissen Sie nie, wie Ihre Daten später verwendet werden müssen. Wenn Sie beispielsweise eine Reihe von Datensätzen in Ihrem Datensatz mit beispielsweise einer Reihe von Elementen aus einer Drittanbieter-API vergleichen und diese in chronologischer Reihenfolge anordnen müssen, sind Sie froh, dass Sie diese haben Unix-Zeitstempel für Ihre Zeilen. Selbst wenn Sie sich für die Verwendung von MySQL-Zeitstempeln entscheiden, speichern Sie einen Unix-Zeitstempel als Versicherung.


14

In meinem Fall habe ich UTC als Zeitzone für alles festgelegt: das System, den Datenbankserver usw., wann immer ich kann. Wenn mein Kunde eine andere Zeitzone benötigt, konfiguriere ich diese in der App.

Ich bevorzuge fast immer Zeitstempel anstelle von Datums- / Uhrzeitfeldern, da Zeitstempel implizit die Zeitzone enthalten. Da Benutzer aus verschiedenen Zeitzonen auf die App zugreifen und sie Datums- und Uhrzeitangaben in ihrer lokalen Zeitzone anzeigen möchten, ist dies mit diesem Feldtyp ziemlich einfach, als wenn die Daten in Datums- / Uhrzeitfeldern gespeichert würden .

Als Plus würde ich mich bei einer Migration der Datenbank auf ein System mit einer anderen Zeitzone sicherer fühlen, wenn ich Zeitstempel verwenden würde. Ganz zu schweigen von möglichen Problemen bei der Berechnung von Differenzen zwischen zwei Momenten mit einer dazwischen liegenden Änderung der Sommerzeit und einer Genauigkeit von 1 Stunde oder weniger.

Zusammenfassend schätze ich diese Vorteile des Zeitstempels:

  • Einsatzbereit für internationale Apps (mit mehreren Zeitzonen)
  • einfache Migrationen zwischen Zeitzonen
  • ziemlich einfach zu berechnende Differenzen (subtrahieren Sie einfach beide Zeitstempel)
  • Keine Sorge um Daten in / aus einem Sommerzeitraum

Aus all diesen Gründen wähle ich UTC- und Zeitstempelfelder, wo dies möglich ist. Und ich vermeide Kopfschmerzen;)


Zeitstempeldaten machen der Person, die Ihre Bewerbung unterstützt, Spaß, wenn der 20. Januar 2038 eintrifft. tick tock tick tock
Wilson Hauck

Der Zeitstempeltyp könnte dann um ein bisschen erhöht und die möglichen Werte verdoppelt werden.
Roger Campanera

Testen Sie Ihre Theorie, um sie ein wenig zu erhöhen, und prüfen Sie, ob Sie den 1. Februar 2038 erfolgreich speichern und mit MySQL abrufen können. Lassen Sie uns Ihre Tabellendefinition sehen, wenn Sie fertig sind. Sie werden wahrscheinlich im Februar 2038 viele unglückliche Bekannte in der Vergangenheit haben.
Wilson Hauck

1
@ WilsonHauck Sie müssen die MySQL-Version sowieso lange vor 2038 aktualisieren. Und dieser erweiterte TIMESTAMP wird von der Migration verwaltet. Abgesehen vom Umgang mit Hypotheken müssen sich derzeit nur wenige Anwendungen wirklich um 2038 kümmern.
Dolmen

@dolmen Viele professionelle Werkzeuge und Materialien haben eine Garantie von mehr als 20 Jahren. So etwas warranties.expires_atkönnte heute kein MySQL-Zeitstempel sein.
Alexw

13

Achten Sie darauf, dass sich der Zeitstempel nicht ändert, wenn Sie eine UPDATE-Anweisung für eine Tabelle ausführen. Wenn Sie eine Tabelle mit den Spalten 'Name' (varchar), 'Age' (int) und 'Date_Added' (Zeitstempel) haben und die folgende DML-Anweisung ausführen

UPDATE table
SET age = 30

Dann wird jeder einzelne Wert in Ihrer Spalte "Date_Added" in den aktuellen Zeitstempel geändert.


3
Abhängig davon, wie Sie Ihre Tabelle einrichten, können Sie dieses Verhalten steuern. Schauen Sie sich dev.mysql.com/doc/refman/5.5/en/timestamp-initialization.html an
Charles Faiga

5
@CharlesFaiga Standardmäßig wird der Zeitstempel aktualisiert, wenn eine andere Spalte aktualisiert wird. Sie müssen dies explizit deaktivieren, wenn der Zeitstempel seinen ursprünglichen Wert behalten soll
Lloyd Banks

Was ist das ?! Sie müssen die Zeitstempelspalte aufON UPDATE CURRENT_TIMESTAMP
Buchhalter م

Dies ist eine Funktion , die Sie beim Erstellen der Tabelle explizit aktivieren müssen.
Dolmen

13

Verweis aus diesem Artikel:

Die Hauptunterschiede:

TIMESTAMP wird verwendet, um Änderungen an Datensätzen zu verfolgen und jedes Mal zu aktualisieren, wenn der Datensatz geändert wird. DATETIME wird zum Speichern eines bestimmten und statischen Werts verwendet, der von Änderungen in Datensätzen nicht betroffen ist.

TIMESTAMP wird auch von verschiedenen Einstellungen für die ZEITZONE beeinflusst. DATETIME ist konstant.

TIMESTAMP konvertierte die aktuelle Zeitzone zur Speicherung intern in UTC und während des Abrufs zurück in die aktuelle Zeitzone. DATETIME kann das nicht.

Von TIMESTAMP unterstützter Bereich: '1970-01-01 00:00:01' UTC bis '2038-01-19 03:14:07' UTC DATETIME unterstützter Bereich: '1000-01-01 00:00:00' bis '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

Ein weiterer Unterschied zwischen Zeitstempel und Datumszeit besteht darin, dass Sie im Zeitstempel den Standardwert nicht auf NULL setzen können.


8
Es ist offensichtlich falsch. Hier ein Beispiel: CREATE TABLE t2 ( ts1 TIMESTAMP NULL, ts2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP); Die erste Spalte kann den Wert NULL akzeptieren.
Ormoz

10

Ich fand unübertroffene Nützlichkeit in der Fähigkeit von TIMESTAMP, sich basierend auf der aktuellen Zeit automatisch zu aktualisieren, ohne unnötige Trigger zu verwenden. Das bin nur ich, obwohl TIMESTAMP wie gesagt UTC ist.

Es kann über verschiedene Zeitzonen hinweg verfolgt werden. Wenn Sie beispielsweise eine relative Zeit anzeigen müssen, ist die UTC-Zeit genau das, was Sie möchten.


9

Der Hauptunterschied ist

  • ein INDEX auf Zeitstempel - funktioniert
  • Ein INDEX ist auf Datetime - Funktioniert nicht

In diesem Beitrag finden Sie Probleme mit der Datetime-Indizierung


6
Beide haben das gleiche Problem, wenn Sie mit einer Funktion auswählen, die auf dem Spaltenwert basiert, und beide können indiziert werden.
Marcus Adams

4
Index funktioniert mit Zeitstempel und nicht mit Datum / Uhrzeit? Sie haben aus diesen Beiträgen falsche Schlussfolgerungen gezogen.
Salman A

9

Ich habe die Verwendung datetimein meinen Anwendungen eingestellt, nachdem ich auf viele Probleme und Fehler in Bezug auf Zeitzonen gestoßen war. IMHO Verwendung timestampist besser als datetimein den meisten Fällen .

Wenn Sie fragen, wie spät ist es? und die Antwort kommt so etwas wie '2019-02-05 21:18:30', das ist nicht abgeschlossen, nicht definierte Antwort, weil es keinen anderen Teil gibt, in welcher Zeitzone? Washington? Moskau? Peking?

Die Verwendung von Datumszeiten ohne Zeitzone bedeutet, dass Ihre Anwendung nur mit einer Zeitzone arbeitet. Zeitstempel bieten Ihnen jedoch die Vorteile datetimeund die Flexibilität, denselben genauen Zeitpunkt in verschiedenen Zeitzonen anzuzeigen.

In den folgenden Fällen bereuen Sie die Verwendung datetimeund möchten, dass Sie Ihre Daten in Zeitstempeln gespeichert haben.

  1. Für den Komfort Ihrer Kunden möchten Sie ihnen die Zeiten basierend auf ihren bevorzugten Zeitzonen anzeigen, ohne dass sie rechnen müssen, und die Zeit in ihre aussagekräftige Zeitzone umrechnen. Sie müssen lediglich die Zeitzone ändern, und Ihr Anwendungscode ist identisch. (Eigentlich sollten Sie die Zeitzone immer zu Beginn der Anwendung definieren oder die Verarbeitung bei PHP-Anwendungen anfordern.)

    SET time_zone = '+2:00';
  2. Sie haben das Land geändert, in dem Sie sich aufhalten, und setzen Ihre Arbeit zur Pflege der Daten fort, während Sie sie in einer anderen Zeitzone anzeigen (ohne die tatsächlichen Daten zu ändern).

  3. Sie akzeptieren Daten von verschiedenen Kunden auf der ganzen Welt. Jeder von ihnen fügt die Zeit in seine Zeitzone ein.

Zusamenfassend

datetime = Anwendung unterstützt 1 Zeitzone (zum Einfügen und Auswählen)

timestamp = Anwendung unterstützt jede Zeitzone (sowohl zum Einfügen als auch zum Auswählen)


Diese Antwort dient nur dazu, die Flexibilität und Leichtigkeit von Zeitstempeln in Bezug auf Zeitzonen hervorzuheben. Sie deckt keine anderen Unterschiede wie die Spaltengröße, den Bereich oder den Bruch ab .


Was ist, wenn Felder verwendet datewerden und andere Felder timestampin einer Tabelle verwendet werden ? Ich denke, es wird ein neues Problem verursachen, da die Daten, nach denen gefiltert wherewird, nicht den Zeitzonenänderungen entsprechen.
Erlang P

@ErlangP In diesem Fall sollte Ihre Anwendung das Zeitzonenproblem in der dateSpalte beheben, bevor Sie die Abfrage senden.
Buchhalter م

7

Ich bevorzuge die Verwendung eines Zeitstempels, um alles in einem gemeinsamen Rohformat zu halten und die Daten in PHP-Code oder in Ihrer SQL-Abfrage zu formatieren. Es gibt Fälle, in denen es in Ihrem Code nützlich ist, alles in Sekundenschnelle zu halten.



6

Ich mag einen Unix-Zeitstempel, weil Sie in Zahlen konvertieren können und sich nur um die Zahl kümmern müssen. Außerdem addieren / subtrahieren Sie und erhalten Dauern usw. Konvertieren Sie dann das Ergebnis in ein Datum in einem beliebigen Format. Dieser Code ermittelt, wie viel Zeit in Minuten zwischen einem Zeitstempel aus einem Dokument und der aktuellen Zeit vergangen ist.

$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
Oder verwenden Sie eine von Menschen lesbare und native MySQL-Datumszeit und native MySQL-Funktionen, um Datumszeiten hinzuzufügen / zu subtrahieren.
Julien Palard
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.