Збереження дати як ціле (числове), які переваги


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 та підзапити, але це не дуже ефективно працювало.


Якщо ви використовуєте SQL Server 2008 або новішої версії, ви можете просто використовувати тип даних Date. Він трохи менший і не змушує вас включати час, але майже всі функції дати SQL все ще працюють на це.
DForck42

2
Я бачу лише недоліки в такому підході, жодної переваги
a_horse_with_no_name

Відповіді:


11

Щоб відповісти на ваше перше запитання, я рекомендую використовувати DATETIMEтип даних у SQL Server. Не обов’язково з міркувань продуктивності, але для використання функціональних особливостей RDBMS. Наприклад, вам доведеться заново винаходити багато логіки просто зробити базову дату математики (думаєте DATEDIFF(), DATEADD(), DATEPART()і багато інших функцій. Вони явно пристосовані до DATETIMEтипу даних і легко працювати з).

Що стосується вашого другого питання, ви стикаєтеся з точною проблемою, до якої спрямовано перше питання (і моя відповідь) . Ви дивитесь на 20111201 та 20120131 як на дати, а ваш мозок говорить вам, що має бути різниця в 60 днів. Ну, ви перебираєте дельта дельта, а це:

20120131 - 20111201 = 8930 (при включеному циклі це буде 8931)

Іншими словами, ваш WHILEцикл виконується 8931 раз. Це відбувається тому, що це цілі значення, і ваш цикл не перескочить з 20111231 прямо на 20120101.

Ви цілі числа не збираєтесь враховувати обмеження років та місяців (тобто, ваша проблема 2 ).


Ну це саме моє питання. Для числових дат петлі можуть перейти на тисячі, а не лише 30 днів або 29 днів. Але майте на увазі, що я працюю з професійною системою . І навіть cisco використовує його, як здається.
Jackofall

4
Крім продуктивності та функціональності, є ще й цілісність. З цілими числами як дати, дб дозволить 20121301і 20120230навіть в 20129999якості дати.
ypercubeᵀᴹ

@Jackofall Cisco не має платформи RDBMS. Вони написали власну логіку. Чому б вони просто не використали цілі числа. З самого початку, це, мабуть, найпростіший спосіб для програмного забезпечення низького рівня. Але ми говоримо тут про яблука та апельсини.
Томас Стрінгер

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'"
AK

3
І які були його міркування?
HLGEM

5

Потенційні типи даних та їх розміри / обмеження:

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

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

  • Вони красиво виглядають?

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

  • Потрібен спеціальний код для обробки операцій з датою
  • Потрібен спеціальний код для керування правильними датами (тобто не допускаючи 20120230 [30 лютого 2012])
  • Більший слід даних у порівнянні з типом даних Date.

Чесно кажучи, вам краще використовувати тип даних IMHO про дату.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.