Как стать автором
Обновить

Зона недопонимания

PostgreSQL *
Перевод
Автор оригинала: Josh Berkus
По некоторым причинам, само понятие «времени с часовым поясом» сбивает с толку многих пользователей и разработчиков приложений. Это влечет за собой появление огромного числа шероховатостей в случае когда приложения должны иметь дело с множеством часовых поясов. В конечном итоге разработчики пытаются оформить эту логику в виде специального кода внутри приложения, в результате чего неизбежно получают заслуженный геморрой с обработкой данных.

Вот некоторые распространенные ошибочные причины, которые я слышал, призывающие не использовать тип timestamp with time zone:

  • Я хочу хранить все в формате UTC;
  • Я не хочу получать несколько разных часовых поясов из запроса;
  • Мы используем специальную библиотеку для обработки часовых поясов;
  • Я не хочу тратить дисковое пространство для хранения часового пояса.


Все эти тезисы произрастают из фундаментального непонимания принципов хранения временных данных в базе данных.



Интуитивно, можно предположить, что timestampTZ в настоящее время хранится примерно как:

"2011-06-11 15:53:22 PDT"

То есть к самому времени добавляется информация о часовом поясе. Это далеко не так.

Вместо этого, все временные данные хранятся в виде значений UTC, вне зависимости от того какой тип использовался: timestamp without time zone или же timestamp with time zone. Разница состоит в процессе записи. Если тип данных подразумевает хранение информации о часовом поясе, то всякий раз при сохранении данных они автоматически преобразовываются из локального времени пользователя во время UTC. Когда пользователь запрашивает данные, они преобразовываются из UTC в местный часовой пояс пользователя.

Допустим, Джош живет в Калифорнии (часовой пояс «America / Los_Angeles»). Он добавляет такую строку в таблицу:

INSERT INTO messages ( user_id, message, left_at )
VALUES ( 3, 'Здорово браттело!', '2011-09-27 17:17:25' );


… тогда Брюс, что живет в Филадельфии (часовой пояс «Америки / New_York»), запросив данные, увидит:

user_id | 3
message | Здорово браттело!
left_at | 2011-09-27 20:17:25-04


… а Магнус, который живет в Швеции («Europe / Stockholm»), в свою очередь, получит:

user_id | 3
message | Здорово браттело!
left_at | 2011-09-28 02:17:25+02


Данные хранятся как UTC, но то, что каждый из пользователей видит, завязано на их местном времени.

Timestamp without time zone просто-напросто не производит никаких преобразований, предполагая, что все временные данные принадлежат одному часовому поясу.

Для большинства языков программирования есть смысл оставить обработку временных данных на совести сервера PostgreSQL, а не полагаться на дополнительный программный слой. Со всей ответственностью можно заявить: „Поддержка временных данных в Postgres по праву является эталонной. И в целом, надежнее и современнее, чем в библиотеках для PHP, Python или Perl“. Стоит также отметить, что PostgreSQL прекрасно справляется с проблемами перехода на летнее\зимнее время.

Что еще более важно, использование timestampTZ означает, что вам никогда не придется беспокоиться о написании кода приложения для отображения данных в часовом поясе пользователя. Вместо этого, вам надо просто установить параметр TIMEZONE для сеанса пользователя и временные данные автоматически будут отображаться в соответствующем часовом поясе.

Конечно, есть несколько годных причин не хранить информацию о часовом поясе:

  • Ваш драйвер или ORM не поддерживает временные зоны (хотя это может быть аргументом в пользу нового);
  • Ваш код должен также работать с СУБД без адекватной поддержки часовых поясов;
  • Вы собираетесь секционировать (partitioning) таблицу по колонке с датой и нуждаетесь в абсолютных значениях;
  • База данных никогда никогда не будет использоваться более чем в одном часовом поясе.


Но если ни одна из этих причин к вам не относится, то вам следует использовать тип timestampTZ.

Кстати, Альваро Эррера в настоящее время работает над созданием нового дополнительного типа данных, который позволит хранить часовой пояс клиентского приложения, изменившего данные. Этот тип будет востребован в узких кругах, и ни в коей мере не является заменой стандартным темпоральным типам.
Теги:
Хабы:
Всего голосов 45: ↑40 и ↓5 +35
Просмотры 34K
Комментарии Комментарии 16