SQL Server Datetime vs. Datetime2

SQL Server-palvelimessa on monia aika-ja päivämäärämuotoja, joissa on erilaisia vaihteluvälejä, tarkkuuksia, tallennuskokoja ja käyttäjän määrittelemiä sekunnin murto-osia.

alla on lyhyt katsaus:

haluamme keskittyä datetime-ja datetime2-formaattien vertailuun. Nykyisessä yrityksessäni kohtaan paljon vanhoja taulukoita, jotka käyttävät datetime. Datetime2 esiteltiin ensimmäisen kerran SQL Server 2008: ssa. Olen kuitenkin sitä mieltä, että jotkut kehittäjät eivät yksinkertaisesti tiedä eduista ja haitoista datetime2.

Datetime

ensin keskustellaan datetime hieman. Kuten näet edellä, se tarvitsee 8 tavua tallennustilaa ja on välillä 1753-01-01 ja 9999-12-31. Erityisesti se on lyhyt kantama taaksepäin. Tämä johtuu siitä, että Iso-Britannia siirtyi Juliaanisesta kalenterista gregoriaaniseen kalenteriin vuonna 1752 hyppäämällä muutaman päivän. Tarkemmin sanottuna 2. syyskuuta 1752 seurasi 14. syyskuuta 1752. Koska päivämäärä ennen vuotta 1753 olisi epäselvä, datetime tyyppi ei ole voimassa ennen vuotta 1753. Toinen melko huomattava ominaisuus datetime datatype on tarkkuus 0,00333 sekuntia, joka on itse asiassa 1/300 sekunnin.

tämä tuntuu hieman oudolta. Meillä ei ole millisekunnin tarkkuutta datetimen kanssa. Okei, mutta miksi? Olkaamme analysoida datetime datatyyppi perusteellisesti. Vuonna datetime käytämme 4 tavua päivämäärä ja 4 tavua aika. Miten se toimii? Katsotaanpa.

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

joten 0x0000A55F00A4CB80 on heksadesimaalinen. Jakakaamme 8 tavua kahteen osaan. Ensin Treffit. 0x0000A55F edustaa päivämäärää. Desimaalilukuna se on 42335. Sen verran päiviä on kulunut vuodesta 1900-01-01. Todiste:

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

nyt on viimeiset 4 tavua 0xA4CB80 käännetty desimaaliksi se on 10800000. Se tarkoittaa 10800000 punkkia keskiyöstä lähtien. Muistatko, kun sanoin, että tarkkuus on 1/300 sekuntia? Tämä johtuu siitä, että datetime tallentaa aikaa punkkeja. Joten 10800000 punkkia keskiyön jälkeen tarkoittaa 10800000 kertaa 1/300 sekunnissa. Lasketaan vähän.

meillä on siis tasan 10 tuntia keskiyöstä ja se tarkoittaa täydellisesti 10:00:00. Yhdistettynä päivämäärä meillä on 2015-11-29 10: 00: 00.

muista, että datetime käyttää aina 8 tavua tallennustilaa ja muista myös, että neljä ensimmäistä tavua, jotka edustavat päivämäärää, voivat olla negatiivisia (2 täydennystä), koska päivämäärä voi olla ennen vuotta 1900. Esimerkiksi 1890-11-29 saa ensimmäiset 4 tavua 0xfffff308: na, joka tarkoittaa 32-bittistä 2-komplementtia -3320: een. Ja 3320 substraattia vuodelta 1900-01-01 on tarkalleen 1890-11-29.

datetime2

kaikilla SQL Server 2008: ssa käyttöön otetuilla datatyypeillä on täysin uusi tallennustyyppi, jota tutkimme nyt. Datetime2-datatyyppi käyttää 6-8 tavua milisekunnin tarkkuudesta riippuen.

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

tällä kertaa homma mutkistuu hieman. Kaikissa uusissa datetime-tietotyypeissä kolme viimeistä tavua edustavat päivämäärää. Tämä johtuu tavujärjestyksen muutoksesta. Niinpä datetime tallennetaan little endianiksi, eli merkittävin tavu on vasemmalla, kun taas Isossa endianissa merkittävin tavu on tallennettu oikeanpuoleisimpaan asentoon.

se tarkoittaa, että kun otamme 0x0300512502BA3A0B, päivämäärä ei ole 0xba3a0b vaan 0x0B3ABA, koska yksi tavu on 2 heksadesimaalilukua.

jälleen matematiikka: 0x0B3ABA edustaa desimaaliluku 735930. Tämä on juuri se päivä, jonka halusimme.:

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

nyt kun tavut muunnetaan, voimme vain ottaa viimeisen tavun pikku endian esityksestä, joka on 0x0225510003. Muista, että aivan viimeinen tavu little endianissa (joka on ensimmäinen tavu alkuperäisessä big endianissa) on ilmoitettu tarkkuus. Kuten näette, määritimme datetime2(3), joka tarkoittaa, että viimeinen tavumme on 0x03.

laskutoimitus: 0x02255100 on desimaalina 36000000. Koska käytimme tarkkuutta 3, joka tarkoittaa 3-numeroista tarkkuutta, laskemme sekunnit ensin jakamalla lukumme luvulla 10 tarkkuuden potenssiin, joka on meidän tapauksessamme 103.

tämäkin kääntyy täydellisesti 10 tuntiin 0 minuuttiin 0 sekuntiin aivan kuten on sanottu.

datetime vs. datetime2

lopuksi yksinkertainen ja yksinkertainen vertailu näiden kahden tietotyypin välillä.

datetime datetime2
suurin pariton tarkkuus 1/300 100 nanosekunnin tarkkuus
käyttäjän määrittelemä tarkkuus ei Kyllä, vaihteluväli 0 – 7
tallennustila aina 8 tavua 6 – 8 tavua tarkkuudesta riippuen
voidaan käyttää + tai-operaattorilla Kyllä ei, käytä datediff, dateadd jne.
SQL Standard compatible ei Kyllä

joten kaiken näet datetime käyttää mahdollisesti enemmän tallennustilaa, on pienempi ja pariton tarkkuus, on pienempi alue ja ei ole yhteensopiva SQL-standardin kanssa, mikä tekee koodin käyttäytymään eri tavoin eri DBMS. Joten jos sovellus tukee date, datetime2 ja datetimeoffset voimakkaasti neuvoo käyttämään uutta datetime tietotyypit, koska niillä on tuskin mitään haittaa.

Kiitos ajastasi. Kiinnostavammissa artikkeleissa käy http://www.dirtyread.de/

Vastaa

Sähköpostiosoitettasi ei julkaista.