He utilizado con éxito la siguiente metodología, elaborada en el Control de versiones y su Base de datos :
- mantener un número de versión en metadatos (uso una propiedad extendida de base de datos)
- cualquier cambio de esquema se codifica como un script que se actualiza desde la versión actual a la siguiente versión
- la aplicación se envía con todos los scripts para actualizar desde la versión 0 (implementación inicial) hasta la versión actual
- Cada cambio se realiza a través de un script. Incluyendo cambios en los datos del 'sistema' como diccionarios y entradas en la tabla de búsqueda.
- cuando se implementa, la aplicación verifica la versión del esquema en el disco, luego ejecuta todos los pasos de actualización para llevar el esquema a la versión actual requerida
A menudo escucho la opinión de '¿en qué se diferencia esto de solo mantener los scripts de definición de objetos bajo control de origen?'. La diferencia es enorme, porque cuando implementa una nueva versión de su aplicación, no va a crear simplemente una nueva base de datos. La mayoría de las veces su aplicación tendrá que actualizar la base de datos existente, incluidos los datos existentes . Esta es una diferencia crucial, sus pasos de actualización deben garantizar la integridad y la coherencia de los datos existentes durante la actualización. Algunas operaciones son triviales en el código (agregue una columna no anulable con valor predeterminado al script de definición de objeto de tabla, hecho), pero de hecho son muy dolorosas en el despliegue real (la tabla tiene 1.5 mil millones de filas, la columna de agregar se agotaría de espacio de registro si se hace de la manera 'simpleton').
¿Cómo funciona esto con la ramificación?
- cuando se crea la rama, se ajusta la versión actual del esquema, digamos la versión 1.6
- A medida que el equipo comienza a trabajar en la sucursal, agrega una nueva versión, 1.7, y luego comienza a codificar el paso de actualización de 1.6 a 1.7
- el paso de actualización cambia a medida que se realizan modificaciones en la rama. Siempre ejecuta la secuencia de comandos que actualiza de v 1.6 a 1.7, pero lo que hacen exactamente esas secuencias de comandos está sujeto a las iteraciones de código normales y los registros en la rama
- la rama finaliza el desarrollo, se prepara para la integración inversa (para fusionarse nuevamente en la línea de base)
- realiza una nueva integración hacia adelante desde la línea base hasta la rama. Si la integración no trae ningún cambio en la versión del esquema, todo está bien, la rama puede revertir la integración tal como está. La versión 1.7 se convierte en la nueva versión de referencia.
- Lo interesante es cuando otra rama se ha integrado inversamente en la base mientras tanto y ahora la versión del esquema base ha cambiado a, digamos, 1.7. En este caso, nuestra sucursal tiene que aumentar su versión de esquema de destino de implementación a 1.8 y hacer una revisión del paso de actualización que anteriormente era de 1.6 a 1.7 para ver cómo funciona en el nuevo entorno, actualizando de 1.7 a 1.8. Los conflictos de esquema lógico tienen que resolverse, el script puede requerir cambios, las pruebas deben hacerse. Una vez completado, la rama puede revertir la integración en la base. La versión de destino implementada del producto ahora se convierte en 1.8.
- cuando otra bifurcación que se bifurca en la versión de esquema 1.6 quiere integrarse inversamente, tendrá que cambiar su versión de esquema a 1.9, probar el script de actualización de 1.8 a 1.9, luego puede integrarse nuevamente en la base.
Tenga en cuenta que no hay ninguna herramienta involucrada, no hay secuencias de comandos de diferencias de esquema mágico, no hay asistentes y no hay una secuencia de comandos de clic con el botón derecho involucrada. Este es un proceso 100% dirigido por el desarrollador, basado en la fuente (scripts). Muchos encuentran todo este proceso elaborado, pero funciona. De hecho, como usuario de SQL Server, ya ha aprovechado los resultados de este proceso en su uso diario de SQL Server: SQL Server utiliza un proceso de actualización de base de datos muy similar y, como probablemente espera, el proceso de desarrollo de productos hace un uso extensivo de ramificación y el problema que mencionó es un problema muy real que debe resolverse.
Por cierto, cómo ocurre realmente la ramificación / integración difiere entre los productos de control de origen, estoy usando los términos familiares del modo de operación forzosamente integrado .