Przechowywanie daty jako liczby całkowitej (numerycznej), jakie są zalety

11

Pytanie 1

Pracuję z systemem, w którym data jest przechowywana jako liczba całkowita (rzeczywista liczba (8,0)) i zauważyłem, że inne systemy również przechowują datę jako int, np. Cisco w tym wątku . Przykład

20120101  -- 01 Jan 2012

Czy jest jakaś korzyść z utrzymywania liczbowego systemu dat i niestosowania SQL Datetime?

pytanie 2

Teraz próbuję przeglądać datę numeryczną, aby znaleźć klientów między dwiema datami. Jeśli starti enddateobejmują dwa miesiące, otrzymuję tysiące rekordów zamiast tylko 60. Przykład:

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

Spowoduje to pobranie 8931 rekordów zamiast 60. Czy istnieje lepszy sposób na ulepszenie logiki powyżej, aby pobierać tylko prawidłowe daty? Próbowałem IsDate i zapytań podrzędnych, ale nie działało to skutecznie.

Jackofall
źródło
Jeśli korzystasz z SQL Server 2008 lub nowszej wersji, możesz po prostu użyć typu danych Date. Jest nieco mniejszy i nie zmusza Cię do uwzględnienia czasu, ale prawie wszystkie funkcje datetime SQL nadal działają.
DForck42
2
Widzę tylko wady tego podejścia, nie ma żadnej przewagi
a_horse_w_no_name

Odpowiedzi:

11

Aby odpowiedzieć na pierwsze pytanie, zaleciłbym użycie DATETIMEtypu danych w SQL Server. Niekoniecznie ze względu na wydajność, ale w celu wykorzystania funkcjonalności specyficznej dla RDBMS. Na przykład, trzeba by wymyślać wiele logiki tylko zrobić podstawowe datę matematyki (myślę DATEDIFF(), DATEADD(), DATEPART()i wiele innych funkcji. Oczywiście są one dostosowane do DATETIMEtypu danych i są łatwe do pracy z).

Jeśli chodzi o twoje drugie pytanie, natrafisz na dokładny problem, do którego zmierza pierwsze pytanie (i moja odpowiedź) . Ty patrzysz 20111201 i 20120131 jak daty, a twój mózg jest informacją, która powinna być różnica 60 dni. Zapętlasz się w oparciu o deltę ... czyli:

20120131 - 20111201 = 8930 (z włączoną pętlą będzie 8931)

Innymi słowy, twoja WHILEpętla wykonuje 8931 razy. Dzieje się tak, ponieważ są to liczby całkowite, a Twoja pętla nie przeskoczy z 20111231 bezpośrednio do 20120101.

Wy, liczby całkowite, nie weźmiecie pod uwagę limitu lat i miesięcy (tj. Problemu z pytaniem 2 ).

Thomas Stringer
źródło
To jest dokładnie moje pytanie. W przypadku dat numerycznych pętle mogą być podzielone na tysiące, a nie tylko 30 dni lub 29 dni. Pamiętaj jednak, że pracuję z profesjonalnym systemem . I nawet cisco używa go, jak się wydaje.
Jackofall
4
Oprócz wydajności i funkcjonalności istnieje również integralność. Z całkowitymi jak daty, db pozwoliłoby 20121301a 20120230nawet 20129999jako data.
ypercubeᵀᴹ
@Jackofall Cisco nie ma za sobą platformy RDBMS. Napisali własną logikę. Dlaczego nie mieliby po prostu używać liczb całkowitych. Od podstaw jest to prawdopodobnie najłatwiejszy sposób dla oprogramowania niskiego poziomu. Ale mówimy tutaj o jabłkach i pomarańczach.
Thomas Stringer
3
@Jackofall: Istnieje ogromna różnica między przechowywaniem dat jako liczb całkowitych (i posiadaniem przerw) a przechowywaniem dat / znaczników czasu jako liczb całkowitych - a nawet dat jako liczb całkowitych, jak robi to VB / Excel.
ypercubeᵀᴹ
4
Istnieje wiele (jeśli nie większość) profesjonalnie zaprojektowanych baz danych, które wykorzystują złe techniki. Pracowałem z wieloma produktami COTS i nie widziałem żadnych, które zostały dobrze zaprojektowane z perspektywy bazy danych.
HLGEM
6
  1. Ralph Kimball zaleca przechowywanie dat jako liczb całkowitych. Dużo napisał, zarówno artykuły online, jak i książki.
  2. Możesz użyć tabeli kalendarza i wydawać kolejne numery swoim datom w następujący sposób:

    Numer daty

    20120229 1234

    20120301 1235

Tabela kalendarza musi zostać wygenerowana, ale jest to bardzo łatwe zadanie.

AK
źródło
1
Chciałbym zobaczyć przypadek, w którym odfiltrujesz zapytanie, łącząc się z tabelą dat z datami zapisanymi jako wartości liczbowe, a filtrowanie tych dat liczbowych byłoby bicie przy użyciu „gdzie [data] między @startdate i @enddate”
DForck42
1
@ DForck42 nie ma potrzeby proponowanego przypadku: „gdzie [dataAsInt] między 20120229 a 20120329” zwróci dokładnie te same wiersze, co „gdzie [data] między„ 20120229 ”a„ 20120329 ””
AK
3
A jakie było jego rozumowanie?
HLGEM
5

Potencjalne typy danych i ich rozmiary / ograniczenia:

  • Dziesiętny (8,0): 5 bajtów
  • Data: 3 bajty, 0001-01-01 do 9999-12-31
  • Int: 4 bajty

Plusy dla numerycznego typu danych:

  • Wyglądają ładnie?

Wady dla numerycznego typu danych:

  • Wymaga niestandardowego kodu do obsługi operacji na datach
  • Wymaga niestandardowego kodu do zarządzania poprawnymi datami (tj. Niedozwoleniem 20120230 [30 lutego 2012 r.])
  • Większy ślad danych w porównaniu do typu danych Data.

Szczerze mówiąc, lepiej jest użyć typu danych IMHO.

DForck42
źródło