Вы порекомендовали бы использовать 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.
В MySQL 5 и выше значения TIMESTAMP преобразуются из текущего часового пояса в UTC для хранения и преобразуются обратно из UTC в текущий часовой пояс для извлечения. (Это происходит только для типа данных TIMESTAMP, а не для других типов, таких как DATETIME.)
По умолчанию текущий часовой пояс для каждого соединения - это время сервера. Часовой пояс может быть установлен для каждого соединения, как описано в Поддержка часовых поясов сервера MySQL.
Я всегда использую поля 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 в общем использовании - например. хранение даты рождения.
Ниже приведены примеры того, как тип даты 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.
Основное отличие состоит в том, что DATETIME является постоянным, а TIMESTAMP зависит от параметра time_zone
.
Итак, это имеет значение только тогда, когда у вас есть — или может в будущем иметь; синхронизированных кластеров во временных зонах.
В более простых словах: Если у меня есть база данных в Австралии и дамп этой базы данных для синхронизации/заполнения базы данных в Америке, то TIMESTAMP будет обновляться, чтобы отображать реальное время события в новом часовой пояс, в то время как DATETIME будет по-прежнему отражать время события в часовой пояс.
Отличным примером DATETIME, используемого там, где TIMESTAMP должен был использоваться, является Facebook, где их серверы никогда не могут быть уверены в том, что произошло во время часовых поясов. Однажды у меня был разговор, в котором время говорило, что я отвечаю на сообщения, прежде чем сообщение действительно отправлено. (Это, конечно, также могло быть вызвано неправильным переводом часового пояса в программном обеспечении для обмена сообщениями, если время было отправлено, а не синхронизировано.)
Я принимаю это решение на семантической основе.
Я использую временную метку, когда мне нужно записать (более или менее) фиксированную точку во времени. Например, когда запись была вставлена в базу данных или когда произошло какое-то действие пользователя.
Я использую поле datetime, когда дату/время можно установить и изменить произвольно. Например, когда пользователь может сохранить последующие изменения в назначении.
Я рекомендую использовать ни поле DATETIME, ни поле TIMESTAMP. Если вы хотите представить конкретный день в целом (например, день рождения), используйте тип DATE, но если вы более конкретны, вам, вероятно, будет интересно записать фактический момент, а не единицу измерения. время (день, неделя, месяц, год). Вместо использования DATETIME или TIMESTAMP, используйте BIGINT и просто сохраняйте количество миллисекунд с начала эпохи (System.currentTimeMillis(), если вы используете Java). Это имеет несколько преимуществ:
Эта проблема тесно связана с тем, как вы должны хранить денежную стоимость (например, $ 1,99) в базе данных. Стоит ли использовать десятичную или базу данных типа Money или, что хуже всего, Double? Все 3 варианта ужасны по многим из перечисленных выше причин. Решение состоит в том, чтобы хранить стоимость денег в центах с помощью BIGINT, а затем конвертировать центы в доллары при отображении значения для пользователя. Задача базы данных - хранить данные, а НЕ интерпретировать эти данные. Все эти причудливые типы данных, которые вы видите в базах данных (особенно в Oracle), мало что добавляют, и вы начинаете идти по пути к привязке к поставщикам.
TIMESTAMP - 4 байта с 8 байтами для DATETIME.
http://dev.mysql.com/doc/refman/5.0/en/storage-requirements.html
Но, подобно тому, как Скронид сказал, что он имеет нижнюю границу 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 to 2038-01-09 03:14:07' UTC. Он имеет разные свойства, в зависимости от версии MySQL и режима SQL, на котором работает сервер.
Зависит от приложения, действительно.
Рассмотрите возможность установки метки времени пользователем на сервер в Нью-Йорке для назначения в Сангхай. Теперь, когда пользователь подключается в Сангхай, он обращается к той же самой отметке времени назначения с зеркального сервера в Токио. Он увидит назначение в Токийское время, компенсированное первоначальным нью-йоркским временем.
Таким образом, для значений, представляющих пользовательское время, например, назначение или расписание, 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
A timestamp
является частным случаем поля datetime
. Вы можете создать столбцы timestamp
, чтобы иметь специальные свойства; он может быть настроен на обновление самого себя при создании и/или обновлении.
В терминах "больших" баз данных timestamp
имеет несколько триггеров специального случая на нем.
То, что правильно, полностью зависит от того, что вы хотите сделать.
TIMESTAMP всегда находится в UTC (то есть, прошедшие секунды с 1970-01-01 в UTC), и ваш сервер MySQL автоматически преобразует его в дату/время для часового пояса соединения. В долгосрочной перспективе TIMESTAMP - это путь, потому что вы знаете, что ваши временные данные всегда будут в UTC. Например, вы не испортите даты, если перенесетесь на другой сервер или измените настройки часового пояса на вашем сервере.
Примечание: часовой пояс соединения по умолчанию - часовой пояс сервера, но его можно (нужно) изменить за сеанс (см. SET time_zone =...
).
Сравнение между DATETIME, TIMESTAMP и DATE
Что это [.fraction]?
Источники:
Стоит отметить, что в MySQL вы можете использовать что-то по строкам ниже при создании столбцов таблицы:
on update CURRENT_TIMESTAMP
Это будет обновлять время в каждом экземпляре, который вы модифицируете строку, и иногда очень полезно для сохранения последней информации редактирования. Это работает только с меткой времени, но не с datetime.
Я всегда использовал временную метку Unix при работе с MySQL и PHP. Основной причиной этого является метод date по умолчанию в PHP использует временную метку в качестве параметра, поэтому не требуется синтаксический анализ.
Чтобы получить текущую временную метку Unix в PHP, просто time();
и в MySQL do SELECT UNIX_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 снова преобразует их в текущее время часового пояса.
Предположим, вы находитесь в США и получаете данные с сервера, который имеет часовой пояс США. Тогда вы получите дату и время в соответствии с часовым поясом США. Столбец типа данных временной метки всегда обновляется автоматически при обновлении его строки. Так что может быть полезно отследить, когда конкретная строка была обновлена в последний раз.
Для более подробной информации вы можете прочитать в блоге Timestamp Vs Datetime.
Я всегда использую временную метку Unix, просто для поддержания здравомыслия при работе с большим количеством информации о времени и времени, особенно при выполнении корректировок для часовых поясов, добавлении/вычитании дат и т.п. При сравнении временных меток это исключает усложняющие факторы часового пояса и позволяет вам сэкономить ресурсы в обработке на стороне сервера (будь то код приложения или запросы к базе данных) в том, что вы используете арифметику легкого веса, а не более тяжелую дату-время добавить/вычесть функции.
Еще одна вещь, которую стоит рассмотреть:
Если вы создаете приложение, вы никогда не знаете, как ваши данные могут быть использованы по линии. Если вам придется, скажем, сравнить кучу записей в вашем наборе данных, скажем, с кучей элементов из стороннего API, и, скажем, поставить их в хронологическом порядке, вы будете счастливы иметь Временные метки Unix для ваших строк. Даже если вы решите использовать временные метки MySQL, сохраните временную метку Unix как страховку.
Остерегайтесь изменения временной метки, когда вы выполняете инструкцию UPDATE в таблице. Если у вас есть таблица со столбцами "Имя" (varchar), "Age" (int) и "Date_Added" (временная метка), и вы запускаете следующий оператор DML
UPDATE table
SET age = 30
то каждое значение в столбце "Date_Added" будет изменено на текущую временную метку.
Ссылка, взятая из этой статьи:
Основные отличия:
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'
В моем случае я устанавливаю UTC как часовой пояс для всего: системы, сервера базы данных и т.д. каждый раз, когда я могу. Если моему клиенту требуется другой часовой пояс, я настраиваю его в приложении.
Я почти всегда предпочитаю временные метки, а не поля datetime, потому что временные метки неявно включают часовой пояс. Таким образом, с момента, когда приложение будет доступно для пользователей из разных часовых поясов, и вы хотите, чтобы они видели даты и время в своем локальном часовом поясе, этот тип поля делает его довольно простым, чем если бы данные были сохранены в полях datetime.
В качестве плюса, в случае миграции базы данных в систему с другим часовым поясом, я бы чувствовал себя более уверенно, используя временные метки. Нельзя говорить о возможных проблемах при расчете различий между двумя моментами с изменением времени ожидания между ними и необходимостью точности 1 час или менее.
Итак, резюмируя, я ценю эти преимущества метки времени:
По всем этим причинам я выбираю поля UTC и timestamp, где это возможно. И я избегаю головных болей;)
Я нашел непревзойденную полезность в способности TIMESTAMP автоматически обновлять себя на основе текущего времени без использования ненужных триггеров. Это только я, хотя, хотя TIMESTAMP - это UTC, как было сказано.
Он может отслеживать различные часовые пояса, поэтому, если вам нужно отобразить относительное время, например, время UTC - это то, что вы хотели бы.
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
| 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. |
+---------------------------------------------------------------------------------------+--------------------------------------------------------------------------+
Еще одно отличие между Timestamp и Datetime в Timestamp, вы не можете использовать значение по умолчанию NULL.
Основное отличие:
посмотрите на это сообщение чтобы увидеть проблемы с индексированием Datetime
Я перестал использовать datetime
в своих приложениях после того, как столкнулся со многими проблемами и ошибками, связанными с часовыми поясами. ИМХО в большинстве случаев использовать timestamp
лучше, чем datetime
время.
Когда вы спрашиваете, который час? и ответ приходит как что-то вроде "2019-02-05 21:18:30", это не завершенный, не определенный ответ, потому что ему не хватает другой части, в каком часовом поясе? Вашингтон? Москва? Пекин?
Использование datetime без часового пояса означает, что ваше приложение имеет дело только с 1 часовым поясом, однако временные метки дают вам преимущества datetime
а также гибкость показа одного и того же точного момента времени в разных часовых поясах.
Вот несколько случаев, которые заставят вас сожалеть об использовании datetime
и datetime
и пожелать, чтобы вы сохранили свои данные в метках времени.
Для удобства ваших клиентов вы хотите показать им время в зависимости от предпочитаемых часовых поясов, не заставляя их делать математику, и переводить время в значимый часовой пояс. все, что вам нужно, это изменить часовой пояс, и весь код вашего приложения будет одинаковым (на самом деле вы всегда должны определять часовой пояс в начале приложения или обработку запросов в случае приложений PHP)
SET time_zone = '+2:00';
Вы изменили страну, в которой находитесь, и продолжили работу по сохранению данных, просматривая их в другом часовом поясе (без изменения фактических данных).
datetime
= приложение поддерживает 1 часовой пояс (как для вставки, так и для выбора)
timestamp
= приложение поддерживает любой часовой пояс (как для вставки, так и для выбора)
Этот ответ предназначен только для того, чтобы подчеркнуть гибкость и простоту временных отметок, когда речь идет о часовых поясах, и не охватывает никаких других отличий, таких как размер столбца, диапазон или дробь.
Я предпочитаю использовать временную метку, чтобы сохранить все в одном распространенном необработанном формате и форматировать данные в PHP-коде или в вашем SQL-запросе. Бывают случаи, когда вам удобно в вашем коде хранить все в считанные секунды.
A TIMESTAMP
требуется 4 байта, тогда как для 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);