Wir können Datums- und Zeitinformationen auf verschiedene Arten speichern. Was ist die beste Methode zum Speichern von DateTime-Informationen?
Speichern von Datum und Uhrzeit in 2 separaten Spalten oder einer Spalte mit DateTime ?
Können Sie erklären, warum dieser Ansatz besser ist?
(Link zu MySQL-Dokumenten als Referenz. Die Frage ist allgemein und nicht spezifisch für MySQL.)
Datums- und Zeittypen: Datum und Zeit
database-design
datetime
julianisch
quelle
quelle
date,time
mit,group by date
aber nicht für einen Indexdatetime
mit verwendet werdengroup by cast(datetime as date)
, obwohl es die gewünschte Reihenfolge liefern würde.Antworten:
Das Speichern der Daten in einer einzelnen Spalte ist die bevorzugte Methode, da sie untrennbar miteinander verbunden sind. Ein Zeitpunkt ist eine einzelne Information, nicht zwei.
Eine übliche Methode zum Speichern von Datums- / Zeitdaten, die von vielen Produkten "hinter den Kulissen" verwendet werden, besteht darin, sie in einen Dezimalwert umzuwandeln, wobei "Datum" der ganzzahlige Teil des Dezimalwerts und "Zeit" der Bruchteil ist Wert. So wird zwischen 1900-01-01 00:00:00 als 0,0 und dem 20. September 2016 zwischen 9:34:00 als 42631.39861 gespeichert. 42631 ist die Anzahl der Tage seit dem 01.01.1900. .39861 ist die Zeit, die seit Mitternacht vergangen ist. Verwenden Sie dazu nicht direkt einen Dezimaltyp, sondern einen expliziten Datums- / Zeittyp. Mein Punkt hier ist nur eine Illustration.
Wenn Sie die Daten in zwei separaten Spalten speichern, müssen Sie beide Spaltenwerte immer dann kombinieren, wenn Sie sehen möchten, ob ein bestimmter Zeitpunkt früher oder später als der gespeicherte Wert liegt.
Wenn Sie die Werte separat speichern, werden Sie ausnahmslos auf "Bugs" stoßen, die schwer zu erkennen sind. Nehmen wir zum Beispiel folgendes:
Im obigen Code erstellen wir eine Testtabelle, füllen sie mit zwei Werten und führen dann eine einfache Abfrage für diese Daten durch. Die erste
SELECT
gibt beide Zeilen zurück, die zweiteSELECT
gibt jedoch nur eine einzelne Zeile zurück, was möglicherweise nicht das gewünschte Ergebnis ist:Die richtige Methode zum Filtern eines Datums- / Zeitbereichs, in dem sich die Werte in separaten Spalten befinden, wie von @ypercube in Kommentaren hervorgehoben, lautet:
Wenn Sie die Zeitkomponente zu Analysezwecken getrennt benötigen , können Sie eine berechnete, dauerhafte Spalte für den Zeitanteil des Werts hinzufügen:
Die persistierte Spalte könnte dann indiziert werden, um schnelle Sortierungen usw. nach Tageszeit zu ermöglichen.
Wenn Sie das Datum und die Uhrzeit für Anzeigezwecke in zwei Felder aufteilen möchten, sollten Sie beachten, dass die Formatierung auf dem Client und nicht auf dem Server erfolgen sollte.
quelle
Ich werde eine abweichende Meinung zu den anderen Antworten abgeben.
Wenn sowohl die Datums- als auch die Zeitkomponente zusammen benötigt werden, dh ein Eintrag ungültig ist, wenn er einen, aber keinen anderen enthält (oder in einem, aber keinem anderen, NULL ist), ist das Speichern in einer einzelnen Spalte aus den in anderen angegebenen Gründen sinnvoll Antworten.
Es kann jedoch vorkommen, dass eine oder beide Komponenten einzeln optional sind. In diesem Fall wäre es falsch, es in einer einzelnen Spalte zu speichern. Wenn Sie dies tun, müssen Sie NULL-Werte auf eine beliebige Weise darstellen, z. B. indem Sie die Zeit als 00:00:00 speichern.
Hier einige Beispiele:
Sie erfassen Fahrzeugfahrten für Meilensteuerabzüge. Die genaue Uhrzeit der Reise zu kennen, wäre hilfreich. Wenn ein Mitarbeiter sie jedoch nicht notiert und vergessen hat, sollte das Datum dennoch selbst aufgezeichnet werden (erforderliches Datum, optionale Uhrzeit).
Sie führen eine Umfrage durch, um herauszufinden, wann die Leute zu Mittag essen, und Sie bitten die Teilnehmer, ein Formular mit einer Stichprobe ihrer Mittagspausen, einschließlich Daten, auszufüllen. Einige machen sich nicht die Mühe, das Datum einzugeben, und Sie möchten die Daten nicht verwerfen, da dies die Zeit ist, die Ihnen wirklich am Herzen liegt (optionales Datum, erforderliche Zeit).
Siehe diese verwandte Frage für alternative Ansätze.
quelle
Ich bevorzuge es immer, das als eine einzelne Spalte zu speichern, es sei denn, es gibt eine bestimmte Geschäfts / Anwendungsnachfrage. Unten sind meine Punkte -
quelle
In SQL Server ist es am besten, DataTime als ein Feld zu speichern. Wenn Sie einen Index für die DataTime-Spalte erstellen, kann dieser als Datumssuche und als DateTime-Suche verwendet werden. Wenn Sie also alle Datensätze einschränken müssen, die für das bestimmte Datum existieren, können Sie den Index trotzdem verwenden, ohne etwas Besonderes tun zu müssen. Wenn Sie einen Zeitabschnitt abfragen müssen, können Sie nicht denselben Index verwenden. Wenn Sie also einen Geschäftsfall haben, bei dem die Uhrzeit wichtiger ist als DateTime, sollten Sie ihn separat speichern, da Sie ihn erstellen müssen einen Index dafür und verbessern die Leistung.
quelle
Tatsächlich ist es schade, dass es hierfür keinen standardmäßigen Cross-DBMS-Typ gibt (wie INT und VARCHAR für Ganzzahlen und Zeichenfolgenwerte). Die beiden datenbankübergreifenden Ansätze, die ich bisher kennengelernt habe, verwenden VARCHAR / CHAR-Spalten, um DataTime-Werte als Zeichenfolgen zu speichern, die gemäß dem ISO 8601-Standard (praktischer, lesbarer) formatiert sind, und verwenden BIGINT, um sie als POSIX-Zeitstempel zu speichern (mehr gespeichert) effizient, schneller, einfacher mathematisch zu manipulieren).
quelle
timestamp
, das definiert der SQL-Standard. Das Speichern von Zeitstempeln als Zeichenfolgen ist ein sehr schlechter RatNach dem Lesen einiger Dinge scheint die UTC-Unix-Zeit in BIGINT die optimale Lösung zu sein. TZDB- Zeitzonen-ID in VARCHAR zur Speicherung der Zeitzone, falls erforderlich. Ein paar Argumente:
TIMESTAMP und DATETIME führen im Hintergrund einige spielerische Konvertierungen durch, die komplex und unklar erscheinen. Der Server wechselt von der Ortszeit zu UTC oder zur Serverzeit und manchmal zurück oder nicht. Ein Haufen versteckter Unkosten für jede Funktion.
BIGINT (8kb) ist mindestens so leicht oder leichter als DECIMAL, das für den xxxxxx.xxxxxx-Formatspeicher erforderlich ist, der von MySQL praktisch als zwei INTs + irgendetwas gespeichert wird . Und es reicht, um Jahrhunderte vorher zu lagern.
Nahezu alle wichtigen Programmiersprachen verfügen über Bibliotheken mit Standardfunktionen für die Arbeit mit Unix-Zeit.
Mathematische Operationen mit BIGINT sollten auf jeder Hardware so schnell oder so schnell wie nichts anderes sein.
Natürlich ist all das für große, internationale Projekte relevant. Für etwas Kleines scheint es gut genug zu sein, mit dem Standardformat des gewählten Frameworks zu arbeiten.
quelle
timestamp
Spalte finden keine "Gimmicky Conversions" statt (auf Datenbankebene) undtimestamp with time zone
dies ist gut dokumentiert und in den Handbüchern erklärt (zumindest für Oracle und Postgres)