SQL Server Datetime vs. Datetime2

az SQL Server számos idő-és dátumformátumot tartalmaz különböző tartományokkal, pontosságokkal, tárolási méretekkel és a felhasználó által definiált tört másodperc pontosságokkal.

az alábbiakban egy rövid áttekintés található:

a datetime és a datetime2 formátum összehasonlítására szeretnénk összpontosítani. A jelenlegi cégemben sok régi táblával találkozom, amelyek a datetime-t használják. A Datetime2-t először az SQL Server 2008-ban vezették be. Úgy gondolom azonban, hogy néhány fejlesztő egyszerűen nem ismeri a datetime2 előnyeit és hátrányait.

Datetime

először beszéljünk egy kicsit a datetime-ről. Mint látható fent, szüksége van 8 bájt tárhelyet, és van egy sor 1753-01-01 hogy 9999-12-31. Nevezetesen, hogy van egy rövid hatótávolságú hátra. Nagy-Britannia ugyanis 1752-ben költözött a Julianusról a Gergely-naptárra néhány nap kihagyásával. Pontosabban, a szeptember 2-án 1752 követte szeptember 14-én 1752. Mivel az 1753 előtti dátum kétértelmű lenne, a datetime típus 1753 előtt nem érvényes. A datetime adattípus másik meglehetősen észrevehető tulajdonsága a 0,00333 másodperc pontossága, amely valójában 1/300 másodperc.

ez egy kicsit furcsának tűnik. Nincs ezredmásodperc pontossággal datetime. Oké, de miért? Elemezzük részletesen a datetime adattípust. Egy datetime – ban 4 bájtot használunk a dátumhoz, 4 bájtot pedig az időhöz. Hogy működik ez pontosan? Nézzük meg.

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

tehát 0x0000A55F00A4CB80 hexadecimális. Válasszuk szét a 8 bájtot két részre. Először a dátum. 0x0000A55F a dátumot jelöli. Tizedesjegyben ez 42335. Ez az 1900-01-01 óta eltelt napok száma. Bizonyíték:

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

most arra az időre, amikor az utolsó 4 bájt 0xA4CB80 tizedesre fordítva 10800000. Ez 10800000 kullancsot jelent éjféltől. Emlékszel, azt mondtam, hogy a pontosság 1/300 másodperc? Ennek oka az a tény, hogy a datetime kullancsokban tárolja az időt. Tehát 10800000 kullancs éjfél óta 10800000-szer 1/300 másodpercet jelent. Számoljunk egy kicsit.

tehát pontosan 10 óránk van éjféltől, ami tökéletesen 10:00:00-ra fordul. Együtt a dátum van 2015-11-29 10:00: 00.

ne feledje, hogy a datetime mindig 8 bájt tárhelyet használ, és ne feledje, hogy a dátumot képviselő első négy bájt negatív lehet (2kiegészítés), mivel a dátum 1900 előtt is lehet. Például 1890-11-29-ben az első 4 bájtot 0xfffff308-ként kapjuk,ami 32 bites 2-kiegészítésként -3320. És a 3320 1900-01-01-ből pontosan 1890-11-29.

datetime2

az SQL Server 2008-ban bevezetett összes dátum és idő adattípus teljesen új tárhelytípust tartalmaz, amelyet most megvizsgálunk. A datetime2 adattípus 6-8 bájtot használ a miliszekundumos pontosságtól függően.

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

ezúttal egy kicsit bonyolultabb lesz. Minden új datetime adattípusban az utolsó három bájt képviseli a dátumot. Ez a byte sorrend változásának köszönhető. Tehát a datetime kis endianként van tárolva, vagyis a legjelentősebb bájt a bal szélső, míg a big endianban a legjelentősebb bájt a jobb szélső helyzetben van tárolva.

ez azt jelenti, hogy amikor 0x0300512502ba3a0b-t veszünk, a dátum nem 0xBA3A0B, hanem 0x0B3ABA, mivel egy bájt 2 hexadecimális számjegy.

ismét a matematikával: a 0x0B3ABA a decimális 735930 értéket képviseli. Pontosan ezt a dátumot akartuk:

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

most, hogy a bájtokat átalakítottuk, csak a little endian reprezentáció utolsó bájtját vehetjük fel, amely 0x0225510003. Ne feledje, hogy a little endian utolsó bájtja (ez az eredeti big endian első bájtja) a megadott pontosság. Mint látható, meghatároztuk a datetime2(3) – t, ami azt jelenti, hogy az utolsó bájtunk 0x03.

a matematika elvégzése: 0x02255100 tizedes 36000000. Mivel a 3-as pontosságot használtuk, ami 3 számjegyű pontosságot jelent, először kiszámítjuk a másodperceket úgy, hogy számunkat 10-gyel osztjuk a pontosság erejére, amely esetünkben 103.

ez tökéletesen lefordítja a 10 óra 0 perc 0 másodpercet is, amint azt elmondtuk.

datetime vs datetime2

végül egy egyszerű és egyszerű összehasonlítás a két adattípus között.

datetime datetime2
max pontos páratlan pontosság 1/300 100 nanoszekundumos pontosság
felhasználó által meghatározott pontosság nem igen 0-tól 7
tárhely mindig 8 bájt 6-8 bájt a pontosságtól függően
használható a + vagy-operátor igen nem, használja a datediff, dateadd stb.
SQL szabvány kompatibilis nem igen

tehát összességében azt látja, hogy a datetime potenciálisan több tárhelyet használ, alacsonyabb és páratlan pontosságú, alacsonyabb tartományú, és nem kompatibilis az SQL szabvánnyal, ami miatt a kód másképp viselkedik a különböző DBMS-Eken. Tehát, ha az alkalmazás támogatja a dátumot, a datetime2 és a datetimeoffset erősen ajánlom az új datetime adattípusok használatát, mivel alig vannak hátrányaik.

köszönöm az idejét. További érdekes cikkekért látogasson el http://www.dirtyread.de/

Vélemény, hozzászólás?

Az e-mail-címet nem tesszük közzé.