В базе данных вы бы использовали поле даты или поля года и месяца, если вам нужны только год и месяц? - PullRequest
8 голосов
/ 11 марта 2009

Я настраиваю таблицу, где мне нужны год и месяц. В MySQL я считаю, что у меня есть 2 варианта: (1) 2 поля: 1 для года, 1 для месяца или (2) поле даты (день всегда будет 1).

Преимущество двух полей в том, что они быстрее, потому что MySQL не нужно преобразовывать значение из даты в целое число, хотя это, вероятно, ничтожно мало. Поле даты имеет преимущество «автоматической» проверки: кто-то не может получить данные в БД с месяцем, равным 13, или годом, равным 1. С полем даты вы также можете легче выполнять вычисления даты (то есть, месяцы ).

Что бы вы использовали? Или есть другой, который вы бы использовали?

Ответы [ 10 ]

19 голосов
/ 11 марта 2009

Использовать поле даты. Поскольку sql изначально поддерживает поля даты, его легко фильтровать по конкретным датам с помощью предложения WHERE.

Преимущество двух полей в том, что они быстрее [...]

Ваш запрос SELECT не является вашим узким местом, поэтому вам не следует об этом беспокоиться. Читаемость и прагматичная программа важнее «воспринимаемого узкого места».

1 голос
/ 11 марта 2009

Подумайте об этом следующим образом: однажды к вам придет кто-то с требованием улучшить приложение, чтобы сэкономить не только год и месяц, но и день. Не могли бы вы добавить дополнительный столбец на один день? А потом, в следующий раз, они могут попросить вас сэкономить время.

Насколько легко было бы улучшить функциональность, если у вас есть отдельные столбцы для года / месяца / дня? Если у вас есть один столбец даты?

Я бы выбрал столбец даты только по этой причине.

1 голос
/ 11 марта 2009

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

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

Есть еще одна причина использовать отдельные столбцы месяца и года, с которыми я столкнулся: когда месяц неизвестен. Я использовал это для приложений, которые позволяют предстоящему событию быть «где-то в 2009 году». В этом случае использование NULL в столбце month решает проблему. Нет простого способа сделать это с помощью столбца с типом даты, если только вы не придумали какой-нибудь ужасный хак, например, 2 января означает, что месяц неизвестен.

1 голос
/ 11 марта 2009

Я бы сохранил столбец datetime и два вычисляемых столбца с месяцем и годом (конечно, проиндексирован). Возьми мой торт и съешь его тоже :)

1 голос
/ 11 марта 2009

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

Кроме того, подумайте о возможной боли при обслуживании из двух полей. У вас будет два поля базы данных, возможно, два поля на объекте или вам понадобится построить / проанализировать месяц и год в / из базы данных. Сохраняйте простоту с датой, и пусть БД отслеживает целостность ваших данных.

Я работаю с данными, которые вы описали - даты истечения срока, где день всегда является последним днем ​​месяца, поэтому нам нужны только месяц и год. Мы храним их как дату.

1 голос
/ 11 марта 2009

IBM Informix Dynamic Server, хотя он не предназначен для немедленного использования, поддерживает тип:

DATETIME YEAR TO MONTH

Здесь хранится именно то, что вы хотите - год и месяц. Это имеет свое применение. Семейство типов DATETIME включает в себя множество других типов, которые иногда используются - и некоторые из них имеют предельную полезность, каноническим примером является DATETIME MONTH TO MINUTE. (Недостатком типа являются подробные нотации, необходимые для манипулирования им, но есть много операций, которые можно выполнить с любым или всеми типами DATETIME.)

Во многих СУБД вы можете наложить ограничения на столбцы, поэтому, если вы используете двухколонный подход, вы наложите ограничение на CHECK(month_column BETWEEN 1 AND 12) на столбец, чтобы пользователь не поместил недопустимое значение в таблицу. , Вы можете даже наложить ограничение на столбец года.

Кроме того, некоторые СУБД позволяют вам создавать пользовательские типы, и тип год-месяц довольно прост. Конечно, детали зависят от СУБД.

1 голос
/ 11 марта 2009

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

1 голос
/ 11 марта 2009

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

1 голос
/ 11 марта 2009

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

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

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

0 голосов
/ 11 марта 2009

Вероятно, не потому, что наименьший тип данных datetime в SQL Server (Microsoft) равен smalldatetime, что составляет 4 байта. Если вам нужны только месяц и год, вам нужен 1 байт для месяца и 2 байта для года.

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