Должен ли я использовать тип данных datetime или timestamp в MySQL?

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

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

2422
задан 03 янв. '09 в 19:14
источник поделиться
35 ответов
  • 1
  • 2

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

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

1642
ответ дан 03 янв. '09 в 19:26
источник

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

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

844
ответ дан 02 марта '09 в 14:49
источник

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

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

Тип DATETIME используется, когда вам нужны значения, содержащие информацию о дате и времени. MySQL извлекает и отображает значения DATETIME в формате "YYYY-MM-DD HH: MM: SS". Поддерживаемый диапазон: "1000-01-01 00:00:00" до "9999-12-31 23:59:59".

...

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

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

457
ответ дан 04 янв. '09 в 7:26
источник

Ниже приведены примеры того, как тип даты 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: Datetime Versus Timestamp Data Types.

295
ответ дан 21 авг. '11 в 11:45
источник

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

Итак, это имеет значение только тогда, когда у вас есть — или может в будущем иметь; синхронизированных кластеров во временных зонах.

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

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

179
ответ дан 14 янв. '10 в 17:26
источник

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

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

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

114
ответ дан 03 янв. '09 в 20:11
источник

TIMESTAMP - 4 байта с 8 байтами для DATETIME.

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

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

90
ответ дан 04 янв. '09 в 12:00
источник

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

  1. Вы избегаете блокировки поставщика. Практически каждая база данных поддерживает целые числа относительно похожим образом. Предположим, вы хотите перейти в другую базу данных. Хотите ли вы беспокоиться о различиях между значениями MySQL DATETIME и о том, как их определяет 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) в базе данных. Стоит ли использовать десятичную или базу данных типа Money или, что хуже всего, Double? Все 3 варианта ужасны по многим из перечисленных выше причин. Решение состоит в том, чтобы хранить стоимость денег в центах с помощью BIGINT, а затем конвертировать центы в доллары при отображении значения для пользователя. Задача базы данных - хранить данные, а НЕ интерпретировать эти данные. Все эти причудливые типы данных, которые вы видите в базах данных (особенно в Oracle), мало что добавляют, и вы начинаете идти по пути к привязке к поставщикам.

87
ответ дан 12 июня '14 в 2:02
источник
  • TIMESTAMP - это четыре байта против восьми байтов для DATETIME.

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

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

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

  1. DATETIME постоянна, а TIMESTAMP - установкой time_zone.
86
ответ дан 21 дек. '13 в 14:12
источник

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

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

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

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

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

40
ответ дан 27 окт. '10 в 0:07
источник

2016 +: я советую вам установить часовой пояс Mysql на UTC и использовать DATETIME:

Любая недавняя интерфейсная среда (Angular 1/2, реагировать, Vue,...) может легко и автоматически преобразовать дату и время UTC в местное время.

Дополнительно:

(Если вы, вероятно, не измените часовой пояс своих серверов)


Пример с AngularJs

// back-end: format for angular within the sql query
SELECT DATE_FORMAT(my_datetime, "%Y-%m-%dT%TZ")...

// font-end Output the localised time
{{item.my_datetime | date :'medium' }}

Весь локализованный формат времени доступен здесь: https://docs.angularjs.org/api/ng/filter/date

36
ответ дан 18 февр. '16 в 1:36
источник
Поле

A timestamp является частным случаем поля datetime. Вы можете создать столбцы timestamp, чтобы иметь специальные свойства; он может быть настроен на обновление самого себя при создании и/или обновлении.

В терминах "больших" баз данных timestamp имеет несколько триггеров специального случая на нем.

То, что правильно, полностью зависит от того, что вы хотите сделать.

32
ответ дан 03 янв. '09 в 19:21
источник

TIMESTAMP всегда находится в UTC (то есть, прошедшие секунды с 1970-01-01, в UTC), и ваш MySQL-сервер автоматически конвертирует его в дату/время для часовой пояс сервера. В долгосрочной перспективе TIMESTAMP - это путь, потому что вы знаете, что ваши временные данные всегда будут в UTC. Например, вы не будете вставлять свои даты, если вы перейдете на другой сервер или измените настройки часового пояса на своем сервере.

27
ответ дан 26 авг. '10 в 2:21
источник

Сравнение между DATETIME, TIMESTAMP и DATE

введите описание изображения здесь

Что это [.fraction]?

  • Значение DATETIME или TIMESTAMP может включать трейлинг-дробное секунд в минуту до точностью до микросекунд (6 цифр). В в частности, любая дробная часть в значении, вставленном в DATETIME или столбцы TIMESTAMP сохраняются, а не отбрасываются. Это, конечно, необязательно.

Источники:

23
ответ дан 11 авг. '17 в 12:53
источник

Стоит отметить, что в MySQL вы можете использовать что-то по строкам ниже при создании столбцов таблицы:

on update CURRENT_TIMESTAMP

Это будет обновлять время в каждом экземпляре, который вы модифицируете строку, и иногда очень полезно для сохранения последней информации редактирования. Это работает только с меткой времени, но не с datetime.

21
ответ дан 07 янв. '12 в 2:04
источник

Я всегда использовал временную метку Unix при работе с MySQL и PHP. Основной причиной этого является метод date по умолчанию в PHP использует временную метку в качестве параметра, поэтому не требуется синтаксический анализ.

Чтобы получить текущую временную метку Unix в PHP, просто time();
и в MySQL do SELECT UNIX_TIMESTAMP();.

20
ответ дан 03 янв. '09 в 19:18
источник

Исходя из моего опыта, если вам нужно поле даты, в которое вставка происходит только один раз, и вы не хотите обновлять или выполнять какие-либо другие действия в этом конкретном поле, переходите к дате.

Например, рассмотрим user таблицу с полем ДАТА РЕГИСТРАЦИИ. В этой user таблице, если вы хотите узнать время последнего входа определенного пользователя, укажите поле типа отметки времени, чтобы оно обновлялось.

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

ALTER TABLE your_table
      MODIFY COLUMN ts_activity TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
14
ответ дан 06 февр. '12 в 6:34
источник

Тип данных timestamp хранит дату и время, но в формате UTC, а не в текущем формате часового пояса, как datetime. И когда вы выбираете данные, timestamp снова преобразует их в текущее время часового пояса.

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

Для более подробной информации вы можете прочитать в блоге Timestamp Vs Datetime.

13
ответ дан 20 дек. '12 в 11:48
источник

Остерегайтесь изменения временной метки, когда вы выполняете инструкцию UPDATE в таблице. Если у вас есть таблица со столбцами "Имя" (varchar), "Age" (int) и "Date_Added" (временная метка), и вы запускаете следующий оператор DML

UPDATE table
SET age = 30

то каждое значение в столбце "Date_Added" будет изменено на текущую временную метку.

12
ответ дан 04 окт. '13 в 9:00
источник

Ссылка, взятая из этой статьи:

Основные отличия:

TIMESTAMP используется для отслеживания изменений в записях и обновления при каждом изменении записи. DATETIME используется для хранения определенного и статического значения, на которое не влияют изменения в записях.

TIMESTAMP также зависит от настройки, связанной с TIME ZONE. DATETIME постоянна.

TIMESTAMP внутренне преобразует текущий часовой пояс в UTC для хранения, а во время поиска преобразуется обратно в текущий часовой пояс. DATETIME не может этого сделать.

Поддерживаемый диапазон TIMESTAMP: '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC Поддерживаемый диапазон DATETIME: '1000-01-01 00:00:00' до '9999-12-31 23:59:59'

12
ответ дан 07 февр. '16 в 15:49
источник

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

Еще одна вещь, которую стоит рассмотреть:

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

12
ответ дан 05 янв. '12 в 5:50
источник

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

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

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

Итак, резюмируя, я ценю эти преимущества метки времени:

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

По всем этим причинам я выбираю поля UTC и timestamp, где это возможно. И я избегаю головных болей;)

11
ответ дан 24 февр. '17 в 21:19
источник

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

Он может отслеживать различные часовые пояса, поэтому, если вам нужно отобразить относительное время, например, время UTC - это то, что вы хотели бы.

10
ответ дан 01 нояб. '11 в 22:42
источник

Еще одно отличие между Timestamp и Datetime в Timestamp, вы не можете использовать значение по умолчанию NULL.

10
ответ дан 19 янв. '14 в 14:06
источник

Основное отличие:

  • a INDEX на отметке времени - работает
  • a INDEX в Datetime - Не работает

посмотрите на это сообщение чтобы увидеть проблемы с индексированием Datetime

10
ответ дан 07 марта '14 в 15:09
источник

Я предпочитаю использовать временную метку, чтобы сохранить все в одном распространенном необработанном формате и форматировать данные в PHP-коде или в вашем SQL-запросе. Бывают случаи, когда вам удобно в вашем коде хранить все в считанные секунды.

8
ответ дан 04 янв. '09 в 10:49
источник
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
|                                       TIMESTAMP                                       |                                 DATETIME                                 |
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
| TIMESTAMP requires 4 bytes.                                                           | DATETIME requires 8 bytes.                                               |
| Timestamp is the number of seconds that have elapsed since January 1, 1970 00:00 UTC. | DATETIME is a text displays 'YYYY-MM-DD HH:MM:SS' format.                |
| TIMESTAMP supported range: ‘1970-01-01 00:00:01′ UTC to ‘2038-01-19 03:14:07′ UTC.    | DATETIME supported range: ‘1000-01-01 00:00:00′ to ‘9999-12-31 23:59:59′ |
| TIMESTAMP during retrieval converted back to the current time zone.                   | DATETIME can not do this.                                                |
| TIMESTAMP is used mostly for metadata i.e. row created/modified and audit purpose.    | DATETIME is used mostly for user-data.                                   |
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
7
ответ дан 12 апр. '18 в 6:11
источник

Мне нравится отметка времени Unix, потому что вы можете конвертировать в числа и просто беспокоиться о номере. Кроме того, вы добавляете/вычитаете и получаете длительность и т.д. Затем преобразуйте результат в Date в любом формате. Этот код узнает, сколько времени в минутах прошло между меткой времени от документа и текущим временем.

$date  = $item['pubdate']; (etc ...)
$unix_now = time();
$result = strtotime($date, $unix_now);
$unix_diff_min = (($unix_now  - $result) / 60);
$min = round($unix_diff_min);
7
ответ дан 28 апр. '11 в 20:34
источник

A TIMESTAMP требуется 4 байта, тогда как для DATETIME требуется 8 байт.

6
ответ дан 23 июня '16 в 17:12
источник

Я просто использую unsigned BIGINT при сохранении UTC...

который по-прежнему можно настроить на локальное время в PHP.

DATETIME выбирается с помощью FROM_UNIXTIME( integer_timestamp_column ).

Очевидно, что в этом столбце должен быть установлен индекс, иначе не было бы прогресса.

4
ответ дан 23 мая '16 в 14:20
источник
  • 1
  • 2

Другие вопросы по меткам или Задайте вопрос