893 Stimmen

DateTime2 vs. DateTime in SQL Server

Welche?

es le site Empfohlene Methode zum Speichern von Datum und Uhrzeit in SQL Server 2008+?

Ich bin mir der Unterschiede in der Genauigkeit (und dem Speicherplatz) bewusst, aber ignoriere diese für den Moment, gibt es ein Best-Practice-Dokument darüber, wann was zu verwenden ist, oder sollten wir vielleicht einfach datetime2 nur?

758voto

Adam Porad Punkte 13624

Die MSDN-Dokumentation für datetime empfiehlt die Verwendung von datetime2 . Hier ist ihre Empfehlung:

Verwenden Sie die time , date , datetime2 y datetimeoffset Datentypen für neue Arbeit. Diese Typen entsprechen dem SQL Standard. Sie sind besser portierbar. time , datetime2 y datetimeoffset mehr Sekunden Präzision bieten. datetimeoffset bietet Zeitzone Unterstützung für weltweit eingesetzte Anwendungen.

datetime2 hat einen größeren Datumsbereich, eine größere Standardbruchgenauigkeit und eine optionale benutzerdefinierte Genauigkeit. Abhängig von der benutzerdefinierten Genauigkeit kann auch weniger Speicherplatz benötigt werden.

65 Stimmen

Datetime2 bietet zwar eine höhere Genauigkeit, aber einige Clients unterstützen weder Datum, Uhrzeit noch datetime2 und zwingen Sie dazu, in ein String-Literal zu konvertieren. Wenn Sie mehr Wert auf Kompatibilität als auf Präzision legen, verwenden Sie datetime

8 Stimmen

Eine andere Möglichkeit ist die Verwendung einer indizierten Ansicht, bei der die Spalte aus Kompatibilitätsgründen in ein Datum umgewandelt wird. Sie müssten jedoch in der Lage sein, die Anwendung auf die Ansicht zu verweisen.

16 Stimmen

Die Unterstützung von Zeitzonen mit DATETIMEOFFSET ist eine falsche Bezeichnung. Es wird nur ein UTC-Offset für einen bestimmten Zeitpunkt gespeichert, nicht eine Zeitzone.

581voto

marc_s Punkte 701497

DATETIME2 hat einen Datumsbereich von "0001 / 01 / 01" bis "9999 / 12 / 31", während der DATETIME Typ unterstützt nur die Jahre 1753-9999.

Außerdem, wenn Sie es brauchen, DATETIME2 kann zeitlich genauer sein; DATETIME ist auf 3 1/3 Millisekunden begrenzt, während DATETIME2 kann bis auf 100ns genau sein.

Beide Typen sind mit System.DateTime in .NET - da gibt es keinen Unterschied.

Wenn Sie die Wahl haben, würde ich empfehlen, die DATETIME2 wann immer möglich. Ich sehe keine Vorteile bei der Verwendung von DATETIME (außer aus Gründen der Abwärtskompatibilität) - dann haben Sie weniger Probleme (mit Datumsangaben, die außerhalb des zulässigen Bereichs liegen, und ähnlichen Problemen).

Plus: Wenn Sie nur das Datum (ohne Zeitangabe) benötigen, verwenden Sie DATE - es ist genauso gut wie DATETIME2 und spart auch noch Platz! :-) Dasselbe gilt für die Zeit - verwenden Sie TIME . Dafür sind diese Typen ja da!

0 Stimmen

Ich würde Marc zustimmen. Sofern Sie nicht aus irgendeinem Grund Abwärtskompatibilität benötigen, sollten Sie immer DATETIME2 verwenden. Speicherplatz ist billig und nach dem, was ich in meiner eigenen Erfahrung gesehen und anderswo gelesen habe, gibt es keinen Unterschied im Verarbeitungsaufwand zwischen den beiden.

176 Stimmen

Seien Sie vorsichtig, wenn Sie einen .NET DateTime-Wert als Parameter zu einem SqlCommand hinzufügen, denn es wird gerne angenommen, dass es sich um den alten Datetime-Typ handelt, und Sie erhalten eine Fehlermeldung, wenn Sie versuchen, einen DateTime-Wert zu schreiben, der außerhalb des Jahresbereichs 1753-9999 liegt, es sei denn, Sie geben den Typ explizit als System.Data.SqlDbType.DateTime2 für den SqlParameter an. Wie auch immer, datetime2 ist großartig, weil es jeden Wert speichern kann, der im .NET DateTime-Typ gespeichert werden kann.

2 Stimmen

@marc_s - Ich verstehe nicht, warum Sie DATETIME2 bevorzugen, wenn alles andere gleich ist. Ist die Flexibilität, das Jahr 1-1752 zu unterstützen, wirklich ein Vorteil für die meisten Anwendungen? Ich hatte noch nie eine Anwendung, die ein Jahr vor dem späten 19. Jahrhundert darstellte, und es scheint, als würde es Unfälle wie die falsche Kodierung von 2011 als 11 fördern.

256voto

Iman Punkte 16668

datetime2 gewinnt in den meisten Aspekten außer (alte Anwendungen Kompatibilität)

  1. größer Wertebereich
  2. besser Genauigkeit
  3. kleiner Speicherplatz (wenn eine optionale benutzerdefinierte Genauigkeit angegeben wird)

SQL Date and time data types compare - datetime,datetime2,date,TIME

Bitte beachten Sie die folgenden Punkte

  • Syntax
    • datetime2[(Sekundenbruchteile Genauigkeit=> Siehe unter Speichergröße)]
  • Präzision, Maßstab
    • 0 bis 7 Stellen, mit einer Genauigkeit von 100ns.
    • Die Standardpräzision beträgt 7 Stellen.
  • Speichergröße
    • 6 Bytes bei einer Genauigkeit von weniger als 3;
    • 7 Bytes für die Genauigkeit 3 und 4.
    • Alle anderen Präzisionen 8 Bytes benötigen .
  • DateTime2(3) haben die gleiche Anzahl von Ziffern wie DateTime, benötigen aber 7 Byte Speicherplatz anstelle von 8 Byte ( SQLHINTS- DateTime vs. DateTime2 )
  • Weitere Informationen finden Sie unter datetime2(Transact-SQL MSDN Artikel)

Bildquelle: MCTS-Schulungspaket zum Selbststudium (Prüfung 70-432): Microsoft® SQL Server® 2008 - Implementierung und Wartung Kapitel 3: Tabellen -> Lektion 1: Tabellen erstellen -> Seite 66

8 Stimmen

Danke für den Hinweis auf die Statistik, +1 dafür, datetime2 ist genial(Gewinner)

2 Stimmen

@Iman Abidi: Laut dem Kommentar von Oskar Berggren vom 10. September 2014 um 15:51 Uhr zum Artikel "SQLHINTS- DateTime Vs DateTime2", auf den Sie verwiesen haben: "datetime2(3) ist NICHT das Gleiche wie datetime. Sie haben die gleiche Anzahl von Ziffern, aber die Genauigkeit von datetime ist 3,33ms, während die Genauigkeit von datetime2(3) 1ms ist."

1 Stimmen

@PankajParkar: Woah, nicht so schnell. Sie sollten sich den Abschnitt "Nachteile" in meiner Antwort vom 7.10.17 unten ansehen.

117voto

EBarr Punkte 11598

Ich stimme mit @marc_s und @Adam_Poward überein - DateTime2 ist die bevorzugte Methode für die Zukunft. Es hat einen breiteren Bereich von Daten, höhere Präzision und verwendet gleich oder weniger Speicher (je nach Präzision).

Eine Sache wurde in der Diskussion jedoch übersehen...
@Marc_s erklärt: Both types map to System.DateTime in .NET - no difference there . Das ist richtig, das Gegenteil ist jedoch nicht der Fall ...und es ist wichtig, wenn Sie nach Datumsbereichen suchen (z. B. "Suche alle Datensätze, die am 5.5.2010 geändert wurden").

.NETs Version von Datetime hat eine ähnliche Reichweite und Präzision wie DateTime2 . Bei der Abbildung einer .net Datetime bis hin zum alten SQL DateTime eine implizite Rundung erfolgt . Das alte SQL DateTime ist auf 3 Millisekunden genau. Das bedeutet, dass 11:59:59.997 ist dem Ende des Tages so nahe wie möglich. Alles, was darüber liegt, wird auf den nächsten Tag aufgerundet.

Versuchen Sie dies:

declare @d1 datetime   = '5/5/2010 23:59:59.999'
declare @d2 datetime2  = '5/5/2010 23:59:59.999'
declare @d3 datetime   = '5/5/2010 23:59:59.997'
select @d1 as 'IAmMay6BecauseOfRounding', @d2 'May5', @d3 'StillMay5Because2msEarlier'

Die Vermeidung dieser impliziten Rundung ist ein wichtiger Grund für den Wechsel zu DateTime2. Die implizite Rundung von Daten führt eindeutig zu Verwirrung:

17 Stimmen

Sie können diese Rundung auch vermeiden, indem Sie nicht versuchen, das "Ende" eines Tages zu finden. >= 5. Mai UND < 6. Mai ist viel sicherer und funktioniert bei allen Datums-/Zeittypen (außer TIME natürlich). Vermeiden Sie außerdem regionale, zweideutige Formate wie m/d/yyyy.

2 Stimmen

@AaronBertrand - ich stimme Ihnen vollkommen zu, aber angesichts der vielen Fragen, die wir zu diesem Thema haben, schien es mir eine Beschreibung wert.

2 Stimmen

Warum sind Sie von 20100505 à 5/5/2010 ? Das erste Format funktioniert mit jeder Region in SQL Server. Das zweite Format wird nicht funktionieren: SET LANGUAGE French; SELECT Convert(datetime, '1/7/2015') oops: 2015-07-01 00:00:00.000

30voto

Tom Punkte 802

In fast allen Antworten und Kommentaren wurde viel über die Vorteile und wenig über die Nachteile gesprochen. Hier ist eine Zusammenfassung aller Vor- und Nachteile bis jetzt plus einige entscheidende Nachteile (in #2 unten), die ich nur einmal oder gar nicht erwähnt gesehen habe.

  1. PROS:

1.1. Stärkere ISO-Konformität (ISO 8601) (obwohl ich nicht weiß, wie dies in der Praxis zum Tragen kommt).

1.2. Größerer Bereich (1/1/0001 bis 31.12.9999 gegenüber 1/1/1753-12.31.9999) (obwohl der zusätzliche Bereich, alles vor dem Jahr 1753, wahrscheinlich nicht verwendet wird, außer z. B. in historischen, astronomischen, geologischen usw. Anwendungen).

1.3. Dies entspricht genau dem Bereich von .NET's DateTime Bereich des Typs (obwohl beide ohne besondere Kodierung hin und her 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 aka 0,000,000,1 Sek. vs. 3,33 Millisekunden aka 0,003,33 Sek.) (obwohl die zusätzliche Präzision wahrscheinlich nicht genutzt wird, außer z.B. in technischen/wissenschaftlichen Anwendungen).

1.5. Wenn konfiguriert für ähnlich (wie in 1 Millisekunde und nicht "gleich" (wie in 3,33 Millisekunden), wie Iman Abidi behauptet hat) Präzision als DateTime (7 vs. 8 Bytes), aber dann geht natürlich der Präzisionsvorteil verloren, der wahrscheinlich einer der beiden am meisten angepriesenen Vorteile ist (der andere ist die Reichweite), auch wenn er wahrscheinlich nicht benötigt wird.)

  1. CONS:

2.1. Bei der Übergabe eines Parameters an eine .NET SqlCommand müssen Sie angeben System.Data.SqlDbType.DateTime2 wenn Sie möglicherweise einen Wert außerhalb des SQL-Servers übergeben DateTime Bereich und/oder die Genauigkeit, da sie standardmäßig auf System.Data.SqlDbType.DateTime .

2.2. Kann nicht implizit / einfach in einen numerischen Fließkommawert (Anzahl der Tage seit dem Mindestdatum) konvertiert werden, um in SQL Server-Ausdrücken mit numerischen Werten und Operatoren Folgendes damit zu tun:

2.2.1. die Anzahl der Tage oder Teiltage addieren oder subtrahieren. Anmerkung: Mit DateAdd Die Funktion als Workaround ist nicht trivial, wenn man mehrere oder gar alle Teile der Datumszeit berücksichtigen muss.

2.2.2. für die Berechnung des "Alters" die Differenz zwischen zwei Datumszeitpunkten nehmen. Hinweis: Sie können nicht einfach die SQL Server-Funktion DateDiff Funktion, da diese keine Berechnungen durchführt age wie die meisten Leute erwarten würden, dass, wenn die beiden Datumszeiten zufällig eine Kalender/Uhrzeit-Datumszeit-Grenze der angegebenen Einheiten kreuzen, wenn auch nur für einen winzigen Bruchteil dieser Einheit, es die Differenz als 1 dieser Einheit vs. 0 zurückgeben wird. DateDiff en Day von zwei Datumszeiten, die nur 1 Millisekunde auseinander liegen, ergibt 1 vs. 0 (Tage), wenn diese Datumszeiten an unterschiedlichen Kalendertagen liegen (z.B. "1999-12-31 23:59:59.9999999" und "2000-01-01 00:00:00.0000000"). Die gleichen Datumszeiten mit einer Differenz von 1 Millisekunde werden, wenn sie so verschoben werden, dass sie keinen Kalendertag überschneiden, einen "DateDiff" in Day von 0 (Tagen).

2.2.3. nehmen die Avg von Datumszeiten (in einer Aggregatabfrage) durch einfaches Konvertieren in "Float" und dann wieder zurück in DateTime .

HINWEIS: Zum Konvertieren DateTime2 in eine numerische Zahl umzuwandeln, müssen Sie etwas wie die folgende Formel verwenden, die immer noch davon ausgeht, dass Ihre Werte nicht kleiner als das Jahr 1970 sind (was bedeutet, dass Sie den gesamten zusätzlichen Bereich plus weitere 217 Jahre verlieren). Hinweis: Möglicherweise können Sie die Formel nicht einfach anpassen, um den zusätzlichen Bereich zu berücksichtigen, da es zu Problemen mit dem numerischen Überlauf kommen kann.

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önnen Sie auch Cast a DateTime zuerst (und gegebenenfalls wieder zurück zu DateTime2 ), aber Sie würden die Vorteile von Präzision und Reichweite (alle vor dem Jahr 1753) verlieren DateTime2 vs. DateTime die prolly die 2 größten und auch zur gleichen Zeit prolly die 2 am wenigsten wahrscheinlich benötigt werden, was die Frage aufwirft, warum es verwenden, wenn Sie die implizite / einfache Konvertierungen in Gleitkommazahlen (# von Tagen) für Addition / Subtraktion / "Alter" (vs. DateDiff ) / Avg Calcs profitieren, was meiner Erfahrung nach ein großer Vorteil ist.

Übrigens, die Avg von Datum-Zeiten ist (oder zumindest debe a) Neben der Verwendung, um die durchschnittliche Dauer zu erhalten, wenn Datumszeiten (da eine gemeinsame Basis-Datumszeit) verwendet werden, um die Dauer darzustellen (eine gängige Praxis), b) ist es auch nützlich, eine Dashboard-artige Statistik darüber zu erhalten, was die durchschnittliche Datumszeit in der Datumszeitspalte eines Bereichs / einer Gruppe von Zeilen ist. c) Ein Standard (oder zumindest debe Eine (Standard-)Ad-hoc-Abfrage zur Überwachung / Fehlersuche bei Werten in einer Spalte, die möglicherweise nicht mehr gültig sind und / oder veraltet werden müssen, besteht darin, für jeden Wert die Anzahl des Auftretens und (falls verfügbar) die Min , Avg y Max Datums- und Zeitstempel, die mit diesem Wert verbunden sind.

1 Stimmen

Wie die konträre Sichtweise - sie zeigt die c#-Seite der Gleichung auf. Kombiniert mit all den anderen "Pros" wird es den Menschen ermöglichen, eine gute Wahl zu treffen, wo sie ihre Schmerzen nehmen wollen.

1 Stimmen

@EBarr: Nur der Teil Cons #1 meiner "'konträren Sichtweise'" "weist auf die c#-Seite der Gleichung hin". Der Rest (Cons #'s 2.2.1 - 2.2.3), die wie ich sagte, sind die weitaus wahrscheinlicher benötigten Vorteile (von DateTime ), beziehen sich alle auf Auswirkungen auf SQL Server-Abfragen und -Anweisungen.

0 Stimmen

Zu 2.2.1 - es gilt als unsichere Praxis, mit Datumsangaben zu rechnen, und der bevorzugte Weg ist immer, DateAdd und verwandte Funktionen zu verwenden. Dies ist die beste Praxis. Es gibt schwerwiegende Nachteile bei der Datumsarithmetik, nicht zuletzt, dass sie bei den meisten Datumsarten nicht funktioniert. Ein paar Artikel: sqlservercentral.com/blogs/ sqlblog.org/2011/09/20/…

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X