Ich möchte Zeiten in einer Datenbanktabelle speichern, muss aber nur die Stunden und Minuten speichern. Ich weiß, ich könnte einfach DATETIME verwenden und die anderen Komponenten des Datums ignorieren, aber wie geht das am besten, ohne mehr Informationen zu speichern, als ich tatsächlich benötige?
sql-server
database
database-design
datetime
Matthew Dresser
quelle
quelle
Antworten:
Sie können es als Ganzzahl der Anzahl der Minuten nach Mitternacht speichern:
z.B.
Sie müssten jedoch Code schreiben, um die Zeit wiederherzustellen, aber das sollte nicht schwierig sein.
quelle
Wenn Sie SQL Server 2008+ verwenden, berücksichtigen Sie den
TIME
Datentyp. SQLTeam-Artikel mit weiteren Verwendungsbeispielen.quelle
Ich bitte Sie, stattdessen zwei DATETIME-Werte zu verwenden, die mit event_start und event_end gekennzeichnet sind .
Zeit ist ein komplexes Geschäft
Der größte Teil der Welt hat inzwischen das auf Verweigerung basierende metrische System für die meisten Messungen zu Recht oder zu Unrecht übernommen. Dies ist insgesamt gut, da wir uns zumindest alle einig sein können, dass ag, ein ml, ein Kubikzentimeter ist. Zumindest ungefähr so. Das metrische System weist viele Mängel auf, ist aber zumindest international durchweg fehlerhaft.
Mit der Zeit haben wir jedoch; 1000 Millisekunden in einer Sekunde, 60 Sekunden bis eine Minute, 60 Minuten bis eine Stunde, 12 Stunden für jeden halben Tag, ungefähr 30 Tage pro Monat, die je nach Monat und sogar Jahr variieren. Jedes Land hat seine Zeit von anderen versetzt Die Art und Weise, wie die Zeit in jedem Land formatiert wird, variiert.
Es ist viel zu verdauen, aber das lange und kurze ist für ein so komplexes Szenario unmöglich, eine einfache Lösung zu finden.
Einige Ecken können geschnitten werden, aber es gibt solche, bei denen es klüger ist, dies nicht zu tun
Obwohl die beste Antwort hier darauf hindeutet, dass Sie eine Ganzzahl von Minuten nach Mitternacht speichern, scheint dies durchaus vernünftig zu sein, habe ich gelernt, dies auf die harte Tour zu vermeiden.
Die Gründe für die Implementierung von zwei DATETIME-Werten liegen in einer Erhöhung der Genauigkeit, Auflösung und Rückmeldung.
Diese sind alle sehr praktisch, wenn das Design unerwünschte Ergebnisse liefert.
Speichere ich mehr Daten als erforderlich?
Es mag zunächst so aussehen, als würden mehr Informationen gespeichert, als ich benötige, aber es gibt einen guten Grund, diesen Treffer zu erzielen.
Das Speichern dieser zusätzlichen Informationen spart mir auf lange Sicht fast immer Zeit und Mühe, da ich unweigerlich feststelle, dass jemand, der erfährt, wie lange etwas gedauert hat, zusätzlich wissen möchte, wann und wo die Veranstaltung stattgefunden hat.
Es ist ein riesiger Planet
In der Vergangenheit habe ich mich schuldig gemacht, ignoriert zu haben, dass es neben meinen eigenen noch andere Länder auf diesem Planeten gibt. Es schien damals eine gute Idee zu sein, aber dies hat IMMER zu Problemen, Kopfschmerzen und späterer Zeitverschwendung geführt. Berücksichtigen Sie IMMER alle Zeitzonen.
C #
Eine DateTime lässt sich gut in eine Zeichenfolge in C # rendern. Die ToString-Methode (String Format) ist kompakt und einfach zu lesen.
Z.B
SQL Server
Auch wenn Sie Ihre Datenbank separat von Ihrer Anwendungsoberfläche lesen, ist dateTimes auf einen Blick lesbar und die Durchführung von Berechnungen ist unkompliziert.
Z.B
ISO8601 Datumsstandard
Wenn Sie SQLite verwenden, haben Sie dies nicht. Verwenden Sie stattdessen ein Textfeld und speichern Sie es im ISO8601-Format, z.
2013-01-27T12: 30: 00 + 0000
Anmerkungen:
Dies verwendet die 24-Stunden-Uhr *
Der Zeitversatzteil (oder +0000) der ISO8601 wird direkt dem Längengradwert einer GPS-Koordinate zugeordnet (ohne Berücksichtigung der Sommerzeit oder landesweit).
Z.B
... wobei ± sich auf die Ost- oder Westrichtung bezieht.
Es lohnt sich daher zu überlegen, ob es sich lohnt, Längen-, Breiten- und Höhenangaben zusammen mit den Daten zu speichern. Dies variiert in der Anwendung.
ISO8601 ist ein internationales Format.
Das Wiki ist sehr gut für weitere Details unter http://en.wikipedia.org/wiki/ISO_8601 .
Das Datum und die Uhrzeit werden in internationaler Zeit gespeichert und der Versatz wird abhängig davon aufgezeichnet, wo auf der Welt die Uhrzeit gespeichert wurde.
Nach meiner Erfahrung muss immer das vollständige Datum und die vollständige Uhrzeit gespeichert werden, unabhängig davon, ob ich denke, dass dies der Fall ist, wenn ich mit dem Projekt beginne. ISO8601 ist eine sehr gute und zukunftssichere Methode.
Zusätzliche Beratung kostenlos
Es lohnt sich auch, Ereignisse wie eine Kette zusammenzufassen. Wenn Sie beispielsweise ein Rennen aufzeichnen, kann das gesamte Ereignis nach Racer, Race_Circuit, Circuit_checkpoints und Circuit_Laps gruppiert werden.
Nach meiner Erfahrung ist es auch ratsam zu identifizieren, wer die Aufzeichnung gespeichert hat. Entweder als separate Tabelle, die über den Trigger ausgefüllt wird, oder als zusätzliche Spalte in der Originaltabelle.
Je mehr Sie eingeben, desto mehr steigen Sie aus
Ich verstehe den Wunsch, möglichst sparsam mit dem Platz umzugehen, vollkommen, aber ich würde dies selten auf Kosten des Informationsverlusts tun.
Als Faustregel für Datenbanken gilt, wie der Titel schon sagt, dass eine Datenbank nur so viel aussagen kann, wie sie Daten enthält, und dass es sehr kostspielig sein kann, historische Daten erneut zu durchsuchen und Lücken zu schließen.
Die Lösung besteht darin, es beim ersten Mal richtig zu machen. Dies ist sicherlich leichter gesagt als getan, aber Sie sollten jetzt einen tieferen Einblick in das effektive Datenbankdesign haben und anschließend eine viel bessere Chance haben, es beim ersten Mal richtig zu machen.
Je besser Ihr ursprüngliches Design ist, desto kostengünstiger sind die Reparaturen später.
Ich sage das alles nur, denn wenn ich in die Vergangenheit reisen könnte, würde ich es mir sagen, wenn ich dort ankomme.
quelle
Speichern Sie einfach eine reguläre Datums- und Uhrzeitangabe und ignorieren Sie alles andere. Warum zusätzliche Zeit damit verbringen, Code zu schreiben, der ein Int lädt, bearbeitet und in eine Datums- / Uhrzeitangabe konvertiert, wenn Sie nur eine Datums- / Uhrzeitangabe laden könnten?
quelle
DATETIME
Datentyp benötigt 4 Byte zum Speichern, während ein DatentypSMALLINT
beispielsweise nur ein Viertel davon benötigt. Kein großer Unterschied, wenn Sie nur einige tausend Zeilen haben, aber wenn Sie wie viele Unternehmen viele Millionen Zeilen haben, ist Ihre Platzersparnis erheblich.Da Sie es unter SQL Server 2008 nicht erwähnt haben, können Sie den Datentyp time verwenden, andernfalls Minuten seit Mitternacht
quelle
SQL Server speichert die Zeit tatsächlich als Bruchteil eines Tages. Zum Beispiel ist 1 ganzer Tag = Wert von 1. 12 Stunden ist ein Wert von 0,5.
Wenn Sie den Zeitwert ohne Verwendung eines DATETIME-Typs speichern möchten, entspricht das Speichern der Zeit in Dezimalform diesen Anforderungen und vereinfacht gleichzeitig die Konvertierung in eine DATETIME.
Beispielsweise:
Das Speichern des Werts als DECIMAL (9,9) würde 5 Bytes verbrauchen. Wenn jedoch die Genauigkeit nicht von größter Bedeutung ist, würde ein REAL nur 4 Bytes verbrauchen. In beiden Fällen kann die aggregierte Berechnung (dh die mittlere Zeit) leicht anhand numerischer Werte berechnet werden, nicht jedoch anhand von Daten- / Zeittypen.
quelle
Ich würde sie in eine ganze Zahl (HH * 3600 + MM * 60) konvertieren und so speichern. Kleine Speichergröße und dennoch einfach zu handhaben.
quelle
Wenn Sie MySQL verwenden, verwenden Sie einen Feldtyp von TIME und die zugehörige Funktionalität, die mit TIME geliefert wird.
00:00:00 ist das Standard-Unix-Zeitformat.
Wenn Sie jemals zurückblicken und die Tabellen von Hand überprüfen müssen, können Ganzzahlen verwirrender sein als ein tatsächlicher Zeitstempel.
quelle
Versuchen Sie es mit smalldatetime. Es gibt Ihnen möglicherweise nicht das, was Sie wollen, aber es hilft Ihnen bei Ihren zukünftigen Anforderungen bei Datums- / Zeitmanipulationen.
quelle
Sind Sie sicher, dass Sie immer nur die Stunden und Minuten brauchen werden? Wenn Sie damit etwas Sinnvolles tun möchten (wie zum Beispiel Zeitspannen zwischen zwei solchen Datenpunkten berechnen), wenn Sie keine Informationen über Zeitzonen und Sommerzeit haben, kann dies zu falschen Ergebnissen führen. Zeitzonen gelten in Ihrem Fall möglicherweise nicht, die Sommerzeit jedoch mit Sicherheit.
quelle
Anstelle von Minuten nach Mitternacht speichern wir es als 24-Stunden-Uhr als SMALLINT.
09:12 = 912 14:15 = 1415
Bei der Rückkonvertierung in eine "vom Menschen lesbare Form" fügen wir einfach einen Doppelpunkt ein: "zwei Zeichen von rechts. Linkes Feld mit Nullen, falls erforderlich. Speichert die Mathematik in jeder Richtung und verwendet einige weniger Bytes (im Vergleich zu varchar). Außerdem wird erzwungen, dass der Wert numerisch (und nicht alphanumerisch) ist.
Ziemlich doof ... es sollte schon seit vielen Jahren einen TIME-Datentyp in MS SQL geben, IMHO ...
quelle
Ich denke, Sie fragen nach einer Variablen, die Minuten als Zahl speichert. Dies kann mit den verschiedenen Arten von Ganzzahlvariablen erfolgen:
Dann können Sie dies in Ihrem Programm einfach in der gewünschten Form anzeigen, indem Sie Folgendes berechnen:
Ein Problem tritt auf, wenn Sie die Verwendung von Effizienz anfordern. Wenn Sie jedoch wenig Zeit haben, verwenden Sie einfach ein nullbares BigInt, um Ihren Minutenwert zu speichern.
Ein Wert von null bedeutet, dass die Zeit noch nicht aufgezeichnet wurde.
Jetzt werde ich in Form einer Rundreise in den Weltraum erklären.
Leider speichert eine Tabellenspalte nur einen einzigen Typ. Daher müssen Sie für jeden Typ nach Bedarf eine neue Tabelle erstellen.
Beispielsweise:
Wenn MinutesInput = 0 .. 255, verwenden Sie TinyInt (Konvertieren wie oben beschrieben).
Wenn MinutesInput = 256 .. 131071, verwenden Sie SmallInt (Hinweis: Der Min-Wert von SmallInt beträgt -32.768. Negieren Sie daher 32768 und fügen Sie ihn hinzu, wenn Sie Werte speichern und abrufen, um den gesamten Bereich zu nutzen, bevor Sie wie oben konvertieren).
Wenn MinutesInput = 131072 .. 8589934591, verwenden Sie Int (Hinweis: Negieren Sie und fügen Sie bei Bedarf 2147483648 hinzu).
Wenn MinutesInput = 8589934592 .. 36893488147419103231, verwenden Sie BigInt (Hinweis: Fügen Sie nach Bedarf 9223372036854775808 hinzu und negieren Sie es).
Wenn MinutesInput> 36893488147419103231, würde ich persönlich VARCHAR (X) verwenden, um X nach Bedarf zu erhöhen, da ein Zeichen ein Byte ist. Ich werde diese Antwort zu einem späteren Zeitpunkt noch einmal überprüfen müssen, um sie vollständig zu beschreiben (oder vielleicht kann ein anderer Stackoverflowee diese Antwort beenden).
Da für jeden Wert zweifellos ein eindeutiger Schlüssel erforderlich ist, ist die Effizienz der Datenbank nur dann ersichtlich, wenn der Bereich der gespeicherten Werte eine gute Mischung zwischen sehr klein (nahe 0 Minuten) und sehr hoch (größer als 8589934591) darstellt.
Bis die gespeicherten Werte tatsächlich eine Zahl größer als 36893488147419103231 erreichen, können Sie auch eine einzelne BigInt-Spalte zur Darstellung Ihrer Minuten verwenden, da Sie kein Int für eine eindeutige Kennung und ein anderes int zum Speichern des Minutenwerts verschwenden müssen.
quelle
Die Zeitersparnis im UTC-Format kann besser helfen, wie Kristen vorgeschlagen hat.
Stellen Sie sicher, dass Sie die 24-Stunden-Uhr verwenden, da in UTC kein Meridian AM oder PM verwendet wird.
Beispiel:
Es ist immer noch vorzuziehen, das vierstellige Standardformat zu verwenden.
quelle
Speichern Sie die
ticks
alslong
/bigint
, die derzeit in Millisekunden gemessen werden. Der aktualisierte Wert kann anhand desTimeSpan.TicksPerSecond
Werts ermittelt werden.Die meisten Datenbanken haben einen DateTime-Typ, der die Uhrzeit automatisch als Ticks hinter den Kulissen speichert. Bei einigen Datenbanken, z. B. SqlLite, kann das Speichern von Ticks eine Möglichkeit sein, das Datum zu speichern.
Die meisten Sprachen ermöglichen die einfache Konvertierung von
Ticks
→TimeSpan
→Ticks
.Beispiel
In C # wäre der Code:
Beachten Sie jedoch, dass im Fall von SqlLite nur eine geringe Anzahl verschiedener Typen angeboten wird.
INT
,REAL
UndVARCHAR
es wird notwendig sein , die Anzahl der Ticks als String oder zwei zu speichernINT
Zellen kombiniert. Dies liegt daran, dass anINT
eine vorzeichenbehaftete 32-Bit-Nummer ist, währendBIGINT
es sich um eine vorzeichenbehaftete 64-Bit-Nummer handelt.Hinweis
Meine persönliche Präferenz wäre es jedoch, Datum und Uhrzeit als
ISO8601
Zeichenfolge zu speichern .quelle
IMHO, was die beste Lösung ist, hängt in gewissem Maße davon ab, wie Sie Zeit im Rest der Datenbank (und im Rest Ihrer Anwendung) speichern.
Persönlich habe ich mit SQLite gearbeitet und versucht, immer Unix-Zeitstempel zum Speichern der absoluten Zeit zu verwenden. Wenn ich mich also mit der Tageszeit befasse (wie Sie es wünschen), mache ich das, was Glen Solsberry in seiner Antwort schreibt, und speichere die Anzahl der Sekunden seit Mitternacht
Bei diesem allgemeinen Ansatz sind die Leute (einschließlich mir!), Die den Code lesen, weniger verwirrt, wenn ich überall den gleichen Standard verwende
quelle