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

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

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

+2568
источник поделиться
38 ответов
  • 1
  • 2

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

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

+1752
источник

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

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

+884
источник
другие ответы

Связанные вопросы


Похожие вопросы

Я всегда использую поля 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 в общем использовании - например. хранение даты рождения.

+489
источник

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

+312
источник

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

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

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

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

+187
источник

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

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

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

+121
источник

Я рекомендую использовать ни поле 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), мало что добавляют, и вы начинаете идти по пути к привязке к поставщикам.

+98
источник

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

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

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

+95
источник
  • 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.
+94
источник

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

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

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

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

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

+46
источник

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

+41
источник
Поле

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

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

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

+36
источник

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

Примечание: часовой пояс соединения по умолчанию - часовой пояс сервера, но его можно (нужно) изменить за сеанс (см. SET time_zone =...).

+34
источник

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

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

Что это [.fraction]?

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

Источники:

+27
источник

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

on update CURRENT_TIMESTAMP

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

+24
источник

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

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

+22
источник

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

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

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

ALTER TABLE your_table
      MODIFY COLUMN ts_activity TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
+17
источник

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

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

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

+15
источник

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

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

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

+14
источник

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

UPDATE table
SET age = 30

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

+13
источник

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

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

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'

+13
источник

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

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

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

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

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

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

+13
источник

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

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

+10
источник
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
|                                       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.                                   |
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
+10
источник

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

+9
источник

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

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

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

+9
источник

Я перестал использовать datetime в своих приложениях после того, как столкнулся со многими проблемами и ошибками, связанными с часовыми поясами. ИМХО в большинстве случаев использовать timestamp лучше, чем datetime время.

Когда вы спрашиваете, который час? и ответ приходит как что-то вроде "2019-02-05 21:18:30", это не завершенный, не определенный ответ, потому что ему не хватает другой части, в каком часовом поясе? Вашингтон? Москва? Пекин?

Использование datetime без часового пояса означает, что ваше приложение имеет дело только с 1 часовым поясом, однако временные метки дают вам преимущества datetime а также гибкость показа одного и того же точного момента времени в разных часовых поясах.

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

  1. Для удобства ваших клиентов вы хотите показать им время в зависимости от предпочитаемых часовых поясов, не заставляя их делать математику, и переводить время в значимый часовой пояс. все, что вам нужно, это изменить часовой пояс, и весь код вашего приложения будет одинаковым (на самом деле вы всегда должны определять часовой пояс в начале приложения или обработку запросов в случае приложений PHP)

    SET time_zone = '+2:00';
    
  2. Вы изменили страну, в которой находитесь, и продолжили работу по сохранению данных, просматривая их в другом часовом поясе (без изменения фактических данных).

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

Короче

datetime= приложение поддерживает 1 часовой пояс (как для вставки, так и для выбора)

timestamp= приложение поддерживает любой часовой пояс (как для вставки, так и для выбора)


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

+8
источник

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

+7
источник

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

+7
источник

Мне нравится отметка времени 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);
+6
источник
  • 1
  • 2

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