Welcher:
ist die empfohlene Methode zum Speichern von Datum und Uhrzeit in SQL Server 2008+?
Ich bin mir der Unterschiede in der Präzision (und wahrscheinlich im Speicherplatz) bewusst, aber wenn ich diese vorerst ignoriere, gibt es ein Best-Practice-Dokument darüber, wann was zu verwenden ist, oder sollten wir vielleicht nur verwenden datetime2
?
DateTime2
Bitebene des Typs (oder einem anderen SQL Server ) basieren Typ für diese Angelegenheit)? Siehe die Nachteile in meiner 7/10/17 Antwort unten, warum ich frage.DATETIME2
hat einen Datumsbereich von "0001/01/01" bis "DATETIME
9999/12/31 ", während der Typ nur das Jahr 1753-9999 unterstützt.Wenn nötig,
DATETIME2
kann dies auch zeitlich genauer sein. DATETIME ist auf 3 1/3 Millisekunden begrenzt undDATETIME2
kann auf 100 ns genau sein.Beide Typen sind
System.DateTime
in .NET zugeordnet - da gibt es keinen Unterschied.Wenn Sie die Wahl haben, würde ich empfehlen,
DATETIME2
wann immer möglich zu verwenden. Ich sehe keine Vorteile bei der VerwendungDATETIME
(außer bei der Abwärtskompatibilität) - Sie werden weniger Probleme haben (mit Daten, die außerhalb des Bereichs liegen und solche Probleme verursachen).Plus: Wenn Sie nur das Datum (ohne Zeitangabe) benötigen, verwenden Sie DATE - es ist genauso gut wie
DATETIME2
und spart Ihnen auch Platz! :-) Gleiches gilt nur für die Zeit - verwendenTIME
. Dafür sind diese Typen da!quelle
Nullable<DateTime>
?datetime2 gewinnt in den meisten Aspekten außer (Kompatibilität mit alten Apps)
Bitte beachten Sie die folgenden Punkte
Bildquelle: MCTS Self-Paced Training Kit (Prüfung 70-432): Microsoft® SQL Server® 2008 - Implementierung und Wartung Kapitel 3: Tabellen -> Lektion 1: Erstellen von Tabellen -> Seite 66
quelle
datetime2
datetime2
man weniger Speicherplatz alsdatetime
und bietet dennoch eine größere Reichweite und höhere Präzision?Ich stimme @marc_s und @Adam_Poward zu - DateTime2 ist die bevorzugte Methode für die Zukunft. Es verfügt über einen größeren Datumsbereich, eine höhere Genauigkeit und verwendet (je nach Genauigkeit) den gleichen oder einen geringeren Speicherplatz.
Eines hat die Diskussion jedoch verpasst ...
@Marc_s besagt :
Both types map to System.DateTime in .NET - no difference there
. Dies ist richtig, aber die Umkehrung ist nicht wahr ... und es ist wichtig, wenn Datumsbereichssuchen durchgeführt werden (z. B. "Finde alle Datensätze, die am 05.05.2010 geändert wurden").Die .NET-Version von
Datetime
hat eine ähnliche Reichweite und Präzision wieDateTime2
. Wenn ein .netDatetime
dem alten SQL zugeordnet wird, erfolgtDateTime
eine implizite Rundung . Das alte SQLDateTime
ist auf 3 Millisekunden genau. Dies bedeutet, dass Sie11:59:59.997
so nah wie möglich am Ende des Tages sind. Alles, was höher ist, wird auf den nächsten Tag aufgerundet.Versuche dies :
Das Vermeiden dieser impliziten Rundung ist ein wichtiger Grund, auf DateTime2 umzusteigen. Die implizite Rundung von Daten führt eindeutig zu Verwirrung:
quelle
20100505
zu5/5/2010
gewechselt? Das erstere Format funktioniert mit jeder Region in SQL Server. Letzteres wird brechen:SET LANGUAGE French; SELECT Convert(datetime, '1/7/2015')
oops:2015-07-01 00:00:00.000
Fast alle Antworten und Kommentare waren schwer für die Vor- und Nachteile. Hier ist eine Zusammenfassung aller Vor- und Nachteile sowie einige wichtige Nachteile (in Nr. 2 unten), die ich nur einmal oder gar nicht erwähnt habe.
1.1. ISO-konformer (ISO 8601) (obwohl ich nicht weiß, wie dies in der Praxis zum Tragen kommt).
1.2. Mehr Reichweite (1/1/0001 bis 12/31/9999 vs. 1/1 / 1753-12 / 31/9999) (obwohl die zusätzliche Reichweite, alle vor dem Jahr 1753, wahrscheinlich nicht verwendet wird, außer z. in historischen, astronomischen, geologischen usw. Apps).
1.3. Stimmt genau mit dem Bereich des .NET-
DateTime
Typs überein (obwohl beide ohne spezielle Codierung vor und zurück konvertieren, wenn die Werte innerhalb des Bereichs und der Genauigkeit des Zieltyps liegen, mit Ausnahme von Con # 2.1 unten, da sonst Fehler / Rundungen auftreten).1.4. Mehr Präzision (100 Nanosekunden alias 0,000,000,1 Sek. Gegenüber 3,33 Millisekunden alias 0,003,33 Sek.) (Obwohl die zusätzliche Präzision wahrscheinlich nicht verwendet wird, außer zum Beispiel in technischen / wissenschaftlichen Apps).
1.5. Bei einer Konfiguration für ähnliche (wie in 1 Millisekunde nicht "gleich" (wie in 3,33 Millisekunden), wie Iman Abidi behauptet hat) Präzision wie
DateTime
wird weniger Speicherplatz benötigt (7 gegenüber 8 Bytes), aber dann würden Sie natürlich die verlieren Präzisionsvorteil, der wahrscheinlich einer der beiden am meisten angepriesenen Vorteile ist (der andere ist der Bereich), wenn auch wahrscheinlich nicht benötigte Vorteile).2.1. Wenn Sie einen Parameter an ein .NET übergeben
SqlCommand
, müssen Sie angeben,System.Data.SqlDbType.DateTime2
ob Sie möglicherweise einen Wert außerhalb desDateTime
Bereichs und / oder der Genauigkeit von SQL Server übergeben , da dieser standardmäßig verwendet wirdSystem.Data.SqlDbType.DateTime
.2.2. Kann nicht implizit / einfach in einen numerischen Gleitkommawert (Anzahl der Tage seit dem Mindestdatum / der Mindestzeit) konvertiert werden, um in SQL Server-Ausdrücken mit numerischen Werten und Operatoren Folgendes zu tun:
2.2.1. Addiere oder subtrahiere Anzahl von Tagen oder Teiltagen. Hinweis: Die Verwendung der
DateAdd
Funktion als Problemumgehung ist nicht trivial, wenn Sie mehrere, wenn nicht alle Teile der Datums- und Uhrzeitangabe berücksichtigen müssen.2.2.2. Nehmen Sie die Differenz zwischen zwei Datums- und Uhrzeitangaben für die Berechnung des Alters. Hinweis: Sie können
DateDiff
stattdessen nicht einfach die SQL Server- Funktion verwenden, da sie nicht so berechnet wird,age
wie es die meisten Benutzer erwarten würden, wenn die beiden Datums- und Uhrzeitangaben eine Kalender- / Uhrzeit-Datums- / Uhrzeitgrenze der angegebenen Einheiten überschreiten, wenn auch nur für einen winzigen Bruchteil diese Einheit, wird es gibt die Differenz als 1 diese Einheit gegen 0. Zum Beispiel kann dieDateDiff
inDay
‚s von zwei Daten mal nur 1 Millisekunde auseinander 1 vs. 0 (Tage) zurück , wenn diese Datum-Zeiten sind an verschiedenen Kalendertagen (dh "1999-12-31 23: 59: 59.9999999" und "2000-01-01 00: 00: 00.0000000"). Die gleichen Datums- und Uhrzeitunterschiede von 1 Millisekunde, wenn sie verschoben werden, damit sie keinen Kalendertag überschreiten, geben ein "DateDiff" inDay
0 (Tagen) zurück.2.2.3. Nehmen Sie die
Avg
Datums- und Uhrzeitangaben (in einer aggregierten Abfrage), indem Sie einfach zuerst in "Float" und dann wieder zurück in "Float" konvertierenDateTime
.HINWEIS: Um
DateTime2
in eine Zahl umzuwandeln , müssen Sie etwa die folgende Formel ausführen, bei der immer noch davon ausgegangen wird, dass Ihre Werte nicht unter dem Jahr 1970 liegen (was bedeutet, dass Sie den gesamten zusätzlichen Bereich plus weitere 217 Jahre verlieren. Hinweis: Möglicherweise Sie können die Formel nicht einfach anpassen, um einen zusätzlichen Bereich zu ermöglichen, da möglicherweise Probleme mit dem numerischen Überlauf auftreten.25567 + (DATEDIFF(SECOND, {d '1970-01-01'}, @Time) + DATEPART(nanosecond, @Time) / 1.0E + 9) / 86400.0
- Quelle: „ https://siderite.dev/blog/how-to-translate-t-sql-datetime2-to.html “Natürlich könnte man auch
Cast
zuDateTime
ersten (und ggf. wieder zuDateTime2
), aber Sie würden die Genauigkeit und Reichweite (alle vor dem Jahr 1753) Vorteile verlierenDateTime2
gegenDateTime
die prolly zugleich die 2 größten und auch prolly sind Die 2 am wenigsten benötigten, die die Frage aufwirft, warum sie verwendet werden, wenn Sie die impliziten / einfachen Konvertierungen in Gleitkommazahlen ( Anzahl der Tage) für Addition / Subtraktion / "Alter" (vs.DateDiff
) /Avg
Berechnungsvorteil verlieren, was ein großer Vorteil ist durch meine Erfahrung.Übrigens ist das
Avg
Datum und die Uhrzeit ein wichtiger Anwendungsfall (oder sollte es zumindest sein). a) Neben der Verwendung zum Ermitteln der durchschnittlichen Dauer, wenn Datums- und Uhrzeitangaben (da eine gemeinsame Basisdatum-Uhrzeit) zur Darstellung der Dauer verwendet wird (eine gängige Praxis), ist es b) auch nützlich, eine Dashboard-Statistik über das durchschnittliche Datum zu erhalten. Die Uhrzeit befindet sich in der Datums- / Uhrzeitspalte eines Bereichs / einer Gruppe von Zeilen. c) Eine Standard- Ad-hoc-Abfrage (oder sollte zumindest Standard sein) zur Überwachung / Fehlerbehebung von Werten in einer Spalte, die möglicherweise nie / nicht mehr gültig ist und / oder möglicherweise veraltet sein muss, besteht darin, für jeden Wert die Anzahl der Vorkommen aufzulisten und (falls vorhanden) dieMin
,Avg
undMax
Datum-Zeitstempel mit dem Wert zugeordnet.quelle
DateTime
sind, beziehen sich alle auf Auswirkungen auf SQL Server-Abfragen und -Anweisungen.DateTime2
bereits erwähnten (aufgrund der hohen Wahrscheinlichkeit eines Überlaufs)). Re. "funktioniert nicht für die meisten Datumstypen": Sie benötigen es nur, um mit einem zu arbeiten, und die meisten Daten in den meisten Apps müssen wahrscheinlich nie für ihre gesamte Lebensdauer in einen anderen Datumstyp konvertiert werden (außer vielleicht, wie ich auch erwähnt habe) ,DateTime2
umDateTime
(z. B. "Arithmetik an Datumsangaben" durchzuführen; P). Angesichts dessen ist es nicht die gesamte zusätzliche Codierung in nicht nur programmierten, sondern auch Ad-hoc-Forschungsabfragen wert, einen nicht arithmetikfreundlichen Datumstyp zu verwenden.DateTime2 verursacht Chaos, wenn Sie als Access-Entwickler versuchen, Now () in das betreffende Feld zu schreiben. Habe gerade eine Access -> SQL 2008 R2-Migration durchgeführt und alle datetime-Felder als DateTime2 eingefügt. Anhängen eines Datensatzes mit Now () als bombardiertem Wert. Es war okay am 01.01.2012 14:53:04 Uhr, aber nicht am 10.01.2012 14:53:04 Uhr.
Einmal machte der Charakter den Unterschied. Hoffe es hilft jemandem.
quelle
Hier ist ein Beispiel, das Ihnen die Unterschiede in der Speichergröße (Bytes) und der Genauigkeit zwischen smalldatetime, datetime, datetime2 (0) und datetime2 (7) zeigt:
was zurückkehrt
Wenn ich also Informationen auf die Sekunde - aber nicht auf die Millisekunde - speichern möchte, kann ich jeweils 2 Bytes speichern, wenn ich datetime2 (0) anstelle von datetime oder datetime2 (7) verwende.
quelle
während mit datetime2 die Genauigkeit erhöht wird , hat einige Kunden nicht unterstützen Datum , Zeit oder datetime2 und zwingen Sie zu einem Stringliteral zu konvertieren. Insbesondere erwähnt Microsoft ODBC-, OLE DB-, JDBC- und SqlClient-Probleme auf "niedriger Ebene" mit diesen Datentypen und verfügt über ein Diagramm, das zeigt, wie jeder den Typ zuordnen kann.
Wenn Wert Kompatibilität über Präzision, Gebrauch Datetime
quelle
Alte Frage ... Aber ich möchte hier etwas hinzufügen, das noch niemand gesagt hat ... (Hinweis: Dies ist meine eigene Beobachtung, fragen Sie also nicht nach einer Referenz.)
Datetime2 ist schneller, wenn es in Filterkriterien verwendet wird.
TLDR:
In SQL 2016 hatte ich eine Tabelle mit hunderttausend Zeilen und einer Datetime-Spalte ENTRY_TIME, da die genaue Zeit bis zu Sekunden gespeichert werden musste. Während ich eine komplexe Abfrage mit vielen Verknüpfungen und einer Unterabfrage ausführte, verwendete ich die where-Klausel als:
Die Abfrage war anfangs in Ordnung, wenn Hunderte von Zeilen vorhanden waren. Als jedoch die Anzahl der Zeilen zunahm, gab die Abfrage den folgenden Fehler aus:
Ich habe die where-Klausel entfernt und unerwartet wurde die Abfrage in 1 Sekunde ausgeführt, obwohl jetzt ALLE Zeilen für alle Daten abgerufen wurden. Ich führe die innere Abfrage mit der where-Klausel aus, und es dauerte 85 Sekunden, und ohne der where-Klausel dauerte es 0,01 Sekunden.
Ich bin hier auf viele Threads für dieses Problem als Datetime-Filterleistung gestoßen
Ich habe die Abfrage etwas optimiert. Aber die wirkliche Geschwindigkeit, die ich bekam, war das Ändern der datetime-Spalte in datetime2.
Jetzt dauert dieselbe Abfrage, für die zuvor eine Zeitüberschreitung aufgetreten ist, weniger als eine Sekunde.
Prost
quelle
Die Interpretation von Datumszeichenfolgen in
datetime
unddatetime2
kann auch unterschiedlich sein, wennDATEFORMAT
Einstellungen außerhalb der USA verwendet werden. Z.BDies gibt
2013-05-06
(dh den 6. Mai) fürdatetime
und2013-06-05
(dh den 5. Juni) für zurückdatetime2
. Mitdateformat
set tomdy
, both@d
und@d2
return2013-06-05
.Das
datetime
Verhalten scheint im Widerspruch zu der MSDN-Dokumentation zu stehen, inSET DATEFORMAT
der es heißt: Einige Zeichenfolgenformate, z. B. ISO 8601, werden unabhängig von der Einstellung DATEFORMAT interpretiert . Offensichtlich nicht wahr!Bis ich davon gebissen wurde, hatte ich immer gedacht, dass
yyyy-mm-dd
Daten unabhängig von den Sprach- / Gebietsschemaeinstellungen richtig gehandhabt werden.quelle
SET LANGUAGE FRENCH; DECLARE @d DATETIME = '20130605'; SELECT @d;
Versuchen Sie es erneut mit den Strichen.Laut diesem Artikel müssen Sie einfach DateTime2 (3) verwenden, wenn Sie mit DateTime2 die gleiche Genauigkeit von DateTime erzielen möchten. Dies sollte Ihnen die gleiche Genauigkeit bieten, ein Byte weniger beanspruchen und einen erweiterten Bereich bieten.
quelle
Ich bin gerade auf einen weiteren Vorteil gestoßen
DATETIME2
: Es vermeidet einen Fehler im Python-adodbapi
Modul, der explodiert, wenn ein Standardbibliothekswert übergebendatetime
wird, der Mikrosekunden ungleich Null für eineDATETIME
Spalte hat, aber gut funktioniert, wenn die Spalte als definiert istDATETIME2
.quelle
Das obige SQL funktioniert nicht mit einem DateTime2-Feld. Es wird zurückgegeben und der Fehler "Operandentyp clash: datetime2 ist nicht kompatibel mit int"
Das Hinzufügen von 1 für den nächsten Tag ist etwas, was Entwickler seit Jahren mit Daten tun. Jetzt hat Microsoft ein super neues datetime2-Feld, das diese einfache Funktionalität nicht verarbeiten kann.
"Verwenden wir diesen neuen Typ, der schlechter ist als der alte", glaube ich nicht!
quelle
datetime
unddatetime2
Datentypen wurden in SQL Server eingeführt beide 2008. Sie erhalten auchOperand type clash: date is incompatible with int
von derdate
Art , die seit dem ersten Tag dot schon hat. Alle drei Datentypen funktionieren jedochdateadd(dd, 1, ...)
einwandfrei.Ich denke, es
DATETIME2
ist der bessere Weg, das zu speicherndate
, weil es effizienter ist als dasDATETIME
. In könnenSQL Server 2008
Sie verwendenDATETIME2
, es speichert ein Datum und eine Uhrzeit, dauert 6-8bytes
zum Speichern und hat eine Genauigkeit von100 nanoseconds
. Wer also mehr Zeitpräzision braucht, wird es wollenDATETIME2
.quelle