Dos campos de la base de datos para la fecha y la hora, ¿deberían fusionarse?

7

En la siguiente pregunta, los nombres de los campos y las tablas se han cambiado para proteger sus identidades.

Si tengo dos columnas de base de datos:

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)

El componente de fecha del campo de hora es mayormente configurado el 1 de enero de 1753 ... pero algunos datos tienen el 1 de enero de 1899 y algunos tienen el 1 de enero de 1900.

Encuentro que mantener el código para consultar e informar sobre estas columnas me causa (y a nuestro equipo) un dolor de cabeza que podría resolverse fácilmente fusionando las dos columnas. Sin embargo, la experiencia (y Terry Goodkind ) Me ha enseñado que nunca nada es fácil. Vea a continuación algunos ejemplos de por qué esto es un dolor de cabeza.

Mi enfoque

Estoy pensando que el siguiente enfoque tendrá el efecto deseado de fusionar las dos columnas:

  1. Use SQL para actualizar los datos, estableciendo el valor para el campo de fecha y el valor para el campo de hora en el mismo valor, que es una mezcla del componente de fecha del campo de fecha y el componente de hora del campo de hora
  2. Escriba cualquier código nuevo solo con el campo MONKEY_DATE
  3. Finalmente, elimine gradualmente el campo MONKEY_TIME y cualquiera de los componentes de fecha / hora SQL (ver ejemplos)
  4. soltar MONKEY_TIME

Esto significará que no tenemos que ir de inmediato a realizar cambios retrospectivos en todo el sistema ... todo el código existente seguirá funcionando ... y podemos comenzar a hacer las cosas de la manera correcta.

SQL para # 1 podría ser (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')

La pregunta

Mis preguntas para ti son:

  • ¿Deben combinarse estos campos?
  • ¿Mi enfoque es razonable para combinar estas dos columnas?
  • ¿Crees que sería mejor saltear los pasos dos y tres?
  • ¿Tiene algún otro comentario o sugerencia (constructiva)?

Ejemplos

Por ejemplo, para seleccionar todas las fechas y horas de mi mono y ordenarlas por fecha y hora, necesito hacer algo como esto (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

o esto (Oracle - un poco más explícito):

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

También a menudo me encuentro seleccionando una columna de fecha / hora (Oracle) combinada:

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

Porque, casi todo el tiempo, queremos saber la fecha y la hora del mono.

El SQL anterior se podría modificar fácilmente para:

SELECT MONKEY_DATE_TIME FROM MONKEY ORDER BY MONKEY_DATE_TIME

... Si solo hubiéramos fusionado columnas.

Background

He heredado un sistema ASP antiguo que almacena fechas y horas en columnas separadas en la base de datos. Probablemente me dijeron que esto se debe a que la aplicación comenzó en una versión anterior de Access, donde no era posible almacenar la fecha y la hora en la misma columna. Los por qué y cómo no son realmente parte de esta pregunta, pero a algunas personas les gusta saber.

P.S.

Realmente casi publiqué esto en SO.SE, así que mis disculpas si me equivoco de sitio.

    
pregunta oliver-clare 14.05.2012 - 17:50

5 respuestas

14

Un punto menor: CUANDO fusionas las dos columnas, quizás quieras hacer la fusión en una nueva columna "MONKEY_DATE_2" en lugar de sobrescribir la existente. Eso deja sus columnas actuales sin cambios, y puede encontrar todo el código que no se ha actualizado para trabajar con la nueva estructura con grep.

    
respondido por el mjfgates 14.05.2012 - 18:01
6

Sí, creo que deberían fusionarse. Normalmente no me molestaría en separar los campos de fecha y hora a menos que haya una buena razón para hacerlo. Los sistemas heredados podrían haber sido una buena razón, pero si los datos se han migrado a un sistema que puede manejar fechas y horas combinadas, la combinación es una buena idea.

En cuanto a su enfoque, suena razonable. Es posible que incluso desee ejecutar un pequeño proyecto de refactorización para corregir todo el código al mismo tiempo y asegurarse de que todas sus consultas se corrijan juntas para eliminar el "campo de MONKEY_TIME", aunque podría llevar algún tiempo. y probablemente requerirá pruebas de regresión significativas. Lo que no debería ser un problema si planeas por adelantado.

También investigue si hay sistemas posteriores (como servicios web o sistemas de informes externos) que se construyan a partir de diferentes bases de códigos pero que aún dependan de valores de fecha y hora separados. Si existen tales sistemas, también deberán formar parte de este plan.

    
respondido por el FrustratedWithFormsDesigner 14.05.2012 - 17:56
2

Si la fecha y la hora siempre se usan juntas, entonces, por todos los medios, combine las columnas y coseche los beneficios de menos dolores de cabeza.

Cosas a tener en cuenta:

  • Uso de la columna de tiempo para calcular el tiempo relativo a lo largo de los días (por ejemplo, "selección de los monos que hicieron bananas en cualquier día a la vez dentro de la hora en que este mono se hizo bananas").
  • Aritmética en la columna de fecha que no trata los días fraccionarios de una manera sana.
  • Uso de la columna de fecha como un mecanismo de agrupación.

Si tiene consultas existentes que son particularmente persistentes, cree una vista actualizable que emule el comportamiento anterior hasta que pueda resolverlas.

    
respondido por el Blrfl 14.05.2012 - 20:31
1

Tuve un problema similar en un término de trabajo anterior. Dividimos la fecha y la hora en dos columnas de base de datos. Esto nos causó muchos dolores de cabeza. > _ < Dicho esto, le recomendaría encarecidamente que cambie a una única columna de fecha y hora en su base de datos. Esto evitará que muchos errores suban.

En cuanto a su estrategia, suena razonable, pero asegúrese de involucrar a todo el equipo en esta decisión y refactorización. Debe desalentar activamente que alguien use el esquema de datos anterior.

Si no se requieren muchos cambios de código (¡y tiene tiempo adicional!), puede considerar realizar el cambio de una vez y no tener un paso "intermedio" en el que admita ambos esquemas de datos. Sin embargo, esto suele ser poco probable, por lo que es probable que necesite algún tipo de plan de migración como el que mencionó en el paso 2/3

    
respondido por el Oleksi 14.05.2012 - 17:55
0

Si está cambiando la fase de este cambio a lo largo del tiempo (en lugar de preparar todos los cambios y luego instalar todo al mismo tiempo), debe tener cuidado de no leer los valores de la nueva forma cuando se escribió en el antiguo camino. Así que la transición tendría que ir:

  1. Todas las nuevas escrituras, tanto la nueva como la antigua (usar una nueva columna para la nueva forma ayudarían), y leen la antigua. El código existente se modifica para escribir tanto en la nueva forma como en la antigua.

  2. Una vez que todo el código esté escribiendo en ambos sentidos, convierta los datos existentes para que estén disponibles en ambos sentidos.

  3. Todo el nuevo código lee la nueva forma (y aún escribe en ambas direcciones). El código existente se modifica para leer la nueva forma.

  4. Una vez que todo el código está leyendo la nueva forma, el nuevo código puede escribir solo la nueva forma, y el código existente puede modificarse para escribir solo la nueva forma.

  5. Una vez que todo el código esté leyendo y escribiendo la nueva forma, y ningún código haga referencia a las columnas antiguas, se pueden eliminar.

La nueva forma (una columna con fecha y hora) me parece obviamente mejor, tienes que decidir si es una mejora suficiente para pasar por el proceso de conversión.

    
respondido por el JGWeissman 14.05.2012 - 19:47

Lea otras preguntas en las etiquetas