2008-09-19 16 views
14

Estar atascado con un esquema de base de datos heredado que ya no refleja su modelo de datos es la pesadilla de todo desarrollador. Sin embargo, con todo lo que se habla sobre el código de refactorización para la mantenibilidad, no he escuchado mucho sobre la refactorización de esquemas de bases de datos obsoletos.Consejos para refactorizar un esquema de base de datos obsoleto

¿Cuáles son algunos consejos sobre cómo hacer la transición a un mejor esquema sin romper todo el código que se basa en el anterior? Propondré un problema específico que tengo que ilustrar sobre mi punto, pero siéntanse libres de dar consejos sobre otras técnicas que han demostrado ser útiles; es probable que también sean útiles.


Mi ejemplo:

Mi empresa recibe y envía sus productos. Ahora, un recibo del producto y un envío del producto tienen datos muy diferentes asociados a ellos, por lo que los diseñadores originales de la base de datos crearon una tabla separada para los recibos y los envíos.

En mi primer año de trabajo con este sistema, me he dado cuenta de que el esquema actual no tiene sentido. Después de todo, tanto un recibo como un envío son básicamente una transacción, cada uno implica cambiar la cantidad de un producto, en el fondo solo el signo +/- es diferente. De hecho, con frecuencia necesitamos encontrar la cantidad total que el producto ha cambiado durante un período de tiempo, un problema para el cual este diseño es francamente intratable.

Obviamente, el diseño apropiado sería tener una sola tabla de transacciones con el ID como una clave externa de una tabla ReceiptInfo o una tabla ShipmentInfo. Desafortunadamente, el esquema incorrecto ya ha estado en producción por algunos años y tiene cientos de procedimientos almacenados y miles de líneas de código perdidas. ¿Cómo puedo hacer la transición del esquema para que funcione correctamente?

Respuesta

5

Aquí hay todo un catálogo de refactorizaciones base de datos:

http://databaserefactoring.com/

+0

¿Hay algo específico para MySQL, por ejemplo? Todo lo que veo son gráficos ... no hay instrucciones reales sobre cómo, por ejemplo, eliminar una tabla de búsqueda. –

+0

En su mayoría es RDBMS-agnóstico. El libro en sí contiene las instrucciones reales. Hay una refactorización para * agregar * una tabla de búsqueda, no se puede ver una para eliminarla :) http://databaserefactoring.com/AddLookupTable.html –

0

¿Está todo el acceso a datos limitado a los procedimientos almacenados? Si no, la tarea podría ser casi imposible. De ser así, solo tiene que asegurarse de que sus scripts de migración de datos funcionen correctamente, pasando del esquema antiguo al nuevo, y luego asegúrese de que sus procedimientos almacenados respeten sus entradas y salidas.

Esperemos que ninguno de ellos tenga consultas "select *". Si lo hacen, use 'sp_help tablename' para obtener la lista completa de columnas, cópiela y reemplace cada * con la lista completa de columnas, solo para asegurarse de no romper el código del cliente.

Recomendaría realizar los cambios de forma gradual y realizar muchas pruebas de integración. Es difícil hacer una remodelación significativa sin introducir algunos errores.

+0

Sin faltarle el respeto a Eric, pero esto no da ningún consejo real antes de decir "hazlo con cuidado". En mi caso, el 99% del acceso es de hecho con SP pero hay decenas de miles de líneas de código PL/SQL. ¿Puede recomendar alguna lectura sobre migración de datos? –

+0

Supongo que no veo el punto de lectura sobre la refactorización, per se. Creo que la estrategia correcta es diseñar el esquema correcto (para que la lectura del diseño de la base de datos sea mejor), y una vez hecho esto, averigüe cómo migrar los datos y volver a escribir los procesos. Todo es caso por caso. –

0

Lo primero es crear el esquema de la tabla. Ya hice eso para una base de datos Legacy usando Enterprise Architect. Puede seleccionar la base de datos y le creará todas las tablas/campos. Entonces, necesitarás dividir todo en categorías. Muestra todos tus productos recibidos y enviados juntos, cosas de clientes en otra categoría. Una vez que todo esté despejado, podrá refactorizar el campo creando una nueva tabla, una nueva distribución y nuevos campos. Por supuesto, esto necesitará muchos cambios si se accede a todo sin el Procedimiento almacenado.

2

Eso es una cosa muy difícil de evitar; Un par de opciones rápidas después de refactorizar la base de datos son:

  • Cree vistas que coincidan con el esquema original pero extraiga del nuevo esquema; Es posible que necesite desencadenantes aquí para poder gestionar cualquier actualización de las vistas.
  • Crea el nuevo esquema y coloca los activadores en cada lado para mantener el otro lado.
  • 1

    Los procedimientos almacenados y las vistas son su amigo aquí. Incluso si el sistema no los usa, cámbialos para usarlos, luego refactoriza la base de datos debajo.

    Sus recibos y envíos se convierten en visitas.

    Cuidado, los recibos y los envíos son en realidad dos bestias muy diferentes en la mayoría de los sistemas con los que he trabajado. Los recibos están vinculados a los proveedores, mientras que los envíos están vinculados con los clientes (o las ubicaciones de clientes/envío). En el nivel de inventario, a menudo se representan de la misma manera.

    +0

    Gracias por el consejo, de hecho, son bestias muy diferentes, pero Como la mayoría de las tareas que hacemos con el sistema están relacionadas con el inventario, no tiene sentido salir de nuestro camino para tratarlas como tales. –

    3

    This book (Refactoring Databases) ha sido una bendición para mí cuando se trata de esquemas de bases de datos heredados, incluso cuando tuve que lidiar con casi el mismo problema para nuestra base de datos de inventario.

    Además, tener un sistema implementado para rastrear los cambios en el esquema de la base de datos (como una serie de scripts alternativos almacenados en el repositorio de control de origen) ayuda enormemente a descifrar las dependencias de código a base de datos.

    0

    No creo que sea obvio que la identificación de la tabla de transacciones debe ser una clave externa a ReceiptInfo o a ShipmentInfo. Piensa al revés. En un modelo orientado a objetos, debe tener una tabla de transacciones y ReceiptInfo o ShipmentInfo debe tener una clave externa para la tabla de transacciones. Si tiene suerte, habrá solo 1 o 2 puntos en el código donde se realizan nuevos registros en ReceiptInfo o ShipmentInfo. Allí debe agregar el código donde agrega una entrada en la tabla de transacciones y luego crea la entrada en ReceiptInfo o ShipmentInfo con la clave externa para la transacción.

    +0

    Creo que tenemos lo mismo en mente. Tiene razón sobre la terminología que voy a editar mi publicación. –

    0

    A veces puede crear tablas nuevas que tengan mejores estructuras y luego crear vistas con los nombres de sus tablas antiguas, pero se basan en los datos de las tablas nuevas. De esta forma, tu código no se rompe mientras comienzas a moverte a una mejor estructura. Tenga cuidado con esto aunque algunas veces pasa de una tabla no relacional a una estructura relacional donde tiene múltiples registros mientras que el código solo espera uno. Esto es particularmente cierto si tiene desarrolladores que usan subconsultas.

    Luego, a medida que se cambia cada cosa, se alejará de las vistas hacia la tabla real. Eventualmente puedes dejar caer las vistas. Esto al menos le permite trabajar de forma incremental para mantener las cosas funcionando mientras mueve cosas, pero comienza a arreglar las cosas para usar un mejor diseño.

    Cuestiones relacionadas