Сохранение даты в виде целого числа (числовое), каковы преимущества

11

Вопрос 1

Я работаю с системой, где дата хранится как целое число (фактическое число (8,0)), и я заметил, что другие системы также хранят дату как int, например, cisco в этой теме . пример

20120101  -- 01 Jan 2012

Есть ли какое-то преимущество в том, чтобы хранить систему числовых дат и не использовать SQL Datetime?

вопрос 2

Сейчас я пытаюсь перебрать числовую дату, чтобы найти клиентов между двумя датами. Если startи enddateохватывает два месяца, я получаю тысячи записей вместо 60. Пример:

create table #temp1(day int,capacity int) /* just a temp table */

declare @start int 
declare @end int

set @start=20111201
set @end = 20120131

while (@start <= @end) 
Begin
    insert into #temp1  /* I am storing things in #temp table so data looks pretty */
    exec usp_GetDailyCap @date1= @start

    set @start = @start + 1;    
end

select * from #temp1

Это тянет 8931 записей вместо 60. Есть ли лучший способ улучшить логику выше, чтобы я выбирал только действительные даты? Я пробовал IsDate и подзапросы, но это не совсем эффективно.

Jackofall
источник
Если вы работаете с SQL Server 2008 или выше, вы можете просто использовать тип данных Date. Это немного меньше и не заставляет вас включать время, но почти все функции datetime в SQL все еще работают для него.
DForck42
2
Я вижу только недостатки в этом подходе никаких преимуществ вообще
a_horse_with_no_name

Ответы:

11

Чтобы ответить на ваш первый вопрос, я бы рекомендовал использовать DATETIMEтип данных в SQL Server. Не обязательно по соображениям производительности, но для использования функциональности, специфичной для СУБД. Например, вам придется заново изобретать много логики просто сделать базовую дату математики (думаете DATEDIFF(), DATEADD(), DATEPART()и многие другие функции. Они явно приспособлены к DATETIMEтипу данных и легко работать с).

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

20120131 - 20111201 = 8930 (с включенным циклом это будет 8931)

Другими словами, ваш WHILEцикл выполняется 8931 раз. Это происходит потому, что это целочисленные значения, и ваш цикл не будет переходить с 20111231 на 20120101.

Вы, целые числа, не собираетесь принимать во внимание ограничение по годам и месяцам (т.е. ваша проблема по Вопросу 2 ).

Томас Стрингер
источник
Ну, это как раз мой вопрос. Для числовых дат циклы могут составлять тысячи, а не только 30 или 29 дней. Но имейте в виду, что я работаю с профессиональной системой . И даже cisco использует его, как кажется.
Джекофолл,
4
Помимо производительности и функциональности, есть еще и целостность. С целыми числами как даты, дб позволит 20121301и 20120230даже в 20129999качестве даты.
ypercubeᵀᴹ
@Jackofall У Cisco нет платформы СУБД. Они написали свою собственную логику. Почему бы им просто не использовать целые числа? С самого начала это, вероятно, самый простой способ для низкоуровневого программного обеспечения. Но мы говорим о яблоках и апельсинах здесь.
Томас Стрингер
3
@Jackofall: Существует большая разница между хранением дат в виде целых чисел (и с пробелами) и хранением даты / времени в виде целых чисел - или даже дат в виде целых чисел, как это делает VB / Excel.
ypercubeᵀᴹ
4
Есть много (если не большинство) профессионально разработанных баз данных, которые используют плохие методы. Я работал со многими продуктами COTS и не видел ни одного, который был бы хорошо разработан с точки зрения базы данных.
HLGEM
6
  1. Ральф Кимбалл рекомендует хранить даты как целые числа. Он написал много статей, как онлайн, так и книг.
  2. Вы можете использовать таблицу календаря и выдавать последовательные номера для ваших дат, как показано ниже:

    Номер даты

    20120229 1234

    20120301 1235

Необходимо создать таблицу календаря, но это очень простая задача.

Аляска
источник
1
Я хотел бы видеть случай, когда вы фильтруете запрос, присоединяясь к таблице дат с датами, сохраненными в виде чисел, и фильтруя эти числовые даты, которые будут лучше, если использовать «где [дата] между @startdate и @enddate»
DForck42
1
@ DForck42 нет необходимости в предложенном вами случае: «где [dateAsInt] между 20120229 и 20120329» будет возвращать в точности те же строки, что и «где [дата] между« 20120229 »и« 20120329 »»
АК
3
И каково было его рассуждение?
HLGEM
5

Потенциальные типы данных и их размеры / ограничения:

  • Десятичное число (8,0): 5 байтов
  • Дата: 3 байта, с 0001-01-01 по 9999-12-31
  • Int: 4 байта

Плюсы для числового типа данных:

  • Они выглядят красиво?

Минусы для числового типа данных:

  • Требуется специальный код для обработки операций с датой
  • Требуется пользовательский код для управления правильными датами (т. Е. Не допускается 20120230 [30 февраля 2012])
  • Больший объем данных по сравнению с типом данных Date.

Честно говоря, вам лучше использовать тип данных даты ИМХО.

DForck42
источник