Должен ли я использовать тип данных datetime или timestamp в MySQL? - PullRequest
2503 голосов
/ 03 января 2009

Вы бы порекомендовали использовать поле datetime или timestamp и почему (используя MySQL)?

Я работаю с PHP на стороне сервера.

Ответы [ 37 ]

1704 голосов
/ 03 января 2009

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

Если вы имели в виду, что хотите выбрать между использованием метки времени UNIX или собственного поля даты и времени MySQL, перейдите к собственному формату. Вы можете делать вычисления в MySQL таким образом ("SELECT DATE_ADD(my_datetime, INTERVAL 1 DAY)") и просто изменить формат значения на отметку времени UNIX ("SELECT UNIX_TIMESTAMP(my_datetime)"), когда вы запрашиваете запись, если хотите работать с ней с помощью PHP.

870 голосов
/ 02 марта 2009

В MySQL 5 и выше значения TIMESTAMP преобразуются из текущего часового пояса в UTC для хранения и преобразуются обратно из UTC в текущий часовой пояс для получения. (Это происходит только для типа данных TIMESTAMP, а не для других типов, таких как DATETIME.)

По умолчанию текущим часовым поясом для каждого соединения является время сервера. Часовой пояс можно установить для каждого подключения, как описано в Поддержка часового пояса MySQL Server .

478 голосов
/ 04 января 2009

Я всегда использую поля DATETIME для чего угодно, кроме метаданных строки (дата создания или изменения).

Как упоминается в документации MySQL:

Тип DATETIME используется, когда вам нужны значения, которые содержат как дату, так и время. MySQL извлекает и отображает значения DATETIME в формате «ГГГГ-ММ-ДД ЧЧ: ММ: СС». Поддерживаемый диапазон: от «1000-01-01 00:00:00» до «9999-12-31 23:59:59».

...

Тип данных TIMESTAMP имеет диапазон от '1970-01-01 00:00:01' UTC до '2038-01-09 03:14:07' UTC. Он имеет различные свойства в зависимости от версии MySQL и режима SQL, в котором работает сервер.

Скорее всего, вы достигнете нижнего предела для TIMESTAMPs общего пользования - например, хранение даты рождения.

305 голосов
/ 21 августа 2011

Приведенные ниже примеры показывают, как тип даты TIMESTAMP изменил значения после изменения time-zone to 'america/new_york', где DATETIME не изменилось.

mysql> show variables like '%time_zone%';
+------------------+---------------------+
| Variable_name    | Value               |
+------------------+---------------------+
| system_time_zone | India Standard Time |
| time_zone        | Asia/Calcutta       |
+------------------+---------------------+

mysql> create table datedemo(
    -> mydatetime datetime,
    -> mytimestamp timestamp
    -> );

mysql> insert into datedemo values ((now()),(now()));

mysql> select * from datedemo;
+---------------------+---------------------+
| mydatetime          | mytimestamp         |
+---------------------+---------------------+
| 2011-08-21 14:11:09 | 2011-08-21 14:11:09 |
+---------------------+---------------------+

mysql> set time_zone="america/new_york";

mysql> select * from datedemo;
+---------------------+---------------------+
| mydatetime          | mytimestamp         |
+---------------------+---------------------+
| 2011-08-21 14:11:09 | 2011-08-21 04:41:09 |
+---------------------+---------------------+

Я преобразовал свой ответ в статью, чтобы больше людей могли найти это полезным, MySQL: типы данных с указанием даты и времени .

185 голосов
/ 14 января 2010

Основным отличием является то, что DATETIME является постоянным, в то время как параметр TIMESTAMP зависит от настройки time_zone.

Так что это имеет значение только тогда, когда у вас есть & mdash; или может иметь в будущем & mdash; синхронизированные кластеры по часовым поясам.

Проще говоря: Если у меня есть база данных в Австралии, и я сделаю дамп этой базы данных для синхронизации / заполнения базы данных в Америке, TIMESTAMP обновится, чтобы отразить реальное время события в новом часовой пояс, в то время как DATETIME будет по-прежнему отражать время события в часовом поясе au .

Отличным примером использования DATETIME, где должен был использоваться TIMESTAMP, является Facebook, где их серверы никогда не могут точно определить, что за время происходило в разных часовых поясах. Однажды у меня был разговор, в котором говорилось, что я отвечаю на сообщения до того, как сообщение было отправлено. (Это, конечно же, могло также быть вызвано неправильным переводом часовых поясов в программном обеспечении для обмена сообщениями, если время отправлялось, а не синхронизировалось.)

118 голосов
/ 03 января 2009

Я принимаю это решение на семантической основе.

Я использую метку времени, когда мне нужно записать (более или менее) фиксированный момент времени. Например, когда запись была вставлена ​​в базу данных или когда произошло какое-либо действие пользователя.

Я использую поле даты и времени, когда дата / время могут быть установлены и изменены произвольно. Например, когда пользователь может позже сохранить изменения.

94 голосов
/ 04 января 2009

TIMESTAMP - 4 байта против 8 байтов для DATETIME.

http://dev.mysql.com/doc/refman/5.0/en/storage-requirements.html

Но, как сказал скронид, у него есть нижний предел 1970 года. Хотя это здорово для всего, что может случиться в будущем;)

93 голосов
/ 12 июня 2014

Я рекомендую использовать , ни , ни поле DATETIME, ни поле TIMESTAMP. Если вы хотите представить конкретный день в целом (например, день рождения), используйте тип DATE, но если вы более конкретны, вам, вероятно, будет интересно записать фактический момент, а не единицу измерения. время (день, неделя, месяц, год). Вместо использования DATETIME или TIMESTAMP, используйте BIGINT и просто сохраняйте количество миллисекунд с начала эпохи (System.currentTimeMillis (), если вы используете Java). Это имеет несколько преимуществ:

  1. Вы избегаете блокировки поставщика. Практически каждая база данных поддерживает целые числа относительно похожим образом. Предположим, вы хотите перейти в другую базу данных. Хотите ли вы беспокоиться о различиях между значениями DATETIME в MySQL и о том, как их определяет Oracle? Даже среди разных версий MySQL TIMESTAMPS имеют разный уровень точности. Только недавно MySQL поддерживал миллисекунды в метках времени.
  2. Нет проблем с часовыми поясами. Здесь было несколько проницательных комментариев о том, что происходит с часовыми поясами с различными типами данных. Но общеизвестно ли это, и все ли ваши коллеги потратят время на его изучение? С другой стороны, довольно сложно запутаться, превращая BigINT в java.util.Date. Использование BIGINT приводит к тому, что многие проблемы с часовыми поясами падают на второй план.
  3. Не беспокойтесь о диапазонах или точности. Вам не нужно беспокоиться о том, что будет прервано будущими диапазонами дат (TIMESTAMP поступит только в 2038 году).
  4. Интеграция сторонних инструментов. Использование целого числа упрощает взаимодействие сторонних инструментов (например, EclipseLink) с базой данных. Не каждый сторонний инструмент будет иметь такое же понимание «datetime», как MySQL. Хотите попробовать и выяснить в Hibernate, следует ли вам использовать объект java.sql.TimeStamp или java.util.Date, если вы используете эти пользовательские типы данных? Использование ваших базовых типов данных делает использование сторонних инструментов тривиальным.

Эта проблема тесно связана с тем, как вы должны хранить денежную стоимость (например, $ 1,99) в базе данных. Стоит ли использовать десятичное число, тип денег в базе данных или, что хуже всего, двойное число? Все 3 варианта ужасны по многим из перечисленных выше причин. Решение состоит в том, чтобы хранить стоимость денег в центах с помощью BIGINT, а затем конвертировать центы в доллары при отображении значения для пользователя. Задача базы данных - хранить данные, а НЕ интерпретировать эти данные. Все эти причудливые типы данных, которые вы видите в базах данных (особенно в Oracle), мало что добавят, и вы начнете путь к привязке к поставщикам.

92 голосов
/ 21 декабря 2013
  1. TIMESTAMP - четыре байта против восьми байтов для DATETIME.

  2. Временные метки также легче в базе данных и быстрее индексируются.

  3. Тип DATETIME используется, когда вам нужны значения, которые содержат как дату, так и время. MySQL извлекает и отображает значения DATETIME в формате «ГГГГ-ММ-ДД ЧЧ: ММ: СС». Поддерживаемый диапазон: от 1000-01-01 00:00:00 до 9999-12-31 23:59:59.

Тип данных TIMESTAMP имеет диапазон от '1970-01-01 00:00:01' UTC до '2038-01-09 03:14:07' UTC. Он имеет различные свойства в зависимости от версии MySQL и режима SQL, в котором работает сервер.

  1. DATETIME постоянно, в то время как TIMESTAMP зависит от настройки time_zone.
44 голосов
/ 27 октября 2010

Зависит от приложения, действительно.

Рассмотрите возможность установки метки времени пользователем на сервер в Нью-Йорке для встречи в Сангхае. Теперь, когда пользователь подключается в Сангхае, он получает доступ к той же отметке времени встречи с зеркального сервера в Токио. Он увидит встречу в токийском времени, смещенную от исходного нью-йоркского времени.

Так что для значений, которые представляют пользовательское время, например, встречу или расписание, лучше использовать дату и время. Это позволяет пользователю контролировать точную дату и время, независимо от настроек сервера. Установленное время - это установленное время, не зависящее от часового пояса сервера, часового пояса пользователя или изменений в способах расчета летнего времени (да, оно действительно меняется).

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

Временные метки также легче в базе данных и быстрее индексируются.

...