Comments 19
Спасибо, про ограничения serial не знал
Честно скажу, я не разделяю общей любви к timestamptz. Хранит даты в непонятно какой таймзоне настроенной где-то там на стороне сервера безо всякого твоего контроля (особенно если база предоставляется "облачно" - да даже если не облачно, то в любом моменте когда база администрируется dba а не создателем приложения), и при неучёте этого поведения можно получить совсем не то что ожидаешь...
Я предпочитаю всё же использовать timestamp, в названии колонки явно указывать что это utc (либо если по какой-то странной причине нужно в другой таймзоне - указывать что это local и рядом создавать ещё одну колонку с указанием таймзоны), и на уровне приложения уже передавать именно utc.
База не предназначена для конвертаций таймзон как по мне, это дело приложения, там слишком много подводных камней. А если очень нужно сравнить две даты - используйте utc и не морочьте никому голову.
Можете описать, пожалуйста , что за подводные камни конвертации? Если у нас есть локальное время и смещение, то абсолютное получить можно легким движением руки, разве нет?
Как минимум - всякие особенности при вычислении времени в момент когда таймзона переходит с зимнего на летнее время и обратно. А вообще чёрной магии на уровне таймзон хватает. На уровне приложения можно это дополнительно доучесть - собственно либы всякие часто предоставляют методы "из коробки" для того чтобы это доучесть - а на уровне базы данных таких расширенных инструментов нету.
Хранит даты в непонятно какой таймзоне настроенной где-то там на стороне сервера безо всякого твоего контроля
Просто используйте на серверах UTC. Или выставляйте в сессии time zone в UTC. Ваш кэп.
Если без шуток, то это очень удобно когда у вас инфраструктура по всему глобусу размазана. И даже имеет смысл когда у вас всё в одном городе стоит, ведь никто не даст гарантий, что завтра у вас ещё города/страны не появится.
Хранит даты в непонятно какой таймзоне настроенной где-то там на стороне сервера безо всякого твоего контроля
Что за бред? Значения хранятся в UTC. При сохранении значения можно явно указать к какому часовому поясу оно относится и настройки сервера, на котором БД, ни на что не повлияют
Хранится - да, а отдаётся в таймзоне сервера если не указать иное. И по факту если не озаботиться с явным указанием таймзоны когда вычитываешь данные - то получишь не то что ожидаешь.
Отдается тоже в UTC. По крайней мере это справедливо для драйвера PostgreSQL в Java. При касте в текст он меняет на другую зону, но и это не проблема, так как она указывается на конце.
varchar(n) vs text
в более расширенном варианте:
https://ru-postgres.livejournal.com/65930.html .
уж сколько раз твердили миру...
Но timestamp without timezone
, в лучшем случае, а то ведь есть товарищи, которые таймстампы в bigint
хранят! и varchar(n)
- в каждом первом проекте. И смотреть на миграции, в которых прилично DROP VIEW
, DROP FUNCTION
потому что надо изменить размер поля varchar(n)
- это БОЛЬНО. А с учётом того, что людишки, просмотрев материал выше, продолжают творить дичь из релиза в релиз, не утруждая себя сменить тип на нормальный...
По поводу timestamp когда-то читал диаметрально противоположное мнение. В документации написано, что timestamp, с зоной или без зоны, хранится в UTC, если зона не указана, для конвертации используется системная. В итоге, главное скормить время с временной зоной, а в каком типе оно будет храниться - неважно.
Полагаю, что для большинства задач удобно работать с абсолютным временем.
Другое дело, что есть те же пассажирские перевозки (авиа) где очень важно хранить информацию о локальном времени. Для такой специфики можно использовать два поля: timestamp_local & timestamp_utc
timestamptz хранит в UTC. timestamp сохраняет значение как есть (без преобразований), не отображает часовой пояс, не использует временную зону, timestamptz
отображает и выполняет вычисления во временной зоне, задаваемой параметром timezone:

timestamp, timestamptz не хранят часовой пояс, значения физически хранятся в одинаковом виде, занимают 8 байт.
Последний пример максимально странный. Вы бы ещё '{"color":0}'
вот с этим '<important-property><property-name>color</property-name><property-value>00000</property-value></important-property>'
сравнили. Тогда эффект был бы ещё заметнее.
Понятно, что XML более многословен, чем JSON, однако в данном примере можно и просто '<color>0</color>'
Или добавить корень, если это более сложный объект. Так уже не столь катастофично смотрится.
Тут есть момент, что подразумевается сравнение структурированного хранения ключ-значение. Автор приводит пример ключ-значение на XML и JSON. В итоге очевидно, что в XML больше синтаксических обвесов для этого надо. Суть сравнения именно в этом. Использовать в качестве ключа сам тег не всегда подойдет.
Это не однозначно очевидно. Объекты в json тоже сериализуются так. В данном случае имеем список свойств (на что прямо указывает тэг property), которые вполне могут быть свойствами объекта. Т.е. могут быть заменены на тэги.
Если нужет компактный список ключ-значение - ничто не мешает их хранить в виде <k>key</k><v>value</v> или даже <property key="k" value="v"/>. Разница уже опять не столь драматическая.
Сам факт сравнения "0" и "000000" крайне прозрачно намекает, что никакого честного сравнения не предполагалось.
А есть ли какая нибудь утилита, которой указываешь Postgresql и она показывает в выводе какие типы данных нужно поправить?
Как не облажаться с типами данных в PostgreSQL