MySQL дата или время PHP?

Я обычно храню даты как целые числа, используя функцию time() PHP time() в базе данных MySQL, а не используя формат даты MySQL просто потому, что легче манипулировать, когда я вытаскиваю его обратно, но есть ли какие-то недостатки?

Ассортимент:

Всегда есть очевидный недостаток: диапазон, который вы можете сохранить, ограничен с 1970 по 2038 год. Если вам нужно хранить даты за пределами этого диапазона, вам обычно нужно использовать другой формат. Самый распространенный случай, который я нашел там, где это применимо, – это дата рождения.

Читаемость:

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

Индексы:

Хорошей технической причиной для использования типов дат является то, что он позволяет индексировать запрос в некоторых случаях, когда временные метки unix этого не делают. Рассмотрим следующий запрос:

 SELECT * FROM tbl WHERE year(mydate_field) = 2009; 

Если mydate_field имеет собственный тип даты и в поле есть индекс, этот запрос будет фактически использовать индекс, несмотря на вызов функции. Это почти единственный раз, когда mysql может оптимизировать вызовы функций в таких полях. Соответствующий запрос в поле метки времени не сможет использовать индексы:

 SELECT * FROM tbl WHERE year(from_unixtime(mytimestamp_field)) = 2009; 

Если вы подумаете об этом немного, есть способ обойти это. Этот запрос делает то же самое и сможет использовать оптимизацию индекса:

 SELECT * FROM tbl WHERE mytimestamp_field > unix_timestamp("2009-01-01") AND mytimestamp_field < unix_timestamp("2010-01-01"); 

Расчеты:

Как правило, я храню даты как unix-время, несмотря на недостатки. На самом деле это не основано на его достоинствах, а скорее потому, что я привык к этому. Я обнаружил, что это упрощает некоторые вычисления, но усложняет другие. Например, очень сложно добавить месяц к временной отметке unix, так как количество секунд в месяц меняется. Это очень просто, используя функцию mysql DATE_ADD (). Однако я считаю, что в большинстве случаев это фактически упрощает вычисления. Например, довольно часто вы выбираете сообщения, например, за последние два дня. Если поле содержит временную метку unix, это можно сделать легко, просто выполнив:

 SELECT * FROM tbl WHERE mytimestamp_field > time() - 2*24*3600; 

Это, наверное, вопрос вкуса, но я лично считаю это быстрее и проще, чем повторять синтаксис функции, такой как DATE_SUB ().

Часовые пояса:

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

Один из недостатков заключается в том, что вы не сможете манипулировать и запрашивать эти даты с помощью функций SQL.

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

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

Временная метка UNIX имеет очевидные ограничения в отношении количества дат, которые вы можете хранить.

Я также всегда использую поля DATETIME . Вы можете сделать много математики DATE, используя SQL, чтобы вы могли вытащить полезную информацию, такую ​​как DATEDIFF между теперь и сохраненной датой, без использования какого-либо PHP вообще.

Вы можете определить предложение автоматического обновления для временных меток MySQL в определении вашей таблицы.
http://dev.mysql.com/doc/refman/5.0/en/timestamp.html

Есть много недостатков:

  • Отсутствие точности; Время Unix верное для второго и только для дат между 1901-12-13 и 2038-01-19 при использовании типичного 32-битного целого числа
  • Вы не можете использовать встроенные функции базы данных для запроса или обработки данных
  • Вы не можете сохранить часовой пояс

Если вам нужно time_t , достаточно легко преобразовать его в код.

Только пару, о которой я могу думать:
* Если другому не-php-приложению необходимо использовать базу данных, это будет в трудном формате для чтения.
* Если вы хотите выполнять какую-либо работу на основе SQL на эти даты (например, добавление месяца или получение всех значений для определенного года и т. Д.), Это будет сложнее.

Небольшая потеря деталей. Переменная MySQL Datetime может быть очень точной.

Кроме того, если вам нужно сравнивать даты в вашей базе данных, формат даты имеет некоторые встроенные функции, которые вы не сможете использовать.

Я думаю, что по причинам масштабируемости лучше использовать временные метки Unix.

Преимущества :

  • Всегда хранится в часовом поясе UTC (если у вас есть серверы в нескольких часовых поясах, преобразование не требуется).
  • Приложения конвертируют их в предпочтительный часовой пояс (это происходит только один раз, на последнем уровне).
  • Не строки (они огромны по сравнению с целыми числами).
  • Меньше вычислений базы данных (Stuff, как created <19345345345-24 * 60 * 60, вычисляется один раз).

EDIT: Временные метки MySQL не хранятся внутри строки в качестве строк, но при вытаскивании из базы данных они преобразуются в строки. Тип DATETIME не модифицируется MySQL , а это означает, что если вы поместите дату в базу данных, вы получите то же самое.

Если у вас есть посетители на веб-сайте из другого часового пояса, вам придется конвертировать даты, такие как string-> string вместо integer-> string). В некоторых странах даты – это не просто цифры (например, во Франции это Mardi 15 мая 2012 года. Я предпочитаю делать это в PHP или JS. Я думаю, что целая цепочка конвертирования simpe быстрее, чем Integer-> String-> String. при переходе на серверы в другой стране нет головной боли.

Поддельные недостатки :

  • Я считаю, что ограниченный диапазон временных меток Unix на самом деле не ограничен. Метка времени – это целое число в базе данных, поэтому вы можете настроить размер. По умолчанию целое число unsignedint(10) означает, что вы можете хранить номера до 4294967295 , но ограничения не фиксируются, поэтому мы можем легко изменить int(10) int на int(16) bigint

Это не так уж плохо, но вы потеряете некоторые встроенные функции, такие как:

выберите * из таблицы1, где dateColumn = getDate () – 30

Используйте datetime, если сможете!