Каков наилучший способ хранения даты без года в базе данных SQL?

Я создаю приложение, которое имеет ежедневную цитату, которая должна быть сохранена в базе данных. Каждой цитате присваивается день в году, в том числе один на 29 февраля. Поскольку котировка касается только дня, а не года, я должен использовать тип smalldatetime? Пожалуйста, дайте мне знать ваше мнение, спасибо!

Ответ 1

У меня была эта проблема в последнее время, мой первоначальный дизайн сохранил дату, и я просто проигнорировал год. Тем не менее, это просто не понравилось. Я решил просто удалить его и иметь отдельный столбец Day/Month. Он просто чувствовал себя намного чище и читательнее.

Обновление

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

В зависимости от ваших политик проверки это может не беспокоить, однако, если вы полагаетесь на проверку БД, я бы посоветовал вам либо сохранить его как DATE, либо просто вытащить соответствующую информацию или использовать триггер для выполнения некоторой проверки перед вставкой.

Ответ 2

Другой вариант (я не думаю, что кто-то еще предложил) будет хранить месяц и день как отдельные ints. Итак, чтобы найти сегодняшнюю запись, вы могли бы:

select quote from quoteTable where month = 4 and day = 20;

Это позволит вам иметь специальные сообщения дня, не используя даты (и игнорируя год).

Просто идея.

Ответ 3

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

Ответ 4

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

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

Ответ 5

Поскольку не существует типа Interval, такого как Oracle, тогда у вас есть один из нескольких вариантов, которые приходят на ум.

  • Храните год при использовании даты и времени / smalldatetime, это будет стоить вам ничего не нужно хранить, просто выберите, чтобы не отображать его.
  • Принять подход типа DW с датой таблицу и ссылку на нее с помощью PK/FK
  • Используйте тип, не основанный на дате, например smallint или varchar, хотя это вполне может привести к некоторым трудностям в вопросе о том, чтобы оставаться и избегайте сканирования.

Ответ 6

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

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

Ответ 7

Вы все равно можете использовать столбец datetime в своей базе данных и использовать функцию DatePart() SQL для получения дня года.

SELECT datepart(dy,myDateColumn) FROM myTable

Ответ 8

Я бы не использовал для этого время datetime. В некотором смысле, вы будете хранить неверные данные. Например, вы будете хранить 4/20/2010 как 4/20/2012 или в любой другой год, который вы выбрали. Несмотря на то, что год не имеет значения для вашего приложения, этот подход может привести к неожиданным проблемам.

Например, что, если вы каким-то образом получили дату там с неправильным годом? Ваши расчеты будут неправильными.

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

Ответ 9

Как насчет varchar с 0305, являющимся 5 марта.

Ответ 10

Вы также можете рассмотреть возможность использования одного int для хранения дня года.

Было бы немного больно переводить между форматом человеческого разговора и днем ​​года. С другой стороны, будет очень легко назначить даты кавычками и выбрать их.

SELECT quote FROM QuoteTable 
WHERE dayOfYear = DATEPART(dy, GETDATE())

Ответ 11

Я не могу не чувствовать, что если календарь был изобретен инженером-программистом, что високосный день будет 32 декабря, а не 29 февраля. Таким образом, вы могли бы просто использовать небольшое смещение от 1 января.

Вы по-прежнему можете использовать небольшое смещение с 1 марта, с 1 марта, как 0, 2 марта, как 1, 29 февраля, как 365. Однако он включает в себя выполнение какого-то пользовательского преобразования в нужную цифру и может не сортировать как вы хотели бы.

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

Ответ 12

CONVERT(VARCHAR(5),GETDATE(),101)