Как лучше всего хранить временную метку в PostgreSQL?

20

Я работаю над дизайном БД PostgreSQL и мне интересно, как лучше хранить временные метки.

Предположения

Пользователи в разных часовых поясах будут использовать базу данных для всех функций CRUD.

Я посмотрел на 2 варианта:

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

  • bigint NOT NULL DEFAULT

Поскольку timestampя послал бы строку, которая представит точную (UTC) метку времени для момента ВСТАВКИ.

Ибо bigintя бы сохранил то же самое, но в числовом формате. (Проблемы с часовым поясом обрабатываются до того, как миллис будет передан на сервер, поэтому всегда миллис в UTC.)

Одним из основных преимуществ хранения a bigintможет быть то, что его будет проще хранить и извлекать, поскольку передача правильно отформатированной временной метки является более сложной, чем простое число (миллис со времен Unix Epoc).

Мой вопрос заключается в том, какой из них позволил бы создать наиболее гибкую конструкцию и какие могут быть подводные камни каждого подхода.

Bam
источник
Существует множество причин, по которым временная метка лучше, чем bigint для представления временных меток. Я не могу вспомнить ни одной причины, по которой bigint будет лучше, чем отметка времени.
Леннарт
Основная причина, по которой я могу думать, что BigInt может быть проще, заключается в том, что его гораздо проще найти и сохранить. Я буду обновлять мои вопросы.
Бэм

Ответы:

23

Храните временные метки как timestamp, а точнее timestamptz( timestamp with time zone), так как вы имеете дело с несколькими часовыми поясами . Это обеспечивает правильность данных и, как правило, наиболее эффективно. Убедитесь, что вы понимаете тип данных, есть некоторые заблуждения:

Для решения вашей проблемы:

Передача правильно отформатированной временной метки сложнее простого числа

Вы можете передать и получить эпоху UNIX в любом случае, если вы предпочитаете:

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

Связанный:

Если вы хотите сохранить текущую метку времени с записью в БД, используйте timestamptz столбец со значением по умолчаниюnow() . Системное время на сервере БД, как правило, гораздо более надежно и согласованно, чем несколько клиентов, которые сообщают о своем времени.
Ибо INSERTэто может быть так просто, как:

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

И просто не пишите в эту колонку. Заполняется автоматически.

Эрвин Брандштеттер
источник
Это прояснило ситуацию. В дополнение к тому факту, что временные метки хранятся в виде 8-байтовых целых чисел, таких же, как и для bigint, сохранение и извлечение с помощью функций to_timestamp делает этот выбор намного проще. Спасибо
Бэм
8

Вы всегда должны хранить данные в их собственном типе данных, чтобы вы могли использовать встроенные функции. И тип данных временной метки, очевидно, является timestamp.

Кстати, timestampэто не хранится в виде строки, она хранится как 8-байтовое целое число, точно так же , как bigint: PostgreSQL документации .

dnoeth
источник
Мои извинения, я хотел сказать, что отправлю строку для хранения, а не сохраню метку времени. Исправил это.
Бэм