Вы бы порекомендовали использовать поле datetime или timestamp и почему (используя MySQL)?
Я работаю с PHP на стороне сервера.
Вы бы порекомендовали использовать поле datetime или timestamp и почему (используя MySQL)?
Я работаю с PHP на стороне сервера.
Ответы:
Временные метки в MySQL обычно используются для отслеживания изменений в записях и часто обновляются при каждом изменении записи. Если вы хотите сохранить определенное значение, вы должны использовать поле datetime.
Если вы имели в виду, что хотите выбрать между использованием метки времени UNIX или собственного поля даты и времени MySQL, перейдите к собственному формату. Вы можете выполнять вычисления в MySQL таким образом,
("SELECT DATE_ADD(my_datetime, INTERVAL 1 DAY)")
и вы просто можете изменить формат значения на метку времени UNIX, ("SELECT UNIX_TIMESTAMP(my_datetime)")
когда запрашиваете запись, если хотите работать с ней с помощью PHP.
DATETIME
представляет дату (как указано в календаре) и время (как можно наблюдать на настенных часах), а также TIMESTAMP
представляет четко определенный момент времени. Это может быть очень важно, если ваше приложение обрабатывает часовые пояса. Как давно было '2010-09-01 16:31:00'? Это зависит от того, в каком часовом поясе вы находитесь. Для меня это было всего несколько секунд назад, для вас это может представлять время в будущем. Если я произнесу 1283351460 секунд после «1970-01-01 00:00:00 UTC», вы точно знаете, в какой момент времени я говорю. (См. Отличный ответ Нира ниже). Недостаток: допустимый диапазон.
В MySQL 5 и выше значения TIMESTAMP преобразуются из текущего часового пояса в UTC для хранения и преобразуются обратно из UTC в текущий часовой пояс для извлечения. (Это происходит только для типа данных TIMESTAMP, а не для других типов, таких как DATETIME.)
По умолчанию текущим часовым поясом для каждого соединения является время сервера. Часовой пояс можно установить для каждого подключения, как описано в разделе Поддержка часового пояса MySQL Server .
Я всегда использую поля 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, в котором работает сервер.
Скорее всего, вы достигнете нижнего предела для TIMESTAMP в общем использовании - например, для хранения даты рождения.
new Date().getTime()
уже выдается 64-битное значение.
В приведенных ниже примерах показано, как 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 и Timestamp .
DATETIME
эффективное время изменилось с изменением часового пояса, TIMESTAMP
не изменилось, но человеческое представление изменилось.
set time_zone="america/new_york"
;
Основное отличие состоит в том, что DATETIME является постоянным, в то время как параметр TIMESTAMP зависит от time_zone
настройки.
Так что это имеет значение только тогда, когда у вас есть - или, возможно, в будущем - синхронизированные кластеры по часовым поясам.
Проще говоря: если у меня есть база данных в Австралии, и я сделаю дамп этой базы данных для синхронизации / заполнения базы данных в Америке, TIMESTAMP обновится, чтобы отразить реальное время события в новом часовом поясе, в то время как DATETIME будет по-прежнему отражать время события в часовом поясе au .
Отличным примером использования DATETIME, где должен был использоваться TIMESTAMP, является Facebook, где их серверы никогда не могут точно определить, что за время происходило в разных часовых поясах. Однажды у меня был разговор, в котором говорилось, что я отвечаю на сообщения до того, как сообщение было отправлено. (Это, конечно, также могло быть вызвано неправильным переводом часовых поясов в программном обеспечении для обмена сообщениями, если время было опубликовано, а не синхронизировано.)
Я принимаю это решение на семантической основе.
Я использую метку времени, когда мне нужно записать (более или менее) фиксированный момент времени. Например, когда запись была вставлена в базу данных или когда произошло какое-либо действие пользователя.
Я использую поле даты и времени, когда дата / время могут быть установлены и изменены произвольно. Например, когда пользователь может сохранить изменения позже.
Я рекомендую использовать ни поле DATETIME, ни поле TIMESTAMP. Если вы хотите представить конкретный день в целом (например, день рождения), тогда используйте тип DATE, но если вы более конкретны, вам, вероятно, будет интересно записать фактический момент, а не единицу измерения. время (день, неделя, месяц, год). Вместо использования DATETIME или TIMESTAMP, используйте BIGINT и просто сохраняйте количество миллисекунд с начала эпохи (System.currentTimeMillis (), если вы используете Java). Это имеет несколько преимуществ:
Эта проблема тесно связана с тем, как вы должны хранить денежную стоимость (т. Е. 1,99) в базе данных. Стоит ли использовать десятичное число, тип денег в базе данных или, что хуже всего, двойное число? Все 3 варианта ужасны по многим из перечисленных выше причин. Решение состоит в том, чтобы хранить стоимость денег в центах с помощью BIGINT, а затем конвертировать центы в доллары при отображении значения для пользователя. Задача базы данных - хранить данные, а НЕ интерпретировать эти данные. Все эти причудливые типы данных, которые вы видите в базах данных (особенно в Oracle), мало что добавят, и вы начнете путь к привязке к поставщикам.
TIMESTAMP составляет 4 байта против 8 байтов для DATETIME.
http://dev.mysql.com/doc/refman/5.0/en/storage-requirements.html
Но, как сказал scronide, у него есть нижний предел 1970 года. Это здорово для всего, что может случиться в будущем;)
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 до '2038-01-09 03:14:07' UTC. Он имеет различные свойства в зависимости от версии MySQL и режима SQL, в котором работает сервер.
Зависит от приложения, правда.
Попробуйте установить временную метку пользователем на сервере в Нью-Йорке для встречи в Санхае. Теперь, когда пользователь подключается в Сангхае, он получает доступ к той же отметке времени встречи с зеркального сервера в Токио. Он увидит встречу в токийском времени, смещенную от исходного нью-йоркского времени.
Поэтому для значений, которые представляют время пользователя, например, встречу или расписание, лучше использовать дату и время. Это позволяет пользователю контролировать точную дату и время, независимо от настроек сервера. Установленное время - это установленное время, не зависящее от часового пояса сервера, часового пояса пользователя или от изменений в способе расчета летнего времени (да, он действительно меняется).
С другой стороны, для значений, представляющих системное время, таких как платежные транзакции, изменения в таблице или ведение журнала, всегда используйте временные метки. На систему не повлияет перемещение сервера в другой часовой пояс или сравнение между серверами в разных часовых поясах.
Отметки времени также легче в базе данных и индексируются быстрее.
Любая недавняя интерфейсная структура (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
SET time_zone = '+0:00';
для UTC.
timestamp
Поле является частным случаем datetime
поля. Вы можете создавать timestamp
столбцы, чтобы иметь специальные свойства; это может быть установлено, чтобы обновить себя или создать и / или обновить.
В «больших» терминах базы данных, timestamp
есть пара специальных триггеров.
То, что правильно, полностью зависит от того, что вы хотите сделать.
TIMESTAMP всегда находится в UTC (то есть, прошедшие секунды с 1970-01-01 в UTC), и ваш сервер MySQL автоматически преобразует его в дату / время для часового пояса соединения. В долгосрочной перспективе TIMESTAMP - это путь, потому что вы знаете, что ваши временные данные всегда будут в UTC. Например, вы не испортите даты, если перенесетесь на другой сервер или измените настройки часового пояса на вашем сервере.
Примечание: часовой пояс соединения по умолчанию - часовой пояс сервера, но это может (должно) быть изменено за сеанс (см. SET time_zone = ...
).
Сравнение DATETIME, TIMESTAMP и DATE
Что это [.fraction]?
Источники:
Я всегда использовал бы метку времени Unix при работе с MySQL и PHP. Основной причиной этого является то, что метод даты по умолчанию в PHP использует метку времени в качестве параметра, поэтому анализ не требуется.
Чтобы получить текущую метку времени Unix в PHP, просто делайте time();
и в MySQL делайте SELECT UNIX_TIMESTAMP();
.
Стоит отметить, что в MySQL вы можете использовать что-то вроде следующего при создании столбцов таблицы:
on update CURRENT_TIMESTAMP
Это будет обновлять время при каждом изменении строки и иногда очень полезно для сохраненной информации последнего редактирования. Это работает только с меткой времени, но не с датой.
Исходя из моего опыта, если вам нужно поле даты, в которое вставка происходит только один раз, и вы не хотите обновлять или выполнять какие-либо другие действия в этом конкретном поле, выберите дату и время .
Например, рассмотрим user
таблицу с полем ДАТА РЕГИСТРАЦИИ . В этой user
таблице, если вы хотите узнать время последнего входа определенного пользователя, укажите поле типа отметки времени, чтобы оно обновлялось.
Если вы создаете таблицу из phpMyAdmin, настройка по умолчанию обновит поле метки времени, когда произойдет обновление строки. Если ваша временная метка не обновляется с обновлением строки, вы можете использовать следующий запрос для автоматического обновления поля временной метки .
ALTER TABLE your_table
MODIFY COLUMN ts_activity TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP;
Тип данных timestamp хранит дату и время, но в формате UTC, а не в текущем формате часового пояса, как datetime. И когда вы выбираете данные, отметка времени снова преобразует их в текущее время часового пояса.
Предположим, вы находитесь в США и получаете данные с сервера, который имеет часовой пояс США. Тогда вы получите дату и время в соответствии с часовым поясом США. Столбец типа данных временной метки всегда обновляется автоматически при обновлении его строки. Так что может быть полезно отследить, когда конкретная строка была обновлена в последний раз.
Для более подробной информации вы можете прочитать в блоге Timestamp Vs Datetime .
SET time_zone = '+0:00';
(здесь UTC), чтобы быть уверенным в том, что вы получаете / устанавливаете из TIMESTAMP
значений, и избегаете зависимости от значения по умолчанию для часового пояса сервера, которое может измениться.
Я всегда использую метку времени Unix, просто для поддержания здравого смысла при работе с большим количеством информации о времени и дате, особенно при выполнении корректировки часовых поясов, сложении / вычитании дат и тому подобном. При сравнении временных меток это исключает усложняющие факторы часового пояса и позволяет вам сэкономить ресурсы при обработке на стороне сервера (будь то код приложения или запросы к базе данных), поскольку вы используете более легкую арифметику, а не более сложное сложение / вычитание даты и времени функции.
Стоит рассмотреть еще одну вещь:
Если вы создаете приложение, вы никогда не знаете, как ваши данные могут быть использованы в дальнейшем. Если вам придется, скажем, сравнить кучу записей в вашем наборе данных, скажем, с кучей элементов от стороннего API, и, скажем, расположить их в хронологическом порядке, вы будете рады получить Unix метки времени для ваших строк. Даже если вы решите использовать метки времени MySQL, сохраните метку времени Unix в качестве страховки.
В моем случае я устанавливаю UTC как часовой пояс для всего: системы, сервера базы данных и т. Д. Каждый раз, когда могу. Если моему клиенту требуется другой часовой пояс, я настраиваю его в приложении.
Я почти всегда предпочитаю метки времени, а не поля даты и времени, потому что метки времени включают в себя часовой пояс неявно. Итак, с того момента, как к приложению будут обращаться пользователи из разных часовых поясов, и вы хотите, чтобы они видели даты и время в своем местном часовом поясе, этот тип поля делает это довольно легко, чем если бы данные были сохранены в полях datetime ,
Кроме того, в случае переноса базы данных в систему с другим часовым поясом я бы чувствовал себя более уверенно, используя временные метки. Не говоря уже о возможных проблемах при расчете различий между двумя моментами с изменением времени Шумера между ними и с точностью до 1 часа или меньше.
Итак, подведу итог, я ценю это преимущество отметки времени:
По всем этим причинам я выбираю поля UTC и отметки времени, где это возможно. И я избегаю головных болей;)
warranties.expires_at
не может быть меткой времени MySQL сегодня.
Остерегайтесь изменения метки времени при выполнении оператора UPDATE для таблицы. Если у вас есть таблица со столбцами «Name» (varchar), «Age» (int) и «Date_Added» (отметка времени), и вы выполняете следующую инструкцию DML
UPDATE table
SET age = 30
тогда каждое значение в вашем столбце «Date_Added» будет изменено на текущую временную метку.
ON UPDATE CURRENT_TIMESTAMP
Основные отличия:
TIMESTAMP используется для отслеживания изменений в записях и обновления каждый раз при изменении записи. DATETIME используется для хранения определенного и статического значения, на которое не влияют какие-либо изменения в записях.
На TIMESTAMP также влияют различные настройки, связанные с TIME ZONE. DATETIME является постоянным.
TIMESTAMP внутренне преобразовал текущий часовой пояс в UTC для хранения, а во время поиска преобразовал обратно в текущий часовой пояс. DATETIME не может этого сделать.
Диапазон поддерживаемых TIMESTAMP: '1970-01-01 00:00:01' UTC до '2038-01-19 03:14:07 ′ UTC DATETIME Поддерживаемый диапазон:' 1000-01-01 00:00:00 ′ до '9999 -12-31 23:59:59 ′
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
| 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. |
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
Еще одно различие между меткой времени и датой времени заключается в том, что в метке времени нельзя использовать значение по умолчанию NULL.
CREATE TABLE t2 ( ts1 TIMESTAMP NULL, ts2 TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP);
первый столбец может принимать значение NULL.
Я обнаружил непревзойденную полезность способности TIMESTAMP автоматически обновлять себя, основываясь на текущем времени, без использования ненужных триггеров. Это только я, хотя TIMESTAMP UTC, как было сказано.
Он может отслеживать различные часовые пояса, поэтому, если вам нужно, например, отобразить относительное время, то время в формате UTC - это то, что вам нужно.
Основное отличие заключается в
посмотрите на этот пост, чтобы увидеть проблемы с индексацией Datetime
Я перестал использовать datetime
в своих приложениях после того, как столкнулся со многими проблемами и ошибками, связанными с часовыми поясами. ИМХО использовать timestamp
лучше, чем datetime
в большинстве случаев .
Когда вы спрашиваете, который час? и ответ приходит как что-то вроде «2019-02-05 21:18:30», это не завершенный, не определенный ответ, потому что ему не хватает другой части, в каком часовом поясе? Вашингтон? Г. Москва ? Пекин?
Использование даты и времени без часового пояса означает, что ваше приложение имеет дело только с 1 часовым поясом, однако временные метки дают вам преимущества datetime
плюс гибкость показа одного и того же точного момента времени в разных часовых поясах.
Вот несколько случаев, которые заставят вас сожалеть об использовании datetime
и пожелать, чтобы вы хранили свои данные в метках времени.
Для удобства ваших клиентов вы хотите показать им время в зависимости от предпочитаемых часовых поясов, не заставляя их делать математику, и переводить время в значимый часовой пояс. все, что вам нужно, это изменить часовой пояс, и все ваши коды приложений будут одинаковыми. (На самом деле вы всегда должны определять часовой пояс в начале приложения или обработку запросов в случае PHP-приложений)
SET time_zone = '+2:00';
Вы изменили страну, в которой находитесь, и продолжили работу по сохранению данных, просматривая их в другом часовом поясе (без изменения фактических данных).
datetime
= приложение поддерживает 1 часовой пояс (как для вставки, так и для выбора)
timestamp
= приложение поддерживает любой часовой пояс (как для вставки, так и для выбора)
Этот ответ предназначен только для того, чтобы подчеркнуть гибкость и простоту временных отметок, когда речь идет о часовых поясах, и не охватывает никаких других отличий, таких как размер столбца, диапазон или дробь .
date
, а другие поля используются timestamp
в одной таблице. Я думаю, что это вызовет новую проблему, потому что данные, которые фильтруются, where
не соответствуют изменениям часового пояса.
date
столбце перед отправкой запроса.
A TIMESTAMP
требует 4 байта, тогда как a DATETIME
требует 8 байтов.
Мне нравится метка времени 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);