In einer typischen Webanwendung werden Datumsangaben aus der stark typisierten Datenbankebene abgerufen (z. B. in c # als System.DateTime im Gegensatz zu System.String).
Wenn ein Datum als Zeichenfolge ausgedrückt werden muss (z. B. auf einer Seite angezeigt werden soll), erfolgt die Konvertierung von DateTime in Zeichenfolge in der Präsentationsschicht.
Warum ist das? Warum ist es eine schlechte Sache, die DateTime in eine Zeichenfolge auf der Datenbankebene zu konvertieren?
Siehe auch die hitzige Debatte im Chat und die ursprüngliche Frage, die all dies ausgelöst hat .
database
sql
formatting
John Wu
quelle
quelle
Antworten:
Dates, DateTimes und wirklich alle anderen typisierten Objekte sollten im Allgemeinen in ihrem korrekt typisierten Format belassen werden, bis sie in einen anderen Typ umgewandelt werden müssen - insbesondere, wenn dieser Typ für Menschen lesbar ist und insbesondere, wenn es sich um ein verlustbehaftetes Objekt handelt. One-Way-Art der Konvertierung.
Warum? Da davon ausgegangen wird, dass der Typ viele praktische Funktionen bietet, wie z. B. die Prüfung der Gleichheit, Addition und Subtraktion, Vergleich (größer als, kleiner als), Zeitzonen- und Gebietsschemafunktionalität (besonders wichtig für alles, was mit Zeit zu tun hat). usw. Wenn Sie Amerikaner und das Format "Month Day [th], Year" sowie den gängigen britischen Stil "Day Month Year" oder den ISO-Standard "Year-Month-Day" unterstützen möchten? Was würden Sie tun, wenn es sich um eine Zeichenfolge handeln würde und Sie diese Änderung vornehmen müssten, um sie wieder in ein Datum umzuwandeln? Puh, nein danke - es gibt so viele Übel und abscheuliche Bugs, die man am besten komplett vermeiden kann.
Insbesondere haben Sie die gestufte Architektur erwähnt, bei der die Präsentationsschicht später von den Daten getrennt wird. Dies ist eigentlich der andere wichtige Grund, ein Datum als Datum und nicht als Zeichenfolge zu übergeben. In welcher Zeichenfolgenformatierung soll das Datum eingegeben werden? Englisch, Chinesisch, mit oder ohne Sekunden / Millisekunden, vollständiger Monatsname oder Ziffern, möchten Sie später nach dem Datumsfeld sortieren (das Sortieren nach einer Zeichenfolge erfordert ein bestimmtes Zeichenfolgenformat, wenn es richtig funktionieren soll) usw.? Dies alles ist eine Frage der Präsentation - wie der Benutzer die Daten anzeigen sollte - und das Anordnen dieser Logik an einer anderen Stelle würde den Vorteil einer abgestuften Architektur an erster Stelle einschränken. Die Datenbank muss nicht wissen oder kümmern, wie Sie das Datum in Zukunft anzeigen möchten.
Schließlich verwenden fast alle komplexen Anwendungen (für die mehrstufige Architekturen vorgesehen sind), bei denen es um Zeit geht, unweigerlich Zeiten / Daten auf viele verschiedene Arten und oft auf allen verschiedenen Ebenen der Architektur. Die typisierten Objekte, die sich auf Zeiten und Daten beziehen, existieren aus einem wirklich guten Grund: Die Zeit selbst und insbesondere menschliche Kalendersysteme sind seltsam und hart. Letztendlich sind Zeiten und Datumsangaben keine Zeichenfolgen aus dem gleichen Grund, wie Ganzzahlen und Fließkommazahlen keine Zeichenfolgen sind, und es wird Ihr Leben nur erschweren, wenn Sie so tun, als wären es wirklich nur Anordnungen von Zeichen, weil sie es einfach nicht sind.
quelle
Why? Because it is assumed that the type provides you with lots of handy built in functionality
Meiner Meinung nach ist dies nur zweitrangig. Der wahre Grund ist, dass der Typ Ihnen sagt, was etwas ist . Ein Datum ist keine Zeichenfolge, sondern wird einfach in eine für Menschen lesbare Zeichenfolge übersetzt.Ich möchte den Typ kennen.
Es ist mir wirklich egal, ob Ihre Datenbank Informationen in einem String, einigen Ints oder Bytes speichert, denn letztendlich sind es sowieso immer Bytes. Diese Zeichenfolge, die mehr Speicherplatz beansprucht als in Ihrer Datenbank benötigt wird, stört mich nicht. Was mich stört, sind Daten wie diese:
11/10/2016
Und nicht zu wissen, ob das der elfte oder der zehnte Monat ist.
Aber es ist bestätigt, dass Sie sagen. Sicher, Sie haben es einem Validierungsprozess unterzogen. Das Datum ist vollkommen korrekt. Aber hier behalte ich diese Sache bei und alles was ich weiß ist, dass das Datum eine Zeichenkette ist. Ich kann dir nicht mal sagen, wann das ist.
"Zehnter November im zweitausendsechzehnten Jahr unseres Herrn."
Das ist eine Saite. Eine unserer Präsentationen benötigt es in diesem Format. Sie sagten, die Datenbank konvertiert alle Daten in Zeichenfolgen, oder? Viel Spaß dabei.
Die Aufgabe der Datenbank besteht darin, Daten zu speichern, die nicht vorhanden sind. Sicher, Sie könnten das in Strings machen, aber dann müssen Sie es analysieren, um es nützlich zu machen, es für andere Formate zu präsentieren. Durch die Speicherung in einer standardmäßigen, geparsten Form für jeden Typ, den die DB anbietet, sind wir so nah an der Präsentationsbereitschaft wie möglich, ohne eine Entscheidung über die Präsentation getroffen zu haben. Es ist mir wirklich egal, ob die DB diesen Typ mit einem String oder Ints oder Bytes unterstützt. Solange es weiß, was es tut.
Wenn Sie der Datenbank jedoch nicht mitteilen, dass es sich um ein Datum handelt, und ein Datum als Zeichenfolge speichern, wird eine Präsentation vorzeitig präsentiert und allen anderen vorgezogen. Dies zwingt alle anderen Moderatoren zum Parsen, bevor sie konvertieren. Nein, die Datenbank ist kein Teil der Präsentationsschicht. Bitten Sie nicht darum.
Ebenso ist die Präsentationsschicht nicht Teil der Datenbank, sodass es nicht ratsam ist, einen Bericht mit Datenbankdetails zu koppeln. Es ist weitaus robuster, auf Typen einzuwirken.
quelle
Gebietsschema
Die Konvertierung des Datums in eine Zeichenfolge für Präsentationszwecke erfordert die Kenntnis der Benutzereinstellungen, da genau dasselbe Datum für Benutzer in verschiedenen Ländereinstellungen im Allgemeinen unterschiedlich angezeigt werden sollte. Selbst wenn Sie ein einzelnes Gebietsschema in Ihrer Anwendung verwenden, sollte bei ordnungsgemäßem Verhalten das Gebietsschema der Anwendung anstelle des Datenbankservers verwendet werden. und es ist nicht garantiert, dass sie identisch sind, auch wenn sie in diesem Moment zufällig übereinstimmen.
Die Konvertierung von einem universellen Datums-Datentyp in eine länderspezifische Zeichenfolge sollte in der Präsentationsebene erfolgen, da diese Ebene weiß, wie diese Konvertierung durchgeführt werden soll.
quelle
Dies ist aus dem gleichen Grund unerwünscht, aus dem Sie keinen Typ blind in eine Zeichenfolge konvertieren möchten, sobald er die Anwendungsebene erreicht. Es ist sehr wahrscheinlich, dass Sie dieses Objekt in irgendeiner Weise verwenden möchten, bevor Sie es dem Benutzer präsentieren (wenn Sie es dem Benutzer überhaupt präsentieren). Stellen Sie sich für dieses Beispiel vor, Sie müssten eine Datumsberechnung für das Objekt durchführen. Es ist kein Nachteil, das Objekt nur in eine Zeichenfolge zu konvertieren, bevor Sie es anzeigen.
quelle
Typen gibt es aus einem Grund, wenn sie keinen Nutzen bringen würden, hätten wir sie nicht und würden sie nicht benutzen und hätten nur "den Typ" und alles wäre das. Sie sind nicht nur bequem, sondern tragen auch zur Sicherheit und Effizienz bei. Im Folgenden finden Sie eine Liste der Gründe, warum Sie Typen immer in ihrem ursprünglichen Format und nicht als Zeichenfolgen beibehalten sollten . Ich habe die
DateTime
meiste Zeit als Beispiel verwendet, aber die gleichen Prinzipien gelten für alle primitiven Typen wie Ganzzahlen, Dezimalzahlen, Binärzahlen usw.Datenspeicher
Einschränkungen
Geben Sie Constraint ein
In fast allen Datenspeichern können Einschränkungen für die Daten angegeben werden, einschließlich Typeinschränkungen. Einer der Hauptvorteile der Angabe einer
DateTime
Instanz besteht darin, dass die gespeicherten Daten auf diesen Typ beschränkt sind. Es ist niemals möglich, etwas anderes als eine Datumszeit einzugeben, unabhängig davon, wie die Daten in den Speicher eingefügt wurden. Letzteres ist wichtig für größere Systeme, in denen mehrere Prozesse direkt mit dem Geschäft interagieren. Dies schließt auch den Versuch ein, fehlerhafte Daten wie den 30. Februar (eines Jahres) hinzuzufügen, da der Februar nur 29 Tage pro Schaltjahr und 28 Tage für Nicht-Schaltjahre haben kann.Validierungsbeschränkungen
Es gibt auch Validierungsbeschränkungen, die im Datenspeicher implementiert werden können, z. B. das Sicherstellen, dass ein eingefügtes Datum das aktuelle Datum nicht überschreitet oder dass ein Startdatum vor einem Enddatum liegt.
Operationen
Die meisten Datenspeicher verfügen auch über integrierte Operationen / Funktionen wie
DateAdd
oderDatePart
in MS SQL Server. Auf diese Weise können Sie bestimmte Daten filtern oder auswählen, während sich die Daten noch im Speicher befinden (noch nicht in der Anwendung abgerufen).Universell akzeptiertes Format
Durch die Verwendung des nativen Typs müssen andere Entwickler oder Systeme, die ebenfalls mit dem Speicher interagieren, nicht über die winzigen Details zum Speichern dieses primitiven Typs informiert werden. Ist dies nicht der Fall, wenn dieser Typ als Zeichenfolge gespeichert wurde, müssen Sie sicherstellen, dass jeder das Format dieser
DateTime
Zeichenfolgendarstellung versteht. Dieses System wird anfällig, wenn Daten verarbeitet werden, die sich über Gebietsschemata, Regionen und Kulturen des Datenursprungs, den physischen Standort einer Anwendung und die Attribute des Endbenutzers / Systems erstrecken, der mit diesen Daten interagiert. Beispiel: Das Datumsformat in einem Land könnte MM / TT / JJJJ lauten (wie in den USA), in einem anderen Land könnte es TT / MM / JJJJ lauten, sodass es fast unmöglich ist, diesen Unterschied festzustellen.Geschwindigkeit
Die Geschwindigkeit des Abrufs, die Geschwindigkeit der Validierung, die Geschwindigkeit des Betriebs und die Speichereffizienz sind ebenfalls wichtige Faktoren. Beispiel für die Abrufgeschwindigkeit: Datenspeicher ermöglichen Indizes für Spalten, und diese Indizes können im Allgemeinen effizienter verwendet werden, wenn der Typ im systemeigenen Format gespeichert wird.
Anwendung
Datenzugriff
Das Ausführen von Abfragen für den Speicher wird mit dem systemeigenen Typsystem einfacher, da die Entwickler das Speicherformat nicht erraten müssen. Nahezu alle Datenspeicheranwendungsanbieter ( Beispiel: ado.net ) bieten Mechanismen zum Erstellen der richtigen parametrisierten Abfragen basierend auf den übergebenen nativen Typen. Hier ist ein Beispiel für das Hinzufügen des Datumsteils zu einer ado.net-Abfrage für einen SQL Server-Speicher. Dasselbe mit Strings zu tun, wäre sehr umständlich und anfällig für Fehler.
Operationen
Die systemeigenen Codetypen bieten auch Standardvorgänge wie den .NET-Typ
System.Date
. Operationen sind normalerweise mathematischer Natur wie das Hinzufügen von Datumsangaben, das Ermitteln des Unterschieds zwischen Datumsangaben usw. Auch dies ist bei Zeichenfolgentypen nicht einfach möglich.Präsentationsfolie
Gebietsschema
Wenn ein primitiver Typ schließlich in eine Zeichenfolge in der Präsentationsebene konvertiert wird ( die richtige Position im Programmstapel, um dies zu tun ), hat der Programmierer jetzt verschiedene Optionen, um ihn entsprechend dem Kontext, in dem er dargestellt wird, korrekt anzuzeigen. Dieser Kontext besteht im Allgemeinen aus der tatsächlichen Bedeutung der Daten und dem Gebietsschema des Benutzers.
Beispiel 1Eine datetime-Instanz kann basierend auf dem Gebietsschema des Benutzers automatisch formatiert werden.
Beispiel 2Eine Dezimalinstanz könnte einen Betrag (eine Währung) darstellen, und das Gebietsschema des Benutzers sollte dann auch den Betrag entsprechend seiner Präferenz anzeigen. Eine c # -Anwendung zeigt den Wert dann möglicherweise mit an
Dies kann kritisch sein, da verschiedene Kulturen unterschiedliche Zahlen anzeigen. In den USA haben Punkt (.) Und Komma (,) genau die umgekehrte Bedeutung wie in den Niederlanden.
Lage
Dies ist sehr
DateTime
instanzspezifisch. Ein Datum und eine Uhrzeit stellen ein Ereignis zu einem bestimmten Zeitpunkt dar, dies muss dem Benutzer jedoch in der Regel in Abhängigkeit von seiner eigenen Zeitzone mitgeteilt / präsentiert werden. Beispiel: EineDateTime
Instanz2016-09-21T23:38:21.399Z
könnte wie9/21/2016 5:21 PM
für einen Benutzer in der östlichen Zeitzone in den USA angezeigt werden . Es gibt viele Möglichkeiten, dies zu erreichen, aber es wird nahezu unmöglich, wenn die Datums- / Uhrzeitinstanz als Zeichenfolgentyp oder im Datenspeicher als Zeichenfolgentyp gespeichert wird.Allgemeine Regel
Die beiden allgemeinen Regeln für eine Anwendung beim Konvertieren eines primitiven Typs in eine Zeichenfolgendarstellung lauten wie folgt
quelle
Es ist wirklich nichts Falsches daran (dies wird bei Diensten ständig durchgeführt), solange Sie ein nicht mehrdeutiges Format für Ihr Datum verwenden. Mit eindeutig meine ich, dass nicht nur das Datum klar ist (z. B. MM / DD vs. DD / MM), sondern auch die Zeitzone, in der es sich befindet. Wenn Sie also Ihre Daten als Text darstellen möchten, verwenden Sie im Voraus ein ISO-Format . Ich bevorzuge UTC-basierte Zeitzeichenfolgen.
Vorteile:
Nachteile:
Wenn jemand sagte, er wolle das tun, würde ich fragen: "Warum?" weil es nicht wirklich viel Sinn macht. Wenn jemand das Datum als Zeichenfolge zurückgeben möchte, weil er es nur direkt anzeigt, ist dies kein guter Grund, Zeichenfolgen aus der Datenbank zu verwenden.
quelle