Какой тип MySQL лучше всего хранит информацию о времени - Datetime или Timestamp - PullRequest
0 голосов
/ 30 мая 2018

Введение

Я понимаю, что подобные вопросы уже задавались здесь раньше.Но мне все еще нужно было провести немного больше испытаний для моего варианта использования - и я немного удивлен / смущен результатом.

Ниже приводится описание (с кодом) теста и результатов.

Я работаю над приложением, которое:

  • Записывает историю событий (события, произошедшие в определенный момент времени).
    • Эта история неизменна.Как только событие записано, мы не изменяем его.
    • Мы сообщаем об этой истории.
  • Планирует будущие, возможно, повторяющиеся действия.Например, «каждую пятницу делайте эту проверку».

Так что четкое понимание данных времени очень важно.

Я пытаюсь понять типы меток времени в MySQL (datetime и timestamp) и как они взаимодействуют с кодом Java и временными строками ISO8601.

Я прочитал документы MySQL вокруг своего типа Timestamp - как он преобразует значение времени, чтобы сохранить его как UTC, и, при извлечении, преобразует это значение UTCна сервер или сеанс часового пояса.Это звучало как хорошее хранилище «на определенный момент времени».

Тип MySQL datetime немного более непрозрачен.Эта статья (http://code.openark.org/blog/mysql/timestamp-vs-datetime-which-should-i-be-using) считает, что она не слишком отличается от строки. Я повторил запрос "SELECT NOW () + 0;") и получил такой же ответ, что и статья.

Чтобы попытаться прояснить ситуацию, я написал небольшой класс Java, который записывал в одну таблицу базы данных, состоящую из 3 столбцов:

  • tz (строка, обозначающая стандартный идентификатор часового пояса). UTC используется в тестах - ноэто не часовой пояс.
  • mydatetime (столбец Datetime)
  • mytimestamp (столбец Timestamp)

код Java

Код Java расположенздесь: https://gist.github.com/iliomad/c6d8a50613fa99e2d079b8ad3b9eca4d

Тест 1

Я создал 3 разных строки меток времени ISO8601 - все для одного и того же момента времени - но с разными смещениями / часовыми поясами. Каждая была записана в базу данных, извлеченаи распечатаны.

Для начала я установил часовой пояс сервера базы данных MySQL на "+00: 00".

Вывод

Время записив базу данных.

UTC
2018-04-13T11:12:00Z, 1523617920
Europe/Amsterdam
2018-04-13T13:12:00+02:00, 1523617920
Asia/Calcutta
2018-04-13T16:42:00+05:30, 1523617920

Чтение сохраненного времени из базы данных.

Description, Datetime column (epoch seconds), Datetime column (as ISO string), Timestamp column (as epoch seconds), Timestamp column (as ISO string)
UTC, 1523617920, 2018-04-13T11:12:00Z, 1523617920, 2018-04-13T11:12:00Z
Europe/Amsterdam, 1523617920, 2018-04-13T13:12+02:00[Europe/Amsterdam],       1523617920, 2018-04-13T13:12+02:00[Europe/Amsterdam]
Asia/Calcutta, 1523617920, 2018-04-13T16:42+05:30[Asia/Calcutta], 1523617920, 2018-04-13T16:42+05:30[Asia/Calcutta]

Все выглядит хорошо.Секундные секунды, когда они помещаются во что-то вроде https://www.epochconverter.com/,, соответствуют временным строкам ISO8601.

Тест 2

Затем я изменил часовой пояс сервера MySQL с UTC (+00: 00) в Европу / Амстердам (+02: 00) и снова прочитайте сохраненное время.

Вывод

Чтение сохраненного времени из базы данных.

Description, Datetime column (epoch seconds), Datetime column (as ISO string), Timestamp column (as epoch seconds), Timestamp column (as ISO string)
UTC, 1523617920, 2018-04-13T11:12:00Z, 1523625120, 2018-04-13T13:12:00Z
Europe/Amsterdam, 1523617920, 2018-04-13T13:12+02:00[Europe/Amsterdam], 1523625120, 2018-04-13T15:12+02:00[Europe/Amsterdam]
Asia/Calcutta, 1523617920, 2018-04-13T16:42+05:30[Asia/Calcutta], 1523625120, 2018-04-13T18:42+05:30[Asia/Calcutta]

Я ожидал, что столбец Datetime будет затронут, полагая, что он не хранит информацию о часовом поясе.Однако это был столбец Timestamp.

Заключение

Мы не будем регулярно менять часовой пояс нашего сервера.Я пытаюсь понять, какой тип данных MySQL лучше всего представляет момент времени - что-то, на что я могу рассчитывать как точное и неизменное (а не головокружительное).Исходя из вышеизложенного, если я предоставляю информацию о времени в форме строки ISO8601, тип Datetime MySQL сохраняет предоставленную информацию.

Вполне возможно, что мой тестовый код неверен и /или моя интерпретация результатов.Здесь можно сделать небольшое руководство.

В приведенном выше тесте тип MySQL Datetime лучше справляется с сохранением информации о моменте времени?

1 Ответ

0 голосов
/ 31 мая 2018

После небольшой доработки я получил класс Java, который умеет хранить и извлекать информацию на определенный момент времени.Я до сих пор немного нервничаю по этому поводу - так много частей хотят иметь свое мнение во времени, и это заставляет меня чувствовать себя неловко.

Класс находится на исходной сути: https://gist.github.com/iliomad/c6d8a50613fa99e2d079b8ad3b9eca4d (и ревизии показывают изменения).

  • Я могу изменить часовой пояс сервера MySQL на любой, какой захочу.Я все еще получаю то, что я вставил.
    • Запрос непосредственно в диспетчере запросов MySQL также ведет себя - столбец отметки времени в эпоху Unix остается устойчивым.Это то, что я ожидаю.
    • выберите tz, mydatetime, unix_timestamp (mydatetime) в качестве mydatetime_as_epoch, unix_timestamp (mytimestamp) из basic_time;
    • tz = идентификатор часового пояса (строка);mydatetime (столбец Datetime);mytimestamp (столбец Timestamp)
  • Timestamp Тип MySQL - это временная метка.Мне не нужно возиться с этим.

    • Класс Java 8 java.sql.Timestamp из методов InInstant и toInstant утверждает, что поддерживает один и тот же момент времени.
    • Я пробовал Instant в методах setObject и getObject prepareStatement.MySQL Connector / J просто не принимает их - я покопался в исходном коде для просмотра.
  • Datetime тип MySQL, я все еще немного сбит с толку (я нея не знаю, что это такое, но зная часовой пояс, я могу сохранить информацию о моменте времени.

  • Я пробовал обе версии MySQL Connector / J 5.1.46 и 8.0.11.Такое же поведение для каждого.
  • Параметр JDBC useLegacyDatetimeCode = false представляется важным.Мне нужно выполнить больше тестов с этим подтверждением и без него.

Не совсем до полного анализа этого вопроса.Не забавно пытаться понять это.

...