En la siguiente pregunta, los nombres de campos y 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 tiempo se establece principalmente en 1 de enero de 1753 ... pero algunos datos tienen el 1 de enero de 1899 y algunos tienen el 1 de enero de 1900.
Me parece que mantener el código para consultar e informar sobre estas columnas me causa a mí (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 nada es fácil. Vea a continuación algunos ejemplos de por qué esto es un dolor de cabeza.
Mi acercamiento
Estoy pensando que el siguiente enfoque tendrá el efecto deseado de fusionar las dos columnas:
- Use SQL para actualizar los datos, estableciendo el valor para el campo de fecha y el valor para el campo de tiempo en el mismo valor, que es una combinación del componente de fecha del campo de fecha y el componente de tiempo del campo de tiempo
- Escriba cualquier código nuevo solo usando el campo MONKEY_DATE
- Finalmente, elimine gradualmente el campo MONKEY_TIME y cualquiera de los componentes SQL de fecha / hora (ver ejemplos)
- Soltar MONKEY_TIME
Esto significa que no tenemos que realizar cambios retrospectivos en todo el sistema de inmediato ... todo el código existente continuará 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 usted son:
- ¿Deben fusionarse estos campos?
- ¿Es razonable mi enfoque para fusionar estas dos columnas?
- ¿Crees que sería mejor omitir los pasos dos y tres?
- ¿Tiene algún otro comentario (constructivo) o sugerencia?
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 fusionada (Oracle):
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 hora del mono.
El SQL anterior podría modificarse fácilmente para:
SELECT MONKEY_DATE_TIME FROM MONKEY ORDER BY MONKEY_DATE_TIME
... Si tan solo hubiéramos fusionado columnas.
Antecedentes
Heredé un antiguo sistema ASP que almacena fechas y horas en columnas separadas en la base de datos. Me han dicho que esto probablemente se deba 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 porqués y los cómo no son realmente parte de esta pregunta, pero a algunas personas les gusta saber.
PD
Realmente casi publiqué esto en SO.SE, así que mis disculpas si obtuve el sitio equivocado.
fuente
Respuestas:
Un punto menor: CUANDO combine las dos columnas, es posible que desee fusionarlas 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.
fuente
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 hubieran migrado a un sistema que pueda manejar fechas y horas combinadas, entonces la fusió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 para asegurarse de que todas sus consultas se corrijan juntas para deshacerse del "Eventualmente eliminar el campo 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 lo planifica con anticipación.
También investigue si hay sistemas posteriores (como servicios web o sistemas de informes externos) que se crean a partir de diferentes bases de código pero que aún dependen de valores de fecha y hora separados. Si tales sistemas existen, también deberán ser parte de este plan.
fuente
Si la fecha y la hora siempre se usan juntas, entonces, por supuesto, combine las columnas y aproveche los beneficios de menos dolores de cabeza.
Cosas a tener en cuenta:
Si tiene consultas existentes que son particularmente difíciles, cree una vista actualizable que emule el comportamiento anterior hasta que pueda corregirlas.
fuente
Tuve un problema similar en un período 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, recomiendo encarecidamente que cambie a una sola columna de fecha y hora en su base de datos. Esto evitará la aparición de muchos errores.
En cuanto a su estrategia, parece razonable, pero asegúrese de involucrar a todo el equipo en esta decisión y refactorización. Debe desalentar activamente a cualquier persona para que use el antiguo esquema de datos.
Si no se requieren muchos cambios de código (¡y tiene algo de tiempo extra!), 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 generalmente es poco probable, por lo que probablemente necesitará tener algún tipo de plan de migración como el que mencionó en el paso 2/3
fuente
Si está introduciendo este cambio gradualmente con el tiempo (en lugar de preparar todos los cambios y luego instalar todo de una vez), debe tener cuidado de no leer los valores de la manera nueva cuando se escribió de la manera anterior. Entonces la transición tendría que ir:
Todo nuevo escribe tanto la nueva forma como la antigua (sería útil usar una nueva columna para la nueva forma), y lee la forma antigua. El código existente se modifica para escribir tanto la nueva forma como la antigua.
Una vez que todo el código está escribiendo en ambos sentidos, convierta los datos existentes para que estén disponibles en ambos sentidos.
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.
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.
Una vez que todo el código está leyendo y escribiendo la nueva forma, y ningún código hace referencia a las columnas antiguas, se pueden eliminar.
La nueva forma (una columna con fecha y hora) me parece obviamente mejor, debe decidir si es una mejora suficiente para pasar por el proceso de conversión.
fuente