Würden Sie die Verwendung eines datetime oder eine Zeitstempel Feld und warum (unter Verwendung von MySQL)?
Ich arbeite mit PHP auf der Serverseite.
Würden Sie die Verwendung eines datetime oder eine Zeitstempel Feld und warum (unter Verwendung von MySQL)?
Ich arbeite mit PHP auf der Serverseite.
Ich treffe diese Entscheidung auf einer semantischen Basis.
Ich verwende einen Zeitstempel, wenn ich einen (mehr oder weniger) festen Zeitpunkt aufzeichnen muss. Zum Beispiel, wann ein Datensatz in die Datenbank eingefügt wurde oder wann eine Benutzeraktion stattgefunden hat.
Ich verwende ein Datetime-Feld, wenn das Datum/die Uhrzeit beliebig eingestellt und geändert werden kann. Zum Beispiel, wenn ein Benutzer Termine speichern und später ändern kann.
TIMESTAMP
beträgt vier Bytes gegenüber acht Bytes bei DATETIME
.
Zeitstempel belasten auch die Datenbank weniger und werden schneller indiziert.
El DATETIME
wird verwendet, wenn Sie Werte benötigen, die sowohl Datums- als auch Zeitinformationen enthalten. MySQL ruft ab und zeigt an DATETIME
Werte in YYYY-MM-DD HH:MM:SS
Format. Der unterstützte Bereich ist 1000-01-01 00:00:00
まで 9999-12-31 23:59:59
. Die TIMESTAMP
Datentyp hat einen Bereich von 1970-01-01 00:00:01 UTC
まで 2038-01-09 03:14:07 UTC
. Sie hat unterschiedliche Eigenschaften, die von der MySQL-Version und dem SQL-Modus abhängen, in dem der Server läuft.
DATETIME
konstant ist, während TIMESTAMP
wird beeinflusst durch den time_zone
Umgebung.
Sie müssen Nr. 4 klarstellen: Der gespeicherte Zeitstempel ist konstant und nicht relativ (völlig unabhängig) zur Zeitzone, während die angezeigte Ausgabe beim Abruf von der Zeitzone der anfragenden Sitzung beeinflusst wird. DATETIME ist immer relativ zu der Zeitzone, in der es aufgezeichnet wurde, und muss immer in diesem Kontext betrachtet werden, eine Verantwortung, die nun der Anwendung zufällt.
Ich empfehle die Verwendung von weder ein DATETIME- oder ein TIMESTAMP-Feld. Wenn Sie einen bestimmten Tag als Ganzes darstellen wollen (z. B. einen Geburtstag), dann verwenden Sie den Typ DATE. Wenn Sie jedoch spezifischer sind, dann sind Sie wahrscheinlich daran interessiert, einen tatsächlichen Moment aufzuzeichnen und nicht eine Zeiteinheit (Tag, Woche, Monat, Jahr). Verwenden Sie statt 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:
Diese Frage hängt eng damit zusammen, wie Sie einen Geldwert (z.B. $1,99) in einer Datenbank speichern sollten. Sollten Sie einen Dezimalwert, den Geldtyp der Datenbank oder am schlimmsten ein Double verwenden? Alle 3 Optionen sind aus vielen der oben genannten Gründe schlecht. Die Lösung besteht darin, den Geldwert mit BIGINT in Cents zu speichern und dann Cents in Dollar umzuwandeln, wenn Sie den Wert für den Benutzer anzeigen. Die Aufgabe der Datenbank ist es, Daten zu speichern, und NICHT, diese Daten zu interpretieren. All diese ausgefallenen Datentypen, die man in Datenbanken (vor allem in Oracle) sieht, bringen wenig und führen dazu, dass man sich an einen Anbieter bindet.
Mir gefällt diese Lösung. Das Auslaufen von TIMESTAMP im Jahr 2038 ist ein großes Problem. Das ist doch gar nicht so weit weg!
Es ist schwierig, Daten nach Datum abzufragen, wenn sie als Zahl von Millisekunden gespeichert sind.
Dies sollte die akzeptierte Antwort sein. Ich verabscheue jedes der "nativen" Datumsformate. Endlose Zeitzonenfänge usw.
TIMESTAMP ist 4 Byte groß, gegenüber 8 Byte bei DATETIME.
http://dev.mysql.com/doc/refman/5.0/en/storage-requirements.html
Aber wie scronide sagte, gibt es eine untere Grenze für das Jahr 1970. Es ist jedoch großartig für alles, was in der Zukunft passieren könnte ;)
Weder noch. Die DATETIME
y TIMESTAMP
Typen sind für allgemeine Anwendungsfälle grundsätzlich nicht geeignet. MySQL wird sie in Zukunft ändern. Sie sollten BIGINT
und UNIX-Zeitstempel, es sei denn, Sie haben einen besonderen Grund, etwas anderes zu verwenden.
Hier sind einige spezifische Situationen, in denen Ihre Wahl einfacher ist und Sie die Analyse und allgemeine Empfehlung in dieser Antwort nicht benötigen.
Nur Datum - wenn Sie sich nur für das Datum interessieren (z. B. das Datum des nächsten Mondneujahrs, 2022-02-01) UND Ihnen klar ist, in welche Zeitzone dieses Datum fällt (oder es Ihnen egal ist, wie im Fall des Mondneujahrs), dann verwenden Sie die DATE
Spaltentyp.
Einfügezeiten aufzeichnen - wenn Sie die Einfügedaten/-zeiten für Zeilen in Ihrer Datenbank protokollieren UND es Ihnen egal ist, dass Ihre Anwendung in den nächsten 17 Jahren brechen wird dann verwenden Sie einfach TIMESTAMP
mit einem Standardwert von CURRENT_TIMESTAMP()
.
TIMESTAMP
kaputt?El TIMESTAMP
Typ wird auf der Festplatte in der Zeitzone UTC gespeichert. Das bedeutet, dass Ihr Server nicht kaputt geht, wenn Sie ihn physisch bewegen. Das ist gut. Aber Zeitstempel, wie sie derzeit definiert sind, werden im Jahr 2038 nicht mehr funktionieren.
Jedes Mal, wenn Sie INSERT INTO
o SELECT FROM
a TIMESTAMP
Spalte wird der physische Standort (d. h. die Zeitzonenkonfiguration) Ihres Clients/Anwendungsservers berücksichtigt. Wenn Sie Ihren Anwendungsserver verlegen, ändern sich Ihre Daten.
VARCHAR
kaputt?El VARCHAR
ermöglicht die eindeutige Speicherung eines nicht-lokalen Datums/einer nicht-lokalen Uhrzeit/beides im ISO 8601-Format und funktioniert für Daten nach 2037. Es ist üblich, die Zulu-Zeit zu verwenden, aber ISO 8601 erlaubt die Kodierung eines beliebigen Offsets. Dies ist weniger nützlich, da die MySQL-Datums- und Zeitfunktionen zwar Zeichenketten als Eingabe überall dort unterstützen, wo Datum/Uhrzeit/beides erwartet wird, das Ergebnis aber falsch ist, wenn die Eingabe Zeitzonen-Offsets verwendet.
Auch VARCHAR
verwendet zusätzliche Bytes an Speicherplatz.
DATETIME
kaputt?A DATETIME
speichert eine DATE
und eine TIME
in derselben Spalte. Beides hat keine Bedeutung, wenn die Zeitzone nicht bekannt ist, und die Zeitzone ist nirgendwo gespeichert. Sie sollten die gewünschte Zeitzone als Kommentar in die Spalte einfügen, da die Zeitzone untrennbar mit den Daten verbunden ist. Nur wenige Leute verwenden Spaltenkommentare, daher ist dies ein Fehler, der nur darauf wartet zu passieren. Ich habe einen Server aus Arizona geerbt und muss daher immer alle Zeitstempel VON der Zeit in Arizona und dann in eine andere Zeit umwandeln.
(Update 2021-12-08 Ich habe den Server nach Jahren der Betriebszeit neu gestartet und der Datenbank-Client (mit Upgrades) wurde auf UTC zurückgesetzt. Das bedeutet, dass meine Anwendung Daten vor und nach dem Zurücksetzen unterschiedlich behandeln muss. Hardcode!)
Die einzige Situation, in der ein DATETIME
richtig ist, diesen Satz zu vervollständigen:
Ihr neues Sonnenjahr 2020 beginnt genau um
DATETIME("2020-01-01 00:00:00")
.
Es gibt keine andere gute Verwendung für DATETIME
s. Vielleicht stellen Sie sich einen Webserver für eine Stadtverwaltung in Delaware vor. Die Zeitzone für diesen Server und alle Personen, die auf diesen Server zugreifen, liegt doch sicher in Delaware, in der Eastern Time Zone, oder? Falsch! In diesem Jahrtausend denken wir alle, dass Server in der "Wolke" existieren. Es ist also immer falsch, Ihren Server in einer bestimmten Zeitzone anzusiedeln, denn Ihr Server wird eines Tages verlegt werden.
Hinweis: MySQL ist jetzt unterstützt Zeitzonenverschiebungen en DATETIME
Literale ( danke @Marko ). Dies kann das Einfügen von DATETIME
Das ist zwar bequemer für Sie, aber die unvollständige und daher unbrauchbare Bedeutung der Daten, die dieses fatale Problem kennzeichnet (""), wird dadurch nicht behoben.
BIGINT
?Definieren Sie:
CREATE TEMPORARY TABLE good_times (
a_time BIGINT
)
Einen bestimmten Wert einfügen:
INSERT INTO good_times VALUES (
UNIX_TIMESTAMP(CONVERT_TZ("2014-12-03 12:24:54", '+00:00', @@global.time_zone))
);
Oder natürlich ist dies viel besser von Ihrer Anwendung, wie:
$statement = $myDB->prepare('INSERT INTO good_times VALUES (?)');
$statement->execute([$someTime->getTimestamp()]);
Wählen Sie aus:
SELECT a_time FROM good_times;
Es gibt Techniken zum Filtern relativer Zeiten (Auswahl von Beiträgen innerhalb der letzten 30 Tage, Suche nach Nutzern, die innerhalb von 10 Minuten nach der Registrierung gekauft haben), die den Rahmen dieses Artikels sprengen würden.
Ihr Argument, dass DATETIME keine Bedeutung hat, wenn die Zeitzone nicht verstanden wird, macht es nicht kaputt. Ihr Anwendungscode sollte den datetime-Wert in die gewünschte Zeitzone konvertieren, bevor er ihn in die Datenbank einfügt, damit Sie beim Abrufen des Wertes aus der Datenbank wissen, in welcher Zeitzone er sich befindet. Selbst das ist unnötig, wenn sich Ihre Anwendung nicht um die Zeitzone kümmert, was der Fall wäre, wenn alle Benutzer der Anwendung in derselben Zeitzone sind (z. B. wenn die Anwendung nur in Frankreich verwendet wird).
@Marko dieses Argument gilt auch für die Speicherung von Datumswerten in einer Datenbank als VARCHAR
: Ihr Anwendungscode sollte den Wert in das gewünschte Format konvertieren, bevor er in die Datenbank eingefügt wird. Meiner Meinung nach sind Datenbanken dazu da, Daten zu speichern, einschließlich des gesamten Kontexts, der notwendig ist, damit diese Daten eine Bedeutung haben.
Nein, das gilt nicht gleichermaßen, da Sie VARCHAR-Werte nicht mit den in der Datenbank integrierten Datumsfunktionen und Datumsvergleichsoperatoren bearbeiten können.
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.
2 Stimmen
Hier finden Sie einige wichtige Informationen codeproject.com/Tipps/1215635/MySQL-DATETIME-vs-TIMESTAMP
11 Stimmen
Wenn Sie möchten, dass Ihre Anwendung im Februar 2038 unterbrochen wird, verwenden Sie timestamp. Prüfen Sie den Datumsbereich.
0 Stimmen
Wenn auch nur die geringste Möglichkeit besteht, dass Ihre Datenbank Werte in einer anderen Zeitzone speichern oder Verbindungen von einer Anwendung in einer anderen Zeitzone empfangen muss, sollten Sie ISO-8601 CHARs für alle wichtigen Zeitstempel verwenden. Siehe diese Frage: stackoverflow.com/questions/40670532/
0 Stimmen
Datetime ist völlig nutzlos . es ist nur ein dummer String. timestamp ist in jeder Hinsicht perfekt sondern sie endet im Jahr 2038.