Je travaille sur une conception de base de données PostgreSQL et je me demande comment stocker au mieux les horodatages.
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.
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.
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 .