Когда использовать VARCHAR и DATE / DATETIME - PullRequest
32 голосов
/ 21 января 2011

Мы обсуждали программирование на Freenode, и этот вопрос возник, когда я пытался использовать VARCHAR (255) для хранения переменной даты в этом формате: D / MM / YYYY.Так что вопрос в том, почему так плохо использовать VARCHAR для хранения даты.Вот преимущества:

  1. Его код быстрее.Раньше я использовал DATE, но форматирование даты было настоящей болью.
  2. Более требовательна к использованию строки, чем Date?Кому интересно, мы живем в эпоху Ghz.
  3. Это не этически правильно (смеется?) Это то, что другой пользователь сказал мне ...

Так что бы вы предпочли использовать для хранения даты?SQL VARCHAR или SQL DATE?

Ответы [ 5 ]

40 голосов
/ 21 января 2011

Почему бы не вставить винты с помощью молотка?

Потому что это не подходящий инструмент для работы.

Некоторые из недостатков версии VARCHAR:

  • Вы не можете легко добавлять / вычитать дни к версии VARCHAR.
  • Труднее извлечь только месяц / год.
  • Ничто не останавливаетВы помещаете данные без даты в столбец VARCHAR в базе данных.
  • Версия VARCHAR зависит от культуры.
  • Вы не можете легко отсортировать даты.
  • Этотрудно изменить формат, если вы захотите позже.
  • Это нетрадиционно, что усложнит понимание для других разработчиков.
  • Во многих средах использование VARCHAR будет занимать больше места для хранения.Это может не иметь значения для небольших объемов данных, но в коммерческих средах с миллионами строк данных это может иметь большое значение.

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

15 голосов
/ 21 января 2011

Когда у вас будет база данных с более чем 2-3 миллионами строк, вы поймете, почему лучше использовать DATETIME, чем VARCHAR:)

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

В основном с современными жесткими дисками вы можете читать около 100 записей в секунду, если они читаются в случайном порядке (обычно это так), поэтому вы должны сделать все возможное, чтобы минимизировать размер БД, потому что:

  • Головкам жесткого диска не нужно будет так много "путешествовать"
  • Вы поместите больше данных в ОЗУ

В конце концов, время поиска жесткого диска всегда будетубью тебя.Например.некоторый простой запрос GROUP BY с большим количеством строк может занять несколько часов при выполнении на диске по сравнению с несколькими секундами при выполнении в ОЗУ => из-за времени поиска.

Для VARCHAR вы не можете выполнять поиск.Если вам так не нравится, как SQL работает с датами, просто используйте метку времени unix в поле 32-битного целого числа.Вы будете иметь (в основном) все преимущества использования поля SQL DATE, вам просто нужно будет манипулировать и форматировать даты, используя выбранный язык программирования, а не функции SQL.

6 голосов
/ 21 января 2011

Две причины:

  • Сортировка результатов по датам
  • Нечувствительность к изменениям форматирования даты

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

5/12/1999 | Frank N Stein
1/22/2005 | Drake U. La
10/4/1962 | Goul Friend

Если бы мы хранили данные по-своему, но отсортировали по датам в порядке сборки, SQL ответит набором результатов, который выглядит следующим образом:

1/22/2005 | Drake U. La
10/4/1962 | Goul Friend
5/12/1999 | Frank N. Stein

Где, если мы сохранили даты как DATETIME, SQL ответит правильно, упорядочив их следующим образом:

10/4/1962 | Goul Friend
5/12/1999 | Frank N. Stein
1/22/2005 | Drake U. La

Кроме того, если где-то в будущем вам нужно было отобразить даты в другом формате, например, например:ГГГГ-ММ-ДД, тогда вам нужно будет преобразовать все свои данные или иметь дело со смешанным контентом.Когда он хранится как SQL DATE, вы вынуждены выполнять преобразование в коде, и, скорее всего, у вас есть одна возможность изменить формат для отображения всех дат - бесплатно.

3 голосов
/ 21 января 2011

Я бы проголосовал за использование типов date / datetime, просто ради простоты / согласованности.

Если вы сохраните его в виде строки символов, сохраните его в формате ISO 8601 :

Помимо прочего, строка даты / времени (86) ISO 8601 правильно сопоставляется, (B) удобочитаема, (C) не зависит от локали и (D) легко конвертируется в другие форматы. Для шпаргалки из разметки ISO, строки ISO 8601 предлагают

представления для следующего:

  • Дата
  • Время дня
  • Всемирное координированное время (UTC)
  • Местное время со смещением по UTC
  • Дата и время
  • Временные интервалы
  • Периодические интервалы времени

Представления могут быть в одном из двух форматов: базовый формат имеет минимальное количество символов и расширенный формат это добавляет символы для повышения читабельности человека. Например, третье января 2003 года может быть представлено как 20030103 или 2003-01-03.

[и]

предлагает следующие преимущества перед многими из локально используемых представления:

  • Легко читаемые и записываемые системой
  • Легко сопоставимые и сортируемые
  • Не зависит от языка
  • Большие единицы написаны перед меньшими единицами
  • Для большинства представлений обозначения короткие и имеют постоянную длину

И последнее: если все, что вам нужно сделать, это сохранить дату, то сохранение ее в краткой форме ISO 8601 YYYYMMDD в столбце char (8) занимает не больше места, чем значение datetime (и вам не нужно беспокоиться о разрыве в 3 миллисекунды между последним тактом одного дня и первым тактом следующего. Но это вопрос другого обсуждения. Если разбить его на 3 столбца & mdash; YYYY char(4), MM char(2), DD char(2), вы будете использовать тот же объем памяти и больше возможностей для индексации. Более того, сохраняйте поля как сокращение для гггг (4 байта) и крошечное значение для каждого из ММ и ДД - теперь у вас до 6 байт для даты Недостаток, конечно же, в разложении компонентов даты на их составные части состоит в том, что преобразование в надлежащие типы данных даты / времени является сложным.

3 голосов
/ 21 января 2011

Между DATE/DATETIME и VARCHAR для дат, которые я бы использовал с DATE/DATETIME каждый раз.Но есть упущенный третий вариант.Сохраняя его как INTEGER без знака!

Я решил использовать INTEGER unsigned в своем последнем проекте, и я действительно доволен тем, что сделал этот выбор вместо того, чтобы сохранять его как DATE/DATETIME.Поскольку я передавал даты между клиентом и сервером, это было идеальным типом для меня.Вместо того, чтобы хранить его как DATE и конвертировать обратно каждый раз, когда я выбираю, я просто выбираю его и использую его так, как хочу.Если вы хотите выбрать дату в качестве «удобочитаемой» даты, вы можете использовать функцию FROM_UNIXTIME().

Также целое число занимает 4 байта, тогда как DATETIME занимает 8 байтов.Экономия 50% хранения.

Проблема сортировки, предложенная Берин, также решается с использованием целого числа в качестве хранилища для дат.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...