La semana pasada hablando sobre Visual Studio y como incluye una base de datos local sin instalar componentes adicionales, si te lo perdiste échale un vistazo aquí, mencioné que tener una base de datos por cada desarrollador, puede resultar mucho más productivo que utilizar una base de datos compartida por todo el equipo.
El modelo tracional: Una base de datos compartida
Habitualmente, un equipo de desarrollo comparte su base de datos, generalmente en un servidor dedicado a mantener las bases de datos de desarrollo.
Es evidente la primera implicación de este modelo, si todos los equipos de desarrollo mantienen sus base de datos ahí, este servidor requiere el mismo mantenimiento que uno de producción, dado que cualquier mínima pérdida de rendimiento o disponibilidad afectará a la productividad de todos
En realida esté es el menor de los problemas, existe otro que tiene mucho más impacto y que sólo sale a la luz si se trabaja suficiente tiempo en equipo siguiendo este modelo de bases de datos compartidas.
El problema
Supongamos que un desarrollador del equipo esta trabajando en añadir encriptación al almacén de contraseñas de la aplicación.
Mientras otro desarrollador del equipo, continúa trabajando con otras historias de usuario.
Por supuesto, nuestro equipo de ejemplo utiliza un control de versiones para su código. Finalmente nuestro primer desarrollador modifica las contraseñas en la base de datos, sin embargo, como resultado de ejecutar las pruebas funcionales descubre un bug en la funcionalidad y no está listo para subirlo al control de versiones.
Veis el problema? Sí, en el momento en que nuestro primer desarrollador ha realizado ese cambio en la base de datos, inmediatamente los test de autenticación del resto del equipo dejarán de funcionar. Es más, nuestro segundo desarrollador ni siquiera podrá iniciar la aplicación en caso necesario!
Esto que parece obvio, ocurre en más de un equipo, donde en ese momento todos dejan de trabajar en lo que estaban y comienzan a buscar al responsable que ha cambiado la base de datos.
Una base de datos por desarrollador
Hace tiempo que, cansado de estas interrupciones y pérdidas de productividad, decidí buscarle solución a este problema.
Si estamos creando código de manera local, pensé, y no subimos los cambios al repositorio principal sin haberlos validado antes, porqué no podemos hacer lo mismo con la base de datos?
Es decir, cada desarrollador de nuestro equipo tiene entonces una base de datos completa en su máquina, y mientras desarrolla puede hacer las modificaciones que quiera, sabiendo que no afectan a los demás miembros de equipo.
Reto: Compartir los cambios
Sin embargo, nos encontramos con un nuevo reto, y es que en el momento que subimos los cambios al repositorio principal, necesitamos compartirlos con el resto del equipo.
Lógicamente, hacerlo de forma manual, sería una nueva pérdida de productividad, incluso, dependiendo de la funcionalidad una pérdida total de tiempo.
Migraciones
De la misma forma que todos nuestros cambios de código están versionados, y nadie más los ve, hasta que están listos para ser compartidos, no podemos hacer lo mismo con la base de datos?
Podemos escribir el código DML necesario e incluirlo junto a nuestro changeset para que en cuanto el resto del equipo se baje el código, apliquen los cambios necesarios a la base de datos.
Es decir esto introduce una nueva tarea en nuestro flujo de desarrollo:

Y ahora sí, cada cambio se encuentra asociado a su correspondiente en la base de datos. Hemos versionado nuestra base de datos, de la misma forma que versionamos el código.
Migraciones basadas en código
Yo programo en el lenguaje X# porque tengo que hacer migraciones en SQL?
La verdad es que este es el primero reto al asumir este modelo. De hecho, además de tener que escribir complejas instrucciones DML para migrar la base de datos, puede resultar complicado controlar la transaccionalidad de los cambios. No queremos que nuestra migración deje la base de datos de los demás en un estado irreversible!
Por suerte, tenemos frameworks disponibles que nos permiten escribir nuestras migraciones sólo con código, sin escribir prácticamente una línea de SQL.
En el caso de .NET tenemos dos, EF Migrations, compatible con los proveedores de base de datos que soporta Entity Framework, y FluentMigrator, proyecto en el que colaboré hasta su versión 1.0, con soporte pata múltiples bases de datos.
En resumen
- Versiona tu base de datos, como versionas tu código
- Por cada cambio que hagas a la base de datos, escribe su migración correspondiente
- Apoyáte en frameworks que te hagan sencillo escribir las migraciones y controlar la forma en que se aplican
Termino con una pregunta, ¿cuál es otra ventaja de las migraciones, que ocurre como consecuencia de aplicar el modelo anterior?
Hasta la próxima semana!
Gorka Armentia
Buenas, estoy sentado a 30 centímetros de ti, pero mola contestar por aquí 😛
Se me ocurren varias ventajas adicionales: despliegue y actualizaciones en producción sin morir en el intento, volver a una revisión anterior pudiendo deshacer los cambios automáticamente en la base de datos, incorporaciones de nuevos desarrolladores que con solo bajar el código y compilar ya tendrá la base de datos lista, …
Petición: un post explicando bien la forma de usar EF Migrations, porque nosotros seguimos con FluentMigrator y queremos cambiar 😉
Iñaki Elcoro
Efectivamente Gorka, cuando preguntaba por otras ventajas justo estaba pensando en esas: despliegue de bases datos en producción, con posibilidad de deshacer si algo no sucede como esperamos, étc
Recojo el guante, próxima semana Entity Framework de paso comentaré algunos “gotchas” que me he encontrado!
Frank Torres
Buen post, mister!
Totalmente de acuerdo. Antes los ordenadores no tenían potencia para albergar el servidor de datos, pero ahora cualquier portátil de gama media lo soporta. De modo que viendo la cantidad de ventajas que tiene usar una base de datos local, no hay duda en que es la mejor forma de trabajar en equipo… Esto no quita el que a veces haya que usar una base de datos compartida si los datos con los que se trabaja así lo requieren, pero en la mayoría de los casos 1 BD x programador es lo mejor.
Yo he probado ambos frameworks de migración y, sinceramente, me quedo con fluent.
Un saludo
Iñaki Elcoro
Frank, si echas un vistazo al post de la semana pasada: http://ielcoro.azurewebsites.net/2012/12/06/visual-studio-la-navaja-suiza-1-base-de-datos/ puedes ver que ahora es aún más fácil tener una base de datos local! No hay que hacer nada!
Y respecto a si Entity Framework Migrations o FluentMigrator, te contesto la semana que viene 😉