SQL Server Datetime vs.Datetime2

există multe formate de timp și dată în SQL Server cu diferite intervale, precizii, dimensiuni de stocare și definite de utilizator fracționată a doua precizii.

mai jos este o scurtă prezentare generală:

dorim să ne concentrăm pe compararea formatului datetime și datetime2. În compania mea actuală întâlnesc o mulțime de tabele vechi care utilizează datetime. Datetime2 a fost introdus pentru prima dată în SQL Server 2008. Cu toate acestea, cred că unii dezvoltatori pur și simplu nu știu despre avantajele și dezavantajele datetime2.

Datetime

să discutăm mai întâi datetime un pic. După cum puteți vedea mai sus, are nevoie de 8 octeți de stocare și are o gamă de la 1753-01-01 la 9999-12-31. În special, are o rază scurtă înapoi. Acest lucru se datorează faptului că Marea Britanie s-a mutat de la calendarul iulian la cel Gregorian în 1752, sărind câteva zile. Mai precis, 2 septembrie 1752 a fost urmat de 14 septembrie 1752. Deoarece o dată înainte de 1753 ar fi ambiguă, tipul datetime nu este valabil înainte de 1753. O altă proprietate destul de vizibilă a tipului de date datetime este precizia de 0,00333 secunde, care este de fapt 1/300 de secundă.

acest lucru pare un pic ciudat. Nu avem precizie de milisecunde cu datetime. Bine, dar de ce? Să analizăm în profunzime tipul de date datetime. Într-un datetime folosim 4 octeți pentru Dată și 4 octeți pentru timp. Cum funcționează asta mai exact? Să aruncăm o privire.

DECLARE @test DATETIME = '2015-11-29 10:00:00.000';SELECT CAST(@test as varbinary(8))> 0x0000A55F00A4CB80

deci 0x0000A55F00A4CB80 este hexazecimal. Să separăm cei 8 octeți în două bucăți. Prima dată. 0x0000A55F reprezintă data. În zecimal este 42335. Aceasta este cantitatea de zile trecute de la 1900-01-01. Dovada:

SELECT DATEADD(DD,42335,'1900-01-01')> 2015-11-29

acum, pentru moment, avem ultimii 4 octeți 0xA4CB80traduși în zecimal, este 10800000. Asta înseamnă 10800000 de căpușe de la miezul nopții. Amintiți-vă am spus precizia este 1/300 de secundă? Acest lucru se datorează faptului că datetime stochează timpul în căpușe. Deci, 10800000 căpușe de la miezul nopții înseamnă 10800000 ori 1/300 de secundă. Să calculăm puțin.

deci avem exact 10 ore de la miezul nopții și asta se traduce perfect la 10:00:00. Combinat cu data avem 2015-11-29 10:00:00.

amintiți-vă că datetime utilizează întotdeauna 8 octeți de stocare și, de asemenea, rețineți că primii patru octeți reprezentând data pot fi negativi (2complement), deoarece data poate fi înainte de 1900. De exemplu, în 1890-11-29 obțineți primii 4 octeți ca 0xFFFFF308, care se traduce ca 32-bit 2-complement la -3320. Și 3320 scăzut din 1900-01-01 este exact 1890-11-29.

datetime2

toate tipurile de date de dată și oră introduse cu SQL Server 2008 au un tip de stocare complet nou pe care îl vom examina acum. Tipul de date datetime2 utilizează 6 până la 8 octeți în funcție de precizia milisecundă.

DECLARE @test DATETIME2(3) = '2015-11-29 10:00:00.000';SELECT CAST(@test as varbinary(8))> 0x0300512502BA3A0B

de data aceasta devine un pic mai complicat. În toate noile tipuri de date datetime, ultimii trei octeți reprezintă data. Acest lucru se datorează unei modificări a ordinii de octeți. Deci datetime este stocat ca puțin endian, ceea ce înseamnă că cel mai semnificativ octet este în partea stângă, în timp ce în Big endian cel mai semnificativ octet este stocat în poziția din dreapta.

asta înseamnă că atunci când luăm 0x0300512502ba3a0b data nu este 0xBA3A0B, ci 0x0B3ABA, deoarece un octet este de 2 cifre hexazecimale.

din nou cu matematica: 0x0b3aba reprezintă zecimalul 735930. Aceasta este exact data pe care am dorit-o:

SELECT DATEADD(DD,735930,CAST('0001-01-01' as date))> 2015-11-29

acum, că octeții sunt convertiți, putem lua doar ultimii octeți de mică reprezentare endiană care este 0x0225510003. Rețineți că ultimul octet din little endian (adică primul octet din big endian original) este precizia declarată. După cum puteți vedea, am definit datetime2(3), ceea ce înseamnă că ultimul nostru octet este 0x03.

făcând matematica: 0x02255100 este în zecimal 36000000. Deoarece am folosit precizie 3, ceea ce înseamnă precizie de 3 cifre, calculăm mai întâi secundele împărțind numărul nostru cu 10 la puterea de precizie care este în cazul nostru 103.

acest lucru se traduce, de asemenea, perfect la 10 ore 0 minute 0 secunde la fel cum a declarat.

datetime vs datetime2

în cele din urmă o comparație simplă și simplă între cele două tipuri de date.

datetime datetime 2
precizie impară precisă maximă de 1/300 precizie de 100 nanosecunde
precizie definită de utilizator nu da variind de la 0 la 7
spațiu de stocare întotdeauna 8 octeți 6-8 octeți în funcție de precizie
utilizabil cu + sau-operator da nu, utilizați datediff, dateadd etc.
SQL standard compatibil nu da

deci, în general, vedeți că datetime utilizează potențial mai mult spațiu de stocare, are o precizie mai mică și ciudată, are o gamă mai mică și nu este compatibil cu standardul SQL, ceea ce face ca codul dvs. să se comporte diferit pe diferite baze de date. Deci, dacă cererea dumneavoastră acceptă data, datetime2 și datetimeoffset am puternic sfătui cu privire la utilizarea noilor datetime datatypes, deoarece acestea au abia orice dezavantaj.

Vă mulțumim pentru timpul acordat. Pentru mai multe articole interesante vizitați http://www.dirtyread.de/

Lasă un răspuns

Adresa ta de email nu va fi publicată.