MySQL 5.7 Поле метки времени, показывающее дату и время? - PullRequest
2 голосов
/ 06 мая 2019

В моей базе данных есть столбец с именем time. тип этого столбца timestamp и значение по умолчанию CURRENT_TIMESTAMP

Но после некоторых вставок в phpMyAdmin оно показывает значение как datetime, например 2019-05-05 04:24:45 и даже часовой пояс отображается там и может быть изменен!

Я думал, что временная метка MySQL составляет 4 байта (по сравнению с 8 байтами даты и времени) и не хранит часовой пояс, а данные такие же, как INT (10), например: 1557094115 (секунды прошли с 1970 года или что-то в этом роде)

Может кто-нибудь объяснить, пожалуйста, это ошибка или что-то?

MySQL версия 5.7.25

Редактировать 1 (скриншоты):

Это столбец TIMESTAMP со значением по умолчанию CURRENT_TIMESTAMP enter image description here

Как вы видите, оно отображается как DATETIME, и я не могу сравнить его с целочисленным значением unix_timestamp ... также мы можем изменить TimeZone на любое значение (я думал, что timestamp не хранит часовой пояс ...) enter image description here

Редактировать 2:

Если (на основе одного ответа) MySQL внутренне хранит его как целое число, то почему я не могу сравнить его с целыми числами? (следующий запрос не будет работать)

DELETE FROM `table` WHERE time < UNIX_TIMESTAMP(DATE_SUB(NOW(), INTERVAL :days DAY))

SQLSTATE [22007]: неправильный формат даты и времени: 1292 Неверное значение даты и времени: «1555980012» для столбца «время» в строке 1

Я также пробовал это в Sequel Pro и MySQLWorkbench с теми же результатами

Ответы [ 3 ]

7 голосов
/ 08 мая 2019

Если вам нужно увидеть 1557094115, тогда примените функцию UNIX_TIMESTAMP() к столбцу TIMESTAMP или DATETIME. Это обратное значение FROM_UNIXTIME().

mysql> SELECT UNIX_TIMESTAMP("2019-05-05 04:24:45"), FROM_UNIXTIME(1557055485);
+---------------------------------------+---------------------------+
| UNIX_TIMESTAMP("2019-05-05 04:24:45") | FROM_UNIXTIME(1557055485) |
+---------------------------------------+---------------------------+
|                            1557055485 | 2019-05-05 04:24:45       |
+---------------------------------------+---------------------------+

Подробнее

Внутренняя память для TIMESTAMP составляет 1557055485 в UTC; часовой пояс добавляется / удаляется при получении / сохранении.

Внутренним хранилищем для DATETIME является (логически, но не фактически) строка «2019-05-05 04:24:45» без указания часового пояса. (На самом деле он каким-то образом упакован в 5 байтов.)

Без какой-либо функции преобразования выборки TIMESTAMP и DATETIME выглядят одинаково:

CREATE TABLE `dtts` (
  `ts` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `dt` datetime DEFAULT NULL,
  `just_date` date NOT NULL,
  `di` int(11) DEFAULT NULL,
  `ts_int` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_520_ci
1 row in set (0.00 sec)

mysql> select * from dtts
    -> ;
+---------------------+---------------------+------------+------------+------------+
| ts                  | dt                  | just_date  | di         | ts_int     |
+---------------------+---------------------+------------+------------+------------+
| 2017-06-26 17:52:53 | 2011-06-08 20:45:55 | 2011-06-08 |   20110608 | 1465404577 |
| 2017-06-26 17:52:53 | 2013-03-10 02:35:47 | 2013-03-10 |   20130310 | 1465404577 |

Добавление NOW() к обоим, затем SELECTing:

mysql> INSERT INTO dtts (ts, dt) VALUES (NOW(), NOW());
Query OK, 1 row affected, 1 warning (0.00 sec)

| 2019-05-08 14:14:07 | 2019-05-08 14:14:07 | 0000-00-00 |       NULL |       NULL |
+---------------------+---------------------+------------+------------+------------+
3 голосов
/ 08 мая 2019
  1. DateTime не хранит информацию о часовом поясе (это только значение), в то время как MySQL преобразует значения TIMESTAMP из текущего часового пояса в UTC для хранения и преобразует из UTC в текущий часовой пояс для извлечения. То, что вы видите в PhpMyAdmin - это восстановленное значение, а не сохраненное значение.
  2. Начиная с MySQL 5.6.4, хранилище DateTime было улучшено с 8 байт до 5 байт (+ хранение в долях секунды) Ссылка
1 голос
/ 14 мая 2019

Начиная с MySQL 5.6.4, поле DATETIME требует 5 байтов + 3 байта дробных.Тип TIMESTAMP требует 4 байта + 3 байта дробных.Ни один из этих типов данных не хранит информацию о часовом поясе.Однако и MySQL, и phpMyAdmin отображают поля TIMESTAMP в соответствии с часовым поясом сервера базы данных.Вы можете получить информацию о часовом поясе сервера базы данных с помощью следующих операторов:

SELECT @@global.time_zone, @@session.time_zone;
SELECT EXTRACT(HOUR FROM (TIMEDIFF(NOW(), UTC_TIMESTAMP))) AS `timezone`

Если вы хотите, чтобы phpMyAdmin отображал другой часовой пояс с сервера базы данных, вы можете установить свойство SessionTimeZone внутри файла config.inc phpMyAdmin.php файл.

...