Es gibt eine lange und recht verständliche Antwort auf die Unterschiede zwischen
TIMESTAMP WITH TIME ZONE
-vs-TIMESTAMP WITHOUT TIME ZONE
verfügbar in diesem SO Beitrag . Was ich wissen möchte, ist: Gibt es gültige Anwendungsfälle für die tatsächliche Verwendung TIMESTAMP WITHOUT TIME ZONE
oder sollte dies als Antimuster angesehen werden?
postgresql
Marcus Junius Brutus
quelle
quelle
Antworten:
Dies wird an vielen Stellen angegeben, aber ich denke, es ist immer erwähnenswert, wenn wir die
timestamp with time zone
mittimestamp without time zone
Typen vergleichen : Die Zeitzoneninformationen werden nicht zusammen mit dem Zeitstempeltimestamp WITH time zone
gespeichert . Damit werden alle Daten in der UTC-Zeitzone gespeichert, wie in den Dokumenten angegeben :Es wird für einige als gültig erachtet
timestamp WITHOUT time zone
, wenn (1) sich alles in derselben Zeitzone befindet oder (2) die Anwendungsebene die Zeitzone verwaltet und alles in einer bestimmten Zeitzone (normalerweise UTC) speichert. Es wird jedoch auch als Antimuster angesehen, da die richtige Lösung für (1) darin besteht, die Einstellung für die Zeitzone auf die angegebene Zeitzone für das System zu konfigurieren, und (2) bereits gelöst ist, da PostgreSQL bereits alles in derselben Zeitzone speichert (KOORDINIERTE WELTZEIT).Jetzt, wo die beiden unten sind, kann ich nur einen guten Grund nennen
timestamp WITHOUT time zone
. In diesem Fall möchten Sie Ereignisse in der Zukunft speichern, und zu diesem Zeitpunkt muss eine Warnung ausgelöst werden. Das könnte nützlich sein,timestamp WITH time zone
wenn und nur dann, wenn sich die Regeln, die in den regionalen Gesetzen zur Zeitzone festgelegt sind, nie geändert haben. Die häufigste Regel, die sich ändert, bezieht sich auf die Annahme oder Nichteinhaltung der Sommerzeit.Stellen Sie sich beispielsweise vor, Sie
2013-06-15
planen (noch nicht in der Sommerzeit) ein Ereignis für2013-01-15 10:00
(das sich bereits in der Sommerzeit befindet), und in2013-06-15
Ihrer Region wurde die Einführung der Sommerzeit festgelegt. Aber einige Zeit später änderte die Regierung die Regel und sagte, dass Ihre Region die Sommerzeit nicht mehr verwenden wird, und plötzlich wird Ihre geplante Zeit2013-01-15 11:00
(anstelle von10:00
) diejenige, die Sie verwendentimestamp WITH time zone
, und halten Sie Ihre TZ-Konfigurationen auf dem neuesten Stand. Natürlich können Sie auch bemerken, dass es möglich ist, solche Fälle auch mit Zeitzonen zu behandeln, wenn Sie die Regeländerungen in den Regionen / Zeitzonen Ihres Interesses verfolgen und die betroffenen Datensätze aktualisieren.Erwähnenswert ist, dass einige Regionen diese Regeln häufig ändern (wie in Brasilien, einige Bundesstaaten - nicht das ganze Land - ändern sich häufig), aber in den meisten Fällen ändert es sich sehr viel früher, sodass Ihre Benutzer nur von Ereignissen betroffen sind, die sehr weit entfernt von geplant sind die aktuelle Zeit.
Nach alledem habe ich nur noch einen Vorschlag. Wenn Sie Benutzer, Protokolle oder andere Elemente in unterschiedlichen Zeitzonen haben, speichern Sie die Zeitzone, aus der sie stammen, und wählen Sie sie aus und verwenden Sie sie
timestamp with time zone
. Auf diese Weise können Sie (1) Ereignisse, die näher beieinander liegen, für verschiedene Quellen (unabhängig von ihrer Zeitzone) überqueren und (2) die ursprüngliche Zeit (die Uhrzeit) des Ereignisses anzeigen.quelle
Ja. Es gibt Anwendungsfälle für
TIMESTAMP WITHOUT TIME ZONE
.TIMESTAMP WITH TIME ZONE
und nichtWITHOUT
.TIMESTAMP WITHOUT TIME ZONE
Werte sind kein Punkt auf der Zeitachse, keine tatsächlichen Momente. Sie geben eine ungefähre Vorstellung von potenziellen Momenten und möglichen Punkten auf der Zeitachse in einem Bereich von etwa 26 bis 27 Stunden (dem Bereich der Zeitzonen rund um den Globus). Sie haben keine wirkliche Bedeutung, bis Sie eine Zeitzone oder einen Versatz von UTC anwenden .ZB: Weihnachten
Angenommen, Sie müssen den Beginn von Feiertagen / Feiertagen aufzeichnen.
Um zu erfassen, dass Weihnachten am 25. Dezember dieses Jahres nach Mitternacht beginnt, müssen wir
2016-12-25 00:00:00
keine Zeitzone angeben . Früh am Tag des Weihnachtsmanns besucht er kurz nach Mitternacht Auckland, Neuseeland, da dies eine der frühesten Mitternächte der Welt ist. Dann arbeitet er sich nach Westen vor, bis die nächste Mitternacht die Philippinen erreicht. Dann bewegen sich die Rentiere in westlicher Richtung und erreichen Indien um Mitternacht, was einige Stunden nach Mitternacht in Auckland passiert. Viel später ist noch Mitternacht in Paris FR und noch später Mitternacht in Montreal CA. Alle diese Besuche des Weihnachtsmanns finden zu unterschiedlichen Zeitpunkten statt , und doch geschahen alle kurz nach Mitternacht, je nach Lokalität um Mitternacht.Das Aufnehmen
2016-12-25 00:00:00
ohne Zeitzone zu Beginn von Weihnachten ist also informativ und legitim, aber nur vage. Bis Sie "Weihnachten in Auckland" oder "Weihnachten in Montréal" sagen, haben wir keinen bestimmten Zeitpunkt. Wenn Sie bei jedem Aufsetzen des Schlittens den tatsächlichen Moment aufzeichnen, verwenden SieTIMESTAMP WITH TIME ZONE
statt desWITHOUT
Typs.Ähnlich wie Weihnachten ist Silvester. Wenn der Times Square Ball in New York fällt , kühlen die Leute in Seattle immer noch ihren Champagner und bereiten ihre Partyhörner vor . Dennoch würden wir die Idee des Neujahrsmoments wie
2017-01-01 00:00:00
in aTIMESTAMP WITHOUT TIME ZONE
. Wenn wir dagegen aufzeichnen möchten, wann der Ball in New York gefallen ist oder wann die Leute in Seattle ihre Hörner geblasen haben, würden wir stattdessen diese tatsächlichen Momente drei Stunden hintereinander aufzeichnenTIMESTAMP WITH TIME ZONE
(nichtWITHOUT
).Beispiel: Fabrikschichten
Ein anderes Beispiel könnte das Aufzeichnen einer Richtlinie sein, bei der die Uhrzeit an verschiedenen Orten angezeigt wird. Sagen wir, wir haben Fabriken in Detroit, Düsseldorf und Delhi. Wenn wir sagen, dass in allen drei Fabriken die erste Schicht um 6 Uhr morgens mit einer Mittagspause um 11:30 Uhr beginnt, könnte dies als ein
TIMESTAMP WITHOUT TIME ZONE
. Auch diese Informationen sind auf vage Weise nützlich, geben jedoch keinen bestimmten Zeitpunkt an, bis wir eine Zeitzone anwenden. Im Osten bricht früher ein neuer Tag an. Das Werk in Delhi wird also um 6 Uhr morgens als erstes eröffnet. Stunden später beginnt das Düsseldorfer Werk um 6 Uhr morgens mit der Arbeit. Die Fabrik in Detroit wird jedoch erst sechs Stunden später, wenn 6 Uhr morgens, eröffnet.Vergleichen Sie diese Idee (wann die Fabrikschicht im Allgemeinen beginnt) mit der historischen Tatsache, wann jeder Fabrikarbeiter eingewechselt ist, um seine Schicht an einem bestimmten Tag zu beginnen. Das Eintakten ist ein echter Moment, ein tatsächlicher Punkt auf der Timeline. Wir würden das also in einer Spalte vom Typ
TIMESTAMP WITH TIME ZONE
und nicht vomWITHOUT
Typ aufzeichnen .Also, ja, es gibt legitime Anwendungsfälle für
TIMESTAMP WITHOUT TIME ZONE
. Nach meiner Erfahrung mit Geschäftsanwendungen sind sie jedoch relativ selten. Im Geschäftsleben kümmern wir uns in der Regel um die tatsächlichen Momente: Wann ist die Rechnung tatsächlich angekommen, wann tritt genau dieser Vertrag in Kraft, zu welchem Zeitpunkt wurde die Banküberweisung ausgeführt. In solchen Situationen wollen wir denTIMESTAMP WITH TIME ZONE
Typ.Weitere Informationen finden Sie unter Meine Antwort auf die ähnliche Frage: Soll ich UTC-Zeitstempel oder Ortszeiten für Schichten speichern?
Postgres
Beachten Sie, dass Postgres die beim Einfügen eines Zeitstempels angegebenen Zeitzoneninformationen niemals speichert.
TIMESTAMP WITH TIME ZONE
TIMESTAMP WITH TIME ZONE
alsTIMESTAMP WITH RESPECT FOR TIME ZONE
.TIMESTAMP WITHOUT TIME ZONE
Der SQL-Standard geht kaum auf Probleme mit Datums- und Uhrzeitdatentypen und -verhalten ein. So Datenbank variieren weit in den Umgang mit Datum-Zeit.
quelle
21:00
)Ich möchte dem noch eine andere Ansicht hinzufügen, die gegen vieles verstößt, was in den anderen Antworten geschrieben wurde. Meiner Meinung nach
timestamp with time zone
hat sehr wenig valide Anwendungsfälle undtimestamp without time zone
sollte im Allgemeinen bevorzugt werden.Zunächst müssen Sie das Muster "UTC everywhere" verstehen, das im Allgemeinen für alle Anwendungen empfohlen wird, für die keine besonderen Anforderungen gelten. Das bedeutet einfach, dass Ihre Anwendung alle Zeitstempel in UTC überall und jederzeit darstellen soll. Natürlich werden Sie Benutzern das lokale Datum und die lokale Uhrzeit anzeigen, aber die Idee ist, diese beim Rendern der Ansicht ganz am Rand Ihres Programms zu konvertieren. Dies ist der richtige Ort, um den UTC-Zeitstempel (den Sie möglicherweise aus einer Datenbank geladen haben) und die Zeitzone des Benutzers (die möglicherweise aus dem Browser stammt) in einem lokalen Zeitstempel zu kombinieren.
Wenn Sie diesem Muster folgen,
timestamp with time zone
handelt es sich um ein Anti-Muster. Dieser Typ bewirkt lediglich, dass PostgreSQL beim Lesen und Schreiben von Zeitstempeln Zeitzonenkonvertierungen basierend auf Ihrer PostgreSQL-TimeZone
Sitzungsvariablen durchführt. Anstatt sich mit Zeitzonen am Rande Ihrer Anwendung zu befassen, haben Sie sie in ihr Herzstück, in die Kommunikation mit Ihrer Datenbank, eingeführt. Sie müssen darauf achten, dass PostgreSQL immerTimeZone
ordnungsgemäß konfiguriert ist, um eine weitere unnötige Fehler- und Verwirrungsquelle zu schaffen.Und wofür? Wenn Sie dem UTC-Überall-Muster folgen, hat Ihre Anwendung sowieso nur UTC-Zeitstempel. Warum also Ihre Datenbank auffordern, Zeitzonen-Konvertierungen für sie durchzuführen? Sie können sie einfach in einer
timestamp without time zone
Spalte speichern und so behandeln, als ob es immer UTC ist. Keine Konvertierungen, keine Zeitzonen, keine Komplikationen.quelle
Instance
Idealerweise sollten Sie jedoch einen Client-Typ verwenden, der nur einen UTC-Zeitstempel darstellen kann (z. B. einen in NodaTime / JodaTime). Sie beschreiben im Grunde eine Situation, in der "UTC überall" fast verfolgt wird, oder irgendwie gefolgt ...timestamptz
. Der springende Punkt bei diesem Typ ist die Durchführung von Zeitzonen-Konvertierungen als gelesene und in PostgreSQL geschriebene Werte (intern in der Datenbank wird der Zeitstempel immer als UTC gespeichert). Wenn Sie die Sitzungszeitzone immer auf UTC einstellen, werden diese Konvertierungen deaktiviert. Warum alsotimestamptz
überhaupt verwenden? Anders ausgedrückt: Wenn die Werte in der Datenbank UTC sind und die in und aus der Datenbank eingehenden Werte immer UTC sind, warum hat Ihre Datenbank dann überhaupt eine Zeitzonenerkennung?Der
date
Zeitstempel enthält auch keine Zeitzoneninformationen, die jedoch von vielen Personen verwendet werden.Natürlich ist das an sich keine Antwort.
Es ist gültig,
timestamp
unddate
für alle Zeitstempel und Datumsangaben zu verwenden, die sich immer in derselben Zeitzone befinden oder relativ zu einer bekannten Zeitzone gespeichert werden.Wenn die Zeitzone immer gleich oder implizit ist, ist es eher ein Gegenmuster, sie zu speichern, als sie nicht zu speichern (redundante Informationen).
Zeitstempel können auch zum Speichern technischer Informationen verwendet werden, wie sie in Anwendungsprotokollen oder für Leistungsmessungen verwendet werden. In diesem Fall kann die Zeitzone auch unwichtig sein.
Wenn Sie dagegen ein verteiltes System entwerfen oder daran arbeiten oder sich in einem System befinden, in dem Teile des Systems auf verschiedene Zeitzonen verteilt sind, wird dies möglicherweise als nicht zu verwendendes Antimuster angesehen
timestamp with timezone
, obwohl einige Systeme möglicherweise für die Ausführung ausgelegt sind in einer Zeitzone, zB UTC. In diesem Fall wird die Zeitzonenlogik möglicherweise in die Anwendungsebene verschoben - aber ich würde dies als Anti-Pattern betrachten, ja.quelle
timestamp without timezone
tut, es zu benutzen , aber kauft es mir jemals etwas? Ansonsten, warum sollte ich mich darum kümmern, wenn dertimestamp with timezone data
Typ immer gleich oder passender ist?timestamp without timezone
auch schneller ist, aber das ist wahrscheinlich nur wichtig, wenn Sie Milliarden von Zeilen verarbeiten ...timestamp
undtimestamptz
werden beide gleich gespeichert. In a werden keine Zeitzoneninformationen gespeicherttimestamptz
, sondern zum Speichern in UTC konvertiert. Ich würde sagen, immer verwenden,timestamptz
wenn die fraglichen Zeitstempel die absolute Zeit bezeichnen . Das ist alles wastimestamptz
bedeutet. Ich habe darüber geschrieben hier .Das Speichern und Verarbeiten von Datums- und Uhrzeitangaben in der Ortszeit erscheint möglicherweise zeitaufwändig, wenn Ihre Bewerbung auf eine einzelne Zeitzone beschränkt ist. Ich halte dies jedoch für einen Fehler.
Beim Zurückschalten von Sommerzeit auf Standardzeit wird eine Stunde in Ortszeit wiederholt (vorausgesetzt, die Differenz beträgt eine Stunde). Wo ich wohne, geschieht dies normalerweise um 2 Uhr morgens, sodass die Ortszeit zwischen 01:58, 01:59 und 01:00 Uhr läuft und erst am Ende der wiederholten Stunde bis 02:00 Uhr vorrückt.
Wenn Sie versuchen, Ereignisse zeitlich nach Ortszeit zu ordnen, bedeutet dies, dass Ereignisse aus zwei verschiedenen Stunden miteinander vermischt werden und nicht in der Reihenfolge angezeigt werden, in der sie tatsächlich stattgefunden haben.
Zum Vergleich: UTC hat dieses Problem nicht und bestellt sauber. Selbst wenn Sie mit nur einer Zeitzone arbeiten, möchten Sie, dass die Datenbank die Zeiten in UTC speichert und verarbeitet und für die Eingabe / Anzeige in / von der Ortszeit konvertiert. Dies ist das Verhalten von TIMESTAMP WITH TIME ZONE.
quelle