Я создаю приложение, которое имеет ежедневную цитату, которая должна быть сохранена в базе данных. Каждой цитате присваивается день в году, в том числе один на 29 февраля. Поскольку котировка касается только дня, а не года, я должен использовать тип smalldatetime? Пожалуйста, дайте мне знать ваше мнение, спасибо!
Каков наилучший способ хранения даты без года в базе данных SQL?
Ответ 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)