Zwei Datenbankfelder für Datum und Uhrzeit - sollten sie zusammengeführt werden?

8

In der folgenden Frage wurden Feld- und Tabellennamen geändert, um ihre Identität zu schützen.

Wenn ich zwei Datenbankspalten habe:

MONKEY_DATE DATETIME NULL (with data e.g. 2012-05-14 00:00:00.000)
MONKEY_TIME DATETIME NULL (with data e.g. 1753-01-01 16:30:53.025)

Die Datumskomponente des Zeitfelds ist meistens auf den 1. Januar 1753 eingestellt ... aber einige Daten haben den 1. Januar 1899 und einige den 1. Januar 1900.

Ich finde, dass das Verwalten des Codes zum Abfragen und Berichten dieser Spalten mir (und unserem Team) Kopfschmerzen bereitet, die leicht durch Zusammenführen der beiden Spalten gelöst werden könnten. Die Erfahrung (und Terry Goodkind ) hat mich jedoch gelehrt, dass nichts jemals einfach ist. Nachfolgend einige Beispiele, warum dies Kopfschmerzen sind.

Mein Ansatz

Ich denke, der folgende Ansatz hat den gewünschten Effekt, wenn die beiden Spalten zusammengeführt werden:

  1. Verwenden Sie SQL, um die Daten zu aktualisieren, und setzen Sie den Wert für das Datumsfeld und den Wert für das Zeitfeld auf denselben Wert. Dies ist eine Mischung aus der Datumskomponente aus dem Datumsfeld und der Zeitkomponente aus dem Zeitfeld
  2. Schreiben Sie neuen Code nur mit dem Feld MONKEY_DATE
  3. Schließen Sie schließlich das Feld MONKEY_TIME und die Datums- / Zeitkomponente SQL aus (siehe Beispiele).
  4. Löschen Sie MONKEY_TIME

Dies bedeutet, dass wir nicht sofort nachträglich Änderungen am gesamten System vornehmen müssen ... der gesamte vorhandene Code wird weiterhin funktionieren ... und wir können beginnen, die Dinge richtig zu machen.

SQL für # 1 könnte sein (Oracle):

UPDATE MONKEY SET 
    MONKEY_DATE = TO_DATE(TO_CHAR(MONKEY_DATE, 'MM/DD/YYYY ') || 
                      TO_CHAR(MONKEY_TIME, 'HH24:MI:SS'), 
                      'MM/DD/YYYY HH24:MI:SS')
    MONKEY_TIME = TO_DATE(TO_CHAR(MONKEY_DATE, 'MM/DD/YYYY ') || 
                      TO_CHAR(MONKEY_TIME, 'HH24:MI:SS'), 
                      'MM/DD/YYYY HH24:MI:SS')

Die Frage

Meine Fragen an Sie sind:

  • Sollten diese Felder zusammengeführt werden?
  • Ist mein Ansatz sinnvoll, diese beiden Spalten zusammenzuführen?
  • Denken Sie, es wäre besser, die Schritte zwei und drei zu überspringen?
  • Haben Sie weitere (konstruktive) Kommentare oder Vorschläge?

Beispiele

Um beispielsweise alle meine Affendaten und -zeiten auszuwählen und nach Datum und Uhrzeit zu ordnen, muss ich Folgendes tun (SQL Server):

SELECT 
      CONVERT(DATETIME, CONVERT(VARCHAR, MONKEY_DATE, 101), 101) AS MONKEY_DATE
    , CONVERT(DATETIME, CONVERT(VARCHAR, MONKEY_TIME, 108), 108) AS MONKEY_TIME 
FROM MONKEY 
ORDER BY
      CONVERT(DATETIME, CONVERT(VARCHAR, MONKEY_DATE, 101), 101) DESC
    , CONVERT(DATETIME, CONVERT(VARCHAR, MONKEY_TIME, 108), 108) DESC

oder dies (Oracle - etwas expliziter):

SELECT
      TO_DATE(TO_CHAR(MONKEY_DATE, 'MM/DD/YYYY'), 'MM/DD/YYYY') AS MONKEY_DATE
    , TO_DATE(TO_CHAR(MONKEY_TIME, 'HH24:MI:SS'), 'HH24:MI:SS') AS MONKEY_TIME
FROM MONKEY
ORDER BY
      TO_DATE(TO_CHAR(MONKEY_DATE, 'MM/DD/YYYY'), 'MM/DD/YYYY') DESC
    , TO_DATE(TO_CHAR(MONKEY_TIME, 'HH24:MI:SS'), 'HH24:MI:SS') DESC

Ich finde mich auch oft dabei, eine zusammengeführte Datums- / Zeitspalte (Oracle) auszuwählen:

SELECT 
    TO_DATE(TO_CHAR(MONKEY_DATE, 'MM/DD/YYYY ') || 
            TO_CHAR(MONKEY_TIME, 'HH24:MI:SS'), 
        'MM/DD/YYYY HH24:MI:SS') AS MONKEY_DATE_TIME 
FROM MONKEY

Weil wir fast immer das Datum und die Uhrzeit des Affen wissen wollen.

Das obige SQL kann leicht geändert werden in:

SELECT MONKEY_DATE_TIME FROM MONKEY ORDER BY MONKEY_DATE_TIME

... Wenn wir nur Spalten zusammengeführt hätten.

Hintergrund

Ich habe ein altes ASP-System geerbt, das Datum und Uhrzeit in separaten Spalten in der Datenbank speichert. Mir wurde gesagt, dass dies wahrscheinlich daran liegt, dass die Anwendung in einer frühen Version von Access gestartet wurde, in der es nicht möglich war, Datum und Uhrzeit in derselben Spalte zu speichern. Das Warum und Wie ist nicht wirklich Teil dieser Frage, aber einige Leute möchten es wissen.

PS

Ich habe das wirklich fast in SO.SE gepostet, also entschuldige ich mich, wenn ich die falsche Seite habe.

Oliver-Clare
quelle
Verpflichten Sie sich zum Zusammenführen. Einmal festgeschrieben - schneiden!
Oded

Antworten:

15

Ein kleiner Punkt: Wenn Sie die beiden Spalten zusammenführen, möchten Sie möglicherweise die Zusammenführung in eine neue Spalte "MONKEY_DATE_2" durchführen, anstatt die vorhandene zu überschreiben. Dadurch bleiben Ihre aktuellen Spalten unverändert, und Sie können den gesamten Code finden, der nicht aktualisiert wurde, um mit der neuen Struktur mit grep zu arbeiten.

mjfgates
quelle
6
+1. Genau das wollte ich vorschlagen (mit der Ausnahme, dass ich die neue Spalte MONKEY_DATETIME aufrufen würde).
Doc Brown
5
Und vergessen Sie nicht, Trigger hinzuzufügen, die die alten Spalten aktualisieren, wenn sich die neue ändert, und umgekehrt.
Blrfl
MMM ja. Löst aus. Zumindest bis die Axt fällt ... :)
mjfgates
7

Ja, ich denke, sie sollten zusammengelegt werden. Normalerweise würde ich mich nicht darum kümmern, Datums- und Zeitfelder zu trennen, es sei denn, es gibt einen guten Grund dafür. Ältere Systeme waren vielleicht ein guter Grund, aber wenn die Daten auf ein System migriert wurden, das Datums- und Uhrzeitangaben zusammen verarbeiten kann, ist das Zusammenführen eine gute Idee.

Ihr Ansatz klingt vernünftig. Möglicherweise möchten Sie sogar ein kleines Refactoring-Projekt ausführen, um den gesamten Code gleichzeitig zu korrigieren und sicherzustellen, dass alle Ihre Abfragen zusammen korrigiert werden, um das Feld "Eventuell das MONKEY_TIME-Feld auslaufen zu lassen" zu entfernen. Dies kann jedoch einige Zeit dauern und es wird wahrscheinlich signifikante Regressionstests erfordern. Was kein Problem sein sollte, wenn Sie vorausplanen.

Untersuchen Sie auch, ob es nachgeschaltete Systeme (z. B. Webdienste oder externe Berichtssysteme) gibt, die auf unterschiedlichen Codebasen basieren, aber dennoch von separaten Datums- und Zeitwerten abhängen. Wenn solche Systeme existieren, müssen sie auch Teil dieses Plans sein.

FrustratedWithFormsDesigner
quelle
1
+1 für nachgeschaltete Systeme. Wir haben einige APIs, die überprüft werden müssten ... Hmm, und dies kann sich auf Systeme von Drittanbietern auswirken, die die APIs verwenden. Ich muss darüber nachdenken, danke.
Oliver-Clare
1
Haha. Beide Antworten haben "Was Ihr * betrifft, klingt es vernünftig". Große Köpfe denken ähnlich? : P
Oleksi
Wenn das Altsystem im Wesentlichen noch vorhanden ist, überprüfen Sie, ob der Code, der auf diese Daten verweist, ordnungsgemäß verpackt ist, um nur auf das Datum oder gegebenenfalls nur auf die Uhrzeit zu verweisen.
Mikebabcock
3

Wenn Datum und Uhrzeit immer zusammen verwendet werden, führen Sie auf jeden Fall die Spalten zusammen und profitieren Sie von weniger Kopfschmerzen.

Dinge, auf die Sie achten sollten:

  • Verwendung der Zeitspalte zur Berechnung der relativen Zeit über Tage (z. B. "Auswahl der Affen, die an einem beliebigen Tag innerhalb einer Stunde nach dem Zeitpunkt, zu dem dieser Affe Bananen ging, Bananen gingen").
  • Arithmetik in der Datumsspalte, die nicht auf vernünftige Weise mit Bruchteilen von Tagen umgeht.
  • Verwendung der Datumsspalte als Gruppierungsmechanismus.

Wenn Sie bereits Abfragen haben, die besonders schwierig sind, erstellen Sie eine aktualisierbare Ansicht, die das alte Verhalten emuliert, bis Sie sie korrigieren können.

Blrfl
quelle
2

Ich hatte ein ähnliches Problem in einem früheren Arbeitssemester. Wir teilen Datum und Uhrzeit in zwei DB-Spalten auf. Dies verursachte uns viele Kopfschmerzen. > _ <Vor diesem Hintergrund würde ich Ihnen dringend empfehlen, zu einer einzelnen datetime-Spalte in Ihrer Datenbank zu wechseln. Dies verhindert, dass sich viele Fehler ansammeln.

Ihre Strategie klingt vernünftig, aber stellen Sie sicher, dass Sie das gesamte Team in diese Entscheidung und das Refactoring einbeziehen. Sie müssen aktiv davon abhalten, das alte Datenschema zu verwenden.

Wenn nicht viele Codeänderungen erforderlich sind (und Sie etwas mehr Zeit haben!), Können Sie die Änderung auf einmal vornehmen und keinen "Zwischenschritt" ausführen, in dem Sie beide Datenschemata unterstützen. Dies ist jedoch in der Regel unwahrscheinlich, sodass Sie wahrscheinlich einen Migrationsplan wie den in Schritt 2/3 genannten benötigen

Oleksi
quelle
1

Wenn Sie diese Änderung im Laufe der Zeit schrittweise durchführen (anstatt alle Änderungen vorzubereiten und dann alles auf einmal zu installieren), müssen Sie darauf achten, dass Sie die Werte nicht auf die neue Weise lesen, wenn sie auf die alte Weise geschrieben wurden. Der Übergang müsste also gehen:

  1. Alles Neue schreibt sowohl den neuen als auch den alten Weg (die Verwendung einer neuen Spalte für den neuen Weg würde helfen) und liest den alten Weg. Bestehender Code wird geändert, um sowohl den neuen als auch den alten Weg zu schreiben.

  2. Wenn der gesamte Code in beide Richtungen geschrieben wurde, konvertieren Sie vorhandene Daten so, dass sie in beide Richtungen verfügbar sind.

  3. Jeder neue Code liest den neuen Weg (und schreibt immer noch in beide Richtungen). Bestehender Code wird geändert, um den neuen Weg zu lesen.

  4. Sobald der gesamte Code den neuen Weg gelesen hat, kann der neue Code nur den neuen Weg schreiben, und der vorhandene Code kann so geändert werden, dass nur der neue Weg geschrieben wird.

  5. Sobald der gesamte Code auf die neue Weise gelesen und geschrieben wurde und kein Code auf die alten Spalten verweist, können sie entfernt werden.

Der neue Weg (eine Spalte mit Datum und Uhrzeit) scheint mir offensichtlich besser zu sein. Sie müssen sich entscheiden, ob es ausreicht, den Konvertierungsprozess zu verbessern.

JGWeissman
quelle