web-dev-qa-db-fra.com

Comment stocker au mieux un horodatage dans PostgreSQL?

Je travaille sur une conception de base de données PostgreSQL et je me demande comment stocker au mieux les horodatages.

Hypothèses

Les utilisateurs de différents fuseaux horaires utiliseront la base de données pour toutes les fonctions CRUD.

J'ai regardé 2 options:

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

  • bigint NOT NULL DEFAULT

Pour timestamp j'enverrais une chaîne qui représenterait l'horodatage (UTC) exact pour le moment INSERT.

Pour bigint je stockerais exactement la même chose, mais dans un format numérique. (les problèmes de fuseau horaire sont traités avant que des millis ne soient remis au serveur, donc toujours des millis en UTC.)

Un des principaux avantages du stockage d'un bigint pourrait être qu'il serait plus facile de stocker et de récupérer, car le passage d'un horodatage correctement formaté est plus complexe qu'un simple nombre (millis depuis Unix Epoc).

Ma question est de savoir laquelle permettrait la conception la plus flexible et quels pourraient être les pièges de chaque approche.

23
Bam

Stockez les horodatages sous la forme timestamp, ou plutôt timestamptz (timestamp with time zone ) puisque vous traitez avec plusieurs fuseaux horaires. Cela impose des données valides et est généralement plus efficace. Assurez-vous de comprendre le type de données, il y a des idées fausses qui circulent:

Pour répondre à votre préoccupation:

passer un horodatage correctement formaté est plus complexe qu'un simple nombre

Vous pouvez passer et récupérer une époque UNIX de toute façon si vous préférez:

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

En relation:

Si vous souhaitez stocker l'horodatage actuel avec les écritures dans la base de données, utilisez une colonne timestamptz avec la valeur par défaut now(). L'heure système sur le serveur de base de données est généralement beaucoup plus fiable et cohérente que plusieurs clients remettant leur notion respective de l'heure.
Pour INSERT, cela peut être aussi simple que:

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

Et n'écrivez tout simplement pas dans cette colonne. Il est rempli automatiquement.

25
Erwin Brandstetter

Vous devez toujours stocker les données dans son type de données natif afin de pouvoir utiliser les fonctions intégrées. Et le type de données d'un horodatage est évidemment un timestamp.

Btw, un timestamp n'est pas pas stocké sous forme de chaîne, il est stocké sous la forme d'un entier sur 8 octets, exactement comme bigint: documentation PostgreSQL .

9
dnoeth