php - revisiones - Mecanismos para el seguimiento de cambios en el esquema de base de datos
panel de revisiones word (20)
¿Cuáles son los mejores métodos para rastrear y / o automatizar cambios en el esquema de DB? Nuestro equipo usa Subversion para el control de versiones y hemos podido automatizar algunas de nuestras tareas de esta manera (empujando las compilaciones a un servidor intermedio, implementando código probado en un servidor de producción) pero aún estamos haciendo actualizaciones de la base de datos manualmente. Me gustaría encontrar o crear una solución que nos permita trabajar de manera eficiente en servidores con diferentes entornos mientras sigo usando Subversion como un back-end a través del cual el código y las actualizaciones de bases de datos se envían a varios servidores.
Muchos paquetes de software populares incluyen scripts de actualización automática que detectan la versión DB y aplican los cambios necesarios. ¿Es esta la mejor manera de hacerlo incluso a mayor escala (en múltiples proyectos y, a veces, en múltiples entornos e idiomas)? Si es así, ¿hay algún código existente que simplifique el proceso o es mejor simplemente lanzar nuestra propia solución? ¿Alguien ha implementado algo similar antes y lo ha integrado en los ganchos posteriores a la confirmación de Subversion, o es una mala idea?
Si bien sería preferible una solución que admita múltiples plataformas, definitivamente debemos admitir la pila Linux / Apache / MySQL / PHP ya que la mayoría de nuestro trabajo está en esa plataforma.
Creo carpetas con el nombre de las versiones de compilación y pongo scripts de actualización y degradación allí. Por ejemplo, podría tener las siguientes carpetas: 1.0.0, 1.0.1 y 1.0.2. Cada uno contiene el script que le permite actualizar o degradar su base de datos entre versiones.
En caso de que un cliente o un cliente lo llame con un problema con la versión 1.0.1 y esté utilizando 1.0.2, devolver la base de datos a su versión no será un problema.
En su base de datos, cree una tabla llamada "esquema" donde coloque la versión actual de la base de datos. Luego, escribir un programa que pueda actualizar o degradar su base de datos por usted es fácil.
Justo como dijo Joey, si estás en un mundo de Rails, usa Migraciones. :)
El problema aquí es realmente facilitar a los desarrolladores la escritura de sus propios cambios locales en el control de origen para compartir con el equipo. Me he enfrentado a este problema durante muchos años y me inspiró la funcionalidad de Visual Studio para profesionales de bases de datos. Si desea una herramienta de código abierto con las mismas características, intente esto: http://dbsourcetools.codeplex.com/ Diviértase, - Nathan.
En el mundo de Rails, existe el concepto de migraciones, scripts en los que se realizan cambios en la base de datos en Ruby en lugar de una versión de SQL específica de la base de datos. Su código de migración de Ruby termina convirtiéndose en el DDL específico de su base de datos actual; esto hace que cambiar de plataforma de base de datos sea muy fácil
Por cada cambio que realice en la base de datos, debe escribir una nueva migración. Las migraciones suelen tener dos métodos: un método "arriba" en el que se aplican los cambios y un método "abajo" en el que se deshacen los cambios. Un solo comando actualiza la base de datos y también puede usarse para llevar la base de datos a una versión específica del esquema. En Rails, las migraciones se mantienen en su propio directorio en el directorio del proyecto y se registran en el control de versiones como cualquier otro código de proyecto.
Esta guía de Oracle para las migraciones de Rails cubre bastante bien las migraciones.
Los desarrolladores que usan otros idiomas han analizado las migraciones y han implementado sus propias versiones específicas del idioma. Sé de Ruckusing , un sistema de migraciones PHP modelado a partir de las migraciones de Rails; Puede ser lo que estás buscando.
En mi humilde opinión las migraciones tienen un gran problema:
Actualizar de una versión a otra funciona bien, pero realizar una instalación nueva de una versión determinada puede llevar una eternidad si tiene cientos de tablas y un largo historial de cambios (como nosotros).
Ejecutar todo el historial de deltas desde la línea de base hasta la versión actual (para cientos de bases de datos de clientes) puede llevar mucho tiempo.
Es un poco de baja tecnología, y puede haber una mejor solución, pero podría almacenar su esquema en un script SQL que se puede ejecutar para crear la base de datos. Creo que puede ejecutar un comando para generar este script, pero desafortunadamente no lo sé.
Luego, confirme el script en el control de origen junto con el código que funciona en él. Cuando necesite cambiar el esquema junto con el código, el script se puede registrar junto con el código que requiere el esquema modificado. Luego, diffs en el script indicará diffs en los cambios de esquema.
Con este script, puede integrarlo con DBUnit o algún tipo de script de compilación, por lo que parece que podría encajar con sus procesos ya automatizados.
Existe una herramienta de línea de comandos mysql-diff que compara los esquemas de la base de datos, donde el esquema puede ser una base de datos en vivo o un script SQL en el disco. Es bueno para la mayoría de las tareas de migración de esquemas.
He utilizado la siguiente estructura de proyecto de base de datos en Visual Studio para varios proyectos y ha funcionado bastante bien:
Base de datos
Cambiar guiones
0.PreDeploy.sql
1.SchemaChanges.sql
2.DataChanges.sql
3.Permissions.sql
Crear guiones
Sprocs
Las funciones
Puntos de vista
Nuestro sistema de compilación actualiza la base de datos de una versión a la siguiente ejecutando los scripts en el siguiente orden:
1.PreDeploy.sql
2.SchemaChanges.sql
Contenido de la carpeta Crear secuencias de comandos
2.DataChanges.sql
3.Permissions.sql
Cada desarrollador verifica en sus cambios un error / característica particular al agregar su código al final de cada archivo. Una vez que se completa una versión principal y se ramifica en el control de origen, se elimina el contenido de los archivos .sql en la carpeta Cambiar secuencias de comandos.
K. Scott Allen tiene uno o dos artículos decentes sobre el control de versiones de esquemas, que utiliza el concepto de scripts de actualización incremental / migraciones al que se hace referencia en otras respuestas aquí; ver http://odetocode.com/Blogs/scott/archive/2008/01/31/11710.aspx .
Me gusta la forma en que Yii maneja las migraciones de bases de datos. Una migración es básicamente un script PHP que implementa CDbMigration
. CDbMigration
define un método up
que contiene la lógica de migración. También es posible implementar un método down
para admitir la reversión de la migración. Alternativamente, safeUp
o safeDown
se pueden usar para asegurarse de que la migración se realice en el contexto de una transacción.
La herramienta de línea de comandos de yiic
contiene soporte para crear y ejecutar migraciones. Las migraciones se pueden aplicar o revertir, una por una o en un lote. La creación de una migración da como resultado un código para una clase PHP que implementa CDbMigration
, CDbMigration
nombre exclusivo se basa en una marca de tiempo y un nombre de migración especificado por el usuario. Todas las migraciones que se han aplicado previamente a la base de datos se almacenan en una tabla de migración.
Para obtener más información, consulte el artículo sobre la migración de la base de datos del manual.
Mi equipo escribe todos los cambios en la base de datos y los confirma en SVN, junto con cada lanzamiento de la aplicación. Esto permite cambios incrementales de la base de datos, sin perder ningún dato.
Para pasar de una versión a la siguiente, solo necesita ejecutar el conjunto de scripts de cambio, y su base de datos está actualizada y todavía tiene todos sus datos. Puede que no sea el método más fácil, pero definitivamente es efectivo.
Para mi proyecto PHP actual utilizamos la idea de migraciones de rieles y tenemos un directorio de migraciones en el que guardamos el título de los archivos "migration_XX.sql" donde XX es el número de la migración. Actualmente, estos archivos se crean a mano a medida que se realizan las actualizaciones, pero su creación podría modificarse fácilmente.
Luego tenemos un script llamado "Migration_watcher" que, como estamos en pre-alpha, actualmente se ejecuta en cada carga de página y verifica si hay un nuevo archivo migration_XX.sql donde XX es más grande que la versión de migración actual. Si es así, ejecuta todos los archivos migration_XX.sql hasta el mayor número en la base de datos y ¡listo! Los cambios de esquema son automatizados.
Si necesita la capacidad de revertir el sistema, requerirá muchos ajustes, pero es simple y ha funcionado muy bien para nuestro equipo bastante pequeño hasta ahora.
Pruebe db-deploy, principalmente una herramienta Java, pero también funciona con php.
Recomendaría usar Ant (multiplataforma) para el lado de "secuencias de comandos" (ya que prácticamente puede hablar con cualquier base de datos a través de jdbc) y Subversion para el repositorio de origen. Ant le permitirá "hacer una copia de seguridad" de su base de datos en archivos locales, antes de realizar cambios. 1. copia de seguridad del esquema de db existente para archivar a través de Ant 2. control de versión al repositorio de Subversion a través de Ant 3. enviar nuevas instrucciones sql a db a través de Ant
Scott Ambler produce una gran serie de artículos (y es coautor de un book ) sobre refactorización de bases de datos, con la idea de que esencialmente debe aplicar los principios y prácticas de TDD para mantener su esquema. Configura una serie de pruebas de unidad de datos de estructura y semilla para la base de datos. Luego, antes de cambiar nada, modifica / escribe pruebas para reflejar ese cambio.
Hemos estado haciendo esto por un tiempo y parece funcionar. Escribimos código para generar comprobaciones básicas de nombre de columna y tipo de datos en un conjunto de pruebas unitarias. Podemos volver a ejecutar esas pruebas en cualquier momento para verificar que la base de datos en la comprobación de SVN coincida con la base de datos en vivo que la aplicación realmente está ejecutando.
Como resultado, los desarrolladores también a veces modifican su base de datos de sandbox y no actualizan el archivo de esquema en SVN. El código entonces depende de un cambio de base de datos que no se ha registrado. Ese tipo de error puede ser terriblemente difícil de precisar, pero el conjunto de pruebas lo detectará de inmediato. Esto es particularmente bueno si lo tiene integrado en un plan de integración continua más grande.
Si está utilizando C #, eche un vistazo a Subsonic, una herramienta ORM muy útil, pero también genera un script sql para recrear su esquema y / o datos. Estas secuencias de comandos se pueden poner en el control de origen.
Si todavía está buscando soluciones: estamos proponiendo una herramienta llamada neXtep designer. Es un entorno de desarrollo de bases de datos con el que puede poner toda su base de datos bajo control de versiones. Trabaja en un repositorio de versión controlada donde se puede rastrear cada cambio.
Cuando necesite lanzar una actualización, puede confirmar sus componentes y el producto generará automáticamente el script de actualización SQL de la versión anterior. Por supuesto, puede generar este SQL a partir de 2 versiones.
Entonces tiene muchas opciones: puede tomar esos scripts y ponerlos en su SVN con el código de su aplicación para que su mecanismo existente lo implemente. Otra opción es utilizar el mecanismo de entrega de neXtep: los scripts se exportan en algo llamado "paquete de entrega" (scripts SQL + descriptor XML), y un instalador puede comprender este paquete y desplegarlo en un servidor de destino a la vez que garantiza la coherencia y dependencia de la estructura. verificar, registrar la versión instalada, etc.
El producto es GPL y está basado en Eclipse, por lo que se ejecuta en Linux, Mac y Windows. También es compatible con Oracle, Mysql y Postgresql en este momento (el soporte de DB2 está en camino). Eche un vistazo a la wiki donde encontrará información más detallada: http://www.nextep-softwares.com/wiki
Toad for MySQL tiene una función llamada comparación de esquemas que le permite sincronizar 2 bases de datos. Es la mejor herramienta que he usado hasta ahora.
Utilizamos algo similar a bcwoord para mantener nuestros esquemas de base de datos sincronizados en 5 instalaciones diferentes (producción, puesta en escena y algunas instalaciones de desarrollo), y respaldados en el control de versiones, y funciona bastante bien. Voy a elaborar un poco:
Para sincronizar la estructura de la base de datos, tenemos un solo script, update.php, y varios archivos numerados 1.sql, 2.sql, 3.sql, etc. El script usa una tabla adicional para almacenar el número de versión actual del base de datos. Los archivos N.sql están diseñados a mano, para pasar de la versión (N-1) a la versión N de la base de datos.
Se pueden usar para agregar tablas, agregar columnas, migrar datos de un formato de columna antiguo a uno nuevo y luego soltar la columna, insertar filas de datos "maestros" como tipos de usuario, etc. Básicamente, puede hacer cualquier cosa y con los datos adecuados guiones de migración que nunca perderá datos.
El script de actualización funciona así:
- Conéctese a la base de datos.
- Haga una copia de seguridad de la base de datos actual (porque las cosas saldrán mal) [mysqldump].
- Cree una tabla de contabilidad (llamada _meta) si no existe.
- Lea la VERSIÓN actual de la tabla _meta. Suponga 0 si no se encuentra.
- Para todos los archivos .sql con un número superior a VERSION, ejecútelos en orden
- Si uno de los archivos produjo un error: regrese a la copia de seguridad
- De lo contrario, actualice la versión en la tabla de contabilidad al archivo .sql más alto ejecutado.
Todo pasa al control de la fuente, y cada instalación tiene un script para actualizar a la última versión con una sola ejecución del script (llamando a update.php con la contraseña de la base de datos adecuada, etc.). SVN actualiza los entornos de preparación y producción a través de un script que llama automáticamente al script de actualización de la base de datos, por lo que una actualización de código viene con las actualizaciones necesarias de la base de datos.
También podemos usar el mismo script para recrear toda la base de datos desde cero; simplemente soltamos y recreamos la base de datos, luego ejecutamos el script que repoblará completamente la base de datos. También podemos usar el script para llenar una base de datos vacía para pruebas automatizadas.
Tomó solo unas pocas horas configurar este sistema, es conceptualmente simple y todos obtienen el esquema de numeración de versiones, y ha sido invaluable para tener la capacidad de avanzar y evolucionar el diseño de la base de datos, sin tener que comunicar o ejecutar manualmente las modificaciones. en todas las bases de datos.
Sin embargo, ¡tenga cuidado al pegar consultas desde phpMyAdmin! Esas consultas generadas generalmente incluyen el nombre de la base de datos, que definitivamente no desea, ya que romperá sus scripts. Algo así como CREATE TABLE mydb
. newtable
(...) fallará si la base de datos en el sistema no se llama mydb. Creamos un mydb
SVN previo al comentario que no permitirá los archivos .sql que contengan la cadena mydb
, que es una señal segura de que alguien copió / pegó de phpMyAdmin sin una verificación adecuada.
Utilizamos una solución muy simple pero efectiva.
Para nuevas instalaciones, tenemos un archivo metadata.sql en el repositorio que contiene todo el esquema de base de datos, luego, en el proceso de compilación, usamos este archivo para generar la base de datos.
Para las actualizaciones, agregamos las actualizaciones en el software codificado. Lo mantenemos codificado porque no nos gusta resolver problemas antes de que realmente ES un problema, y este tipo de cosas no han demostrado ser un problema hasta ahora.
Entonces en nuestro software tenemos algo como esto:
RegisterUpgrade(1, ''ALTER TABLE XX ADD XY CHAR(1) NOT NULL;'');
Este código verificará si la base de datos está en la versión 1 (que se almacena en una tabla creada automáticamente), si está desactualizada, entonces se ejecuta el comando.
Para actualizar metadata.sql en el repositorio, ejecutamos estas actualizaciones localmente y luego extraemos los metadatos de la base de datos completa.
Lo único que sucede de vez en cuando es olvidar comprometer metadata.sql, pero este no es un problema importante porque es fácil de probar en el proceso de compilación y también lo único que podría suceder es hacer una nueva instalación con una base de datos desactualizada y la actualizó en el primer uso.
Además, no admitimos degradaciones, pero es por diseño, si algo se rompe en una actualización, restauramos la versión anterior y arreglamos la actualización antes de volver a intentarlo.
Vuelque su esquema en un archivo y agréguelo al control de origen. Luego, un simple diff le mostrará lo que cambió.