Comment stocker au mieux un horodatage dans PostgreSQL?

20

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

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

Car bigintje stockerais exactement la même chose, mais dans un format numérique. (les problèmes de fuseau horaire sont traités avant la remise des millis au serveur, donc toujours des millis en UTC.)

Un des principaux avantages du stockage d'un bigintpourrait être qu'il serait plus facile de le stocker et de le 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.

Bam
la source
Il y a beaucoup de raisons pour lesquelles un horodatage est meilleur qu'un bigint pour représenter les horodatages. Je ne peux pas penser à une seule raison pour laquelle un bigint serait mieux qu'un horodatage.
Lennart
La principale raison pour laquelle je pense qu'un BigInt peut être plus facile est qu'il pourrait être beaucoup plus facile à récupérer et à stocker. Je mettrai à jour mes questions.
Bam

Réponses:

23

Stockez les horodatages en tant que timestamp, ou plutôt timestamptz( timestamp with time zone) car vous avez affaire à 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 des écritures dans la base de données, utilisez une timestamptz colonne avec la valeur par défautnow() . 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.
Car INSERTcela 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.

Erwin Brandstetter
la source
Cela a clarifié les choses. En plus du fait que les horodatages sont stockés sous forme d'entiers de 8 octets, essentiels comme le stockage en tant que bigint, le stockage et la récupération avec les fonctions "to_timestamp" rendent cela un choix beaucoup plus simple. Merci
Bam
8

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

Btw, a timestampn'est pas stocké sous forme de chaîne, il est stocké sous la forme d'un entier de 8 octets, exactement la même chose que bigint: la documentation PostgreSQL .

dnoeth
la source
Mes excuses, je voulais dire que j'enverrais une chaîne pour le stockage, pas un horodatage. Je l'ai corrigé.
Bam