Wie speichere ich einen Zeitstempel am besten in PostgreSQL?

19

Ich arbeite an einem PostgreSQL-DB-Design und frage mich, wie ich Zeitstempel am besten speichern kann.

Annahmen

Benutzer in verschiedenen Zeitzonen verwenden die Datenbank für alle CRUD-Funktionen.

Ich habe mir 2 Möglichkeiten angesehen:

  • timestamp NOT NULL DEFAULT (now() AT TIME ZONE 'UTC')

  • bigint NOT NULL DEFAULT

Für timestampwürde ich eine Zeichenfolge senden, die den genauen (UTC) Zeitstempel für den INSERT Moment darstellen würden.

Denn bigintich würde genau das Gleiche speichern, aber in einem Zahlenformat. (Zeitzonenprobleme werden behandelt, bevor Millis an den Server übergeben wird, also immer Millis in UTC.)

Ein Hauptvorteil beim Speichern von a bigintkönnte sein, dass es einfacher zu speichern und abzurufen ist, da die Übergabe eines korrekt formatierten Zeitstempels komplexer ist als eine einfache Zahl (Millis seit Unix Epoc).

Meine Frage ist, welches das flexibelste Design zulässt und was die Fallstricke jedes Ansatzes sein könnten.

Bam
quelle
Es gibt viele Gründe, warum ein Zeitstempel für die Darstellung von Zeitstempeln besser ist als eine Ganzzahl. Ich kann mir keinen einzigen Grund vorstellen, warum ein Bigint besser wäre als ein Zeitstempel.
Lennart
Der Hauptgrund, warum ich der Meinung bin, dass ein BigInt einfacher sein kann, ist, dass es möglicherweise viel einfacher abzurufen und zu speichern ist. Ich werde meine Fragen aktualisieren.
Bam

Antworten:

23

Speichern Sie Zeitstempel als timestampoder besser als timestamptz( timestamp with time zone), da Sie mit mehreren Zeitzonen arbeiten . Das erzwingt gültige Daten und ist in der Regel am effizientesten. Vergewissern Sie sich, dass Sie den Datentyp verstanden haben. Es gibt einige Missverständnisse:

Um Ihr Anliegen anzusprechen:

Das Übergeben eines korrekt formatierten Zeitstempels ist komplexer als eine einfache Zahl

Sie können eine UNIX-Epoche auf beide Arten übergeben und abrufen, wenn Sie dies vorziehen:

SELECT to_timestamp(1437346800)
     , extract(epoch FROM timestamptz '2015-07-20 01:00+02');

Verbunden:

Wenn Sie den aktuellen Zeitstempel mit Schreibvorgängen in die Datenbank speichern möchten , verwenden Sie eine timestamptz Spalte mit Standardwertnow() . Die Systemzeit auf dem DB-Server ist in der Regel viel zuverlässiger und konsistenter als mehrere Clients, die ihre jeweilige Uhrzeit angeben.
Denn INSERTes kann so einfach sein wie:

CREATE TABLE foo (
  ... -- other columns
, created_at timestamptz NOT NULL DEFAULT now()
);

Und schreibe einfach nicht in diese Spalte. Es wird automatisch ausgefüllt.

Erwin Brandstetter
quelle
Dies machte die Dinge klar. Neben der Tatsache, dass Zeitstempel als 8-Byte-Ganzzahlen gespeichert werden, vereinfacht das Speichern und Abrufen mit den "to_timestamp" -Funktionen die Auswahl erheblich. Vielen Dank
Bam
8

Sie sollten Daten immer in ihrem nativen Datentyp speichern, damit Sie die integrierten Funktionen verwenden können. Und der Datentyp eines Zeitstempels ist offensichtlich a timestamp.

Btw, eine timestampwird nicht als String gespeichert ist , ist es als eine 8-Byte - Ganzzahl gespeichert, genau das gleiche wie bigint: PostgreSQL - Dokumentation .

dnoeth
quelle
Meiner Entschuldigung nach wollte ich sagen, dass ich eine Zeichenfolge zum Speichern senden und keinen Zeitstempel speichern würde. Korrigiert es.
Bam