2011-08-03 9 views
10

Oto jeden mniej lub bardziej ze względu na doskonałość.Serwer SQL: Najbardziej optymalny sposób przechowywania czasu (bez daty).

Serwer Microsoft SQL Server zawiera tylko typ pola datetime do przechowywania dat i godzin.

Ale załóżmy, że chcę przechowywać listę godzin pracy, w których data jest zupełnie nieistotna. Obecnie używam typu datetime, a następnie po prostu wyświetlam porcję danych. Ale mam z tym dwa problemy.

  1. Wydaje się niezręcznie nieefektywne.
  2. Może to zmylić przyszłych programistów, aby zobaczyć datę nadejścia wraz z czasem, który może nie wiedzieć, czy jest używany w dowolnym miejscu, czy nie.

I tak to nasuwa pytanie; w przypadku braku konkretnego pola time (jak w MySQL), jaki jest najbardziej optymalny sposób przechowywania tylko określonej pory dnia, od 00:00 do 23:59?

UPDATE: To SQL Server 2005. (Również byłbym po prostu chcą wiedzieć, co zrobić, gdy w ogóle nie ma time typ.)

+2

Czy to jest SQL Server 2008 lub nowszy (skrzyżowanie palców), ponieważ wtedy można po prostu użyć typu danych Czas. –

+1

SQL Server 2008+ ma typ daty czasu: http: //msdn.microsoft.com/en-us/library/ms187752.aspx –

+0

SQL Server wprowadził [czas] (http://msdn.microsoft.com/en -us/library/bb677243.aspx) datatype w 2008 roku. –

Odpowiedz

7

Dla SQL Server 2005 lub starszej ...

Jeśli chcesz tylko wiedzieć, co do minuty, można przechowywać go jako int w zakresie 1-1440. 1 jest 00:01 i 1440 jest 0:00.

Łatwo byłoby zrobić wyświetlacz jako czas ponownie, jeśli chcesz:

SELECT CAST((605/60) as varchar) + ':' + RIGHT('0' + CAST((605 % 60) as varchar), 2)

Dodatkowym atutem jest to, że jeśli używasz smallint Typ danych podczas zapisywania 1-3 bajtów na rekord z wbudowanego typu danych TIME.

TIME używa 3-5 bajtów na wiersz, a smallint ma 2 bajty na wiersz.

Dodatkowe bajty są dla sekund i ułamków sekund Wierzę.

EDIT

To bardziej skomplikowane z sekundy, ale nadal wykonalne powinny myślę ...

1-86400 range (sekundy dziennie)

DECLARE @i INT 
SET @i = 3661 

SELECT RIGHT('0' + CAST((@i/3600) as varchar),2) --hours 
+ ':' + RIGHT('0' + CAST((@i % 3600)/60 as varchar), 2) -- minutes 
+ ':' + RIGHT('0' + CAST((@i % 3600)%60 as varchar), 2) -- seconds 
+0

Interesujące. Co, jeśli chcę mieć godziny, minuty i sekundy, czy wiesz? – Teekin

+1

@Helgi zobacz edycję – JNK

+0

Użyłbym zakresu '0 do n-1'; północ jest zwykle uważana za pierwszą chwilę na początku dnia, a nie za ostatnią chwilę pod koniec dnia. (To zależy od konkretnego przypadku, ale jest to znacznie bardziej normalne z mojego doświadczenia.) – MatBailie

2
+2

Dotyczy obecnie tylko "SQL Server 2008". – JNK

+1

@JNK true, ale autor nie określił wymagań dotyczących wersji. –

+0

Wiem, ale wystarczy się upewnić, że kwalifikuje się to w tych przypadkach. Jeśli wersja nie jest określona, ​​ale twoje rozwiązanie jest specyficzne dla wersji, wspomnij o tym w swojej odpowiedzi. – JNK

5

SQL Server 2008 ma TIME typ danych:

http://www.sql-server-performance.com/2007/datetime-2008/

DECLARE @dt as TIME 
SET @dt = getdate() 
PRINT @dt 

Przejdź na wersję SQL 2008?

+0

+1 Serwer SQL 2005 miał już "koniec życia" - zdecydowanie czas na aktualizację! –

+0

Wiesz, jak to działa z komercyjnym, zamkniętym oprogramowaniem! Koszt posiadania nie ma znaczenia, dopóki nie musisz dokonać aktualizacji. ;) – Teekin

2

Osobiście nie byłoby rozważenie kwestii poruszonych jako wystarczająca, by odchodzić od używania DATETIME lub smalldatetime.

  • int używa 4 bajtów, co robi smalldatetime
  • Ludzie popełniają błędy z Smallint które powodują niejawne konwersje typów (zwiększenie obciążenia CPU)
  • Disk Space jest tani, to dużo bajtów trzeba dodać do anythign znaczącej
  • Kodeksu takie jak WHERE minutes < 720 jest mniej zrozumiałe niż WHERE time < '12:00'
  • problemy z wyświetlaniem (takich jak konwersji DateTime do hh: mm) jest często najlepszym miejscem w kliencie
  • Korzystanie DATETIME umożliwia przyszłą elastyczność, na przykład przeniesienie do sekundy zamiast minut

powiedział, że użyłem pola Integer trzymać liczbę sekund, na przykład gdy jesteśmy one głównie wykorzystywane do obliczania średniego trwania itp

Moja najważniejsza uwaga przy wyborze typu to sposób użycia wartości; w celu zapewnienia czytelnego kodu i planów wykonawczych.

+0

+1 - Wszystkie bardzo ważne punkty. Mój punkt widzenia na temat bajtów w mojej odpowiedzi jest prawdopodobnie bardziej związany z moim osobistym doświadczeniem. Mam dużo BARDZO dużych (600m-2b wierszy) tabel i jeśli mogę zgolić kilka bajtów w wierszu, to szybko się sumuje. – JNK

+0

To prawda, ale istnieje silne przekonanie, że nawet 4 GB jest stosunkowo niewielkie. – MatBailie

0

SQL 2008 ustalony ten problem jak inni to zauważyli, ale w roku 2005:

Czy trzeba wykonywać żadnych dat matematyki na czas? Jeśli nie, możesz zapisać go jako ciąg znaków.

Jeśli chcesz wykonać matematyczną datę, datetime z ustawionym na zero dniem oraz opisową nazwą kolumny nie powinny zatrzymywać żadnych przyszłych programistów (i dzięki, że pamiętasz o tym).

I tak, datetime jest przyzwoity tylko do przechowywania w czasie, ale działa dobrze.

Powiązane problemy