true transaction tag runonchange database refactoring schema

database - tag - liquibase sql transaction



Consejos para refactorizar un esquema de base de datos obsoleto (8)

¿Todo el acceso a los datos está 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 hacer los cambios gradualmente y hacer muchas pruebas de integración. Es difícil hacer una remodelación significativa sin introducir algunos errores.

Estar atascado con un esquema de base de datos heredado que ya no refleja su modelo de datos es la pesadilla de todos los desarrolladores. 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.

¿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 compañía recibe y envía 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 trabajando con este sistema, me di 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?


A veces puede crear nuevas tablas 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 mesa 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.



Eso es algo muy difícil de solucionar; 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 factores desencadenantes en cada lado para mantener el otro lado.

  • 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.


    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 vistas.

    Tenga 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.


    No creo que sea obvio que el ID de la tabla de transacciones debe ser una clave externa para ReceiptInfo o 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 realizarán 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.


    Este libro (Refactoring Databases) ha sido enviado por Dios al tratar con 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, contar con un sistema para rastrear los cambios en el esquema de la base de datos (como una serie de scripts alternativos que se almacenan en el repositorio de control de origen) ayuda inmensamente a determinar las dependencias de código a base de datos.