Ha habido alguna discusión en la wiki de la comunidad SO sobre si los objetos de la base de datos deben ser controlados por versiones. Sin embargo, no he visto mucha discusión sobre las mejores prácticas para crear un proceso de automatización de compilación para objetos de base de datos.
Este ha sido un punto polémico de discusión para mi equipo, particularmente porque los desarrolladores y DBA a menudo tienen diferentes objetivos, enfoques y preocupaciones al evaluar los beneficios y riesgos de un enfoque de automatización para la implementación de bases de datos.
Me gustaría escuchar algunas ideas de la comunidad SO sobre qué prácticas han sido efectivas en el mundo real.
Me doy cuenta de que es algo subjetivo qué prácticas son realmente las mejores, pero creo que un buen diálogo sobre qué trabajo podría ser útil para muchas personas.
Estas son algunas de mis preguntas teaser sobre áreas de interés en este tema. No se pretende que sean una lista definitiva, sino un punto de partida para que las personas me ayuden a comprender lo que estoy buscando.
- ¿Deben construirse tanto los entornos de prueba como los de producción a partir del control de código fuente?
- ¿Deben construirse ambos utilizando la automatización, o la producción debe construirse copiando objetos de un entorno de prueba finalizado y estable?
- ¿Cómo maneja las posibles diferencias entre los entornos de prueba y producción en los scripts de implementación?
- ¿Cómo se prueba que los scripts de implementación funcionarán con la misma eficacia en la producción que en la prueba?
- ¿Qué tipos de objetos deben controlarse por versión?
- ¿Solo código (procedimientos, paquetes, activadores, java, etc.)?
- Índices?
- Restricciones?
- Definiciones de tablas
- ¿Scripts de cambio de tabla? (por ejemplo, secuencias de comandos ALTER)
- ¿Todo?
- ¿Qué tipos de objetos no deberían controlarse por versión?
- Secuencias
- ¿Subsidios?
- ¿Cuentas de usuario?
- ¿Cómo deberían organizarse los objetos de la base de datos en su repositorio de SCM?
- ¿Cómo maneja cosas únicas como scripts de conversión o scripts ALTER?
- ¿Cómo maneja la retirada de objetos de la base de datos?
- ¿Quién debería ser responsable de promover los objetos desde el desarrollo hasta el nivel de prueba?
- ¿Cómo coordinas los cambios de varios desarrolladores?
- ¿Cómo maneja la ramificación de los objetos de base de datos utilizados por múltiples sistemas?
- ¿Qué excepciones, si las hay, pueden hacerse razonablemente a este proceso?
- ¿Temas de seguridad?
- ¿Datos con problemas de desidentificación?
- ¿Secuencias de comandos que no se pueden automatizar por completo?
- ¿Cómo puede hacer que el proceso sea resistente y ejecutable?
- ¿Al error del desarrollador?
- ¿A problemas medioambientales inesperados?
- ¿Para recuperación ante desastres?
- ¿Cómo convence a los responsables de la toma de decisiones de que los beneficios de DB-SCM realmente justifican el costo?
- ¿Evidencia anecdótica?
- ¿Investigación de la industria?
- ¿Recomendaciones de mejores prácticas de la industria?
- ¿Apelaciones a autoridades reconocidas?
- ¿Análisis coste-beneficio?
- ¿Quién debería "poseer" los objetos de la base de datos en este modelo?
- Desarrolladores?
- DBA?
- Analistas de datos?
- ¿Más de uno?
fuente
Respuestas:
Aquí hay algunas respuestas a sus preguntas:
fuente
Trato el SQL como código fuente cuando es posible
Si puedo escribirlo en SQL compatible con el estándar, generalmente va en un archivo en mi control de código fuente. El archivo definirá tanto como sea posible, como SP, declaraciones CREATE de tabla.
También incluyo datos ficticios para probar en control de fuente:
Y luego abstraigo todas mis consultas SQL para poder construir el proyecto completo para MySQL, Oracle, MSSQL o cualquier otra cosa.
La automatización de compilación y prueba utiliza estos scripts de compilación, ya que son tan importantes como la fuente de la aplicación y prueba todo, desde la integridad hasta los desencadenantes, los procedimientos y el registro.
fuente
Utilizamos la integración continua a través de TeamCity. En cada registro en el control de fuente, la base de datos y todos los datos de prueba se reconstruyen desde cero, luego el código, luego las pruebas unitarias se ejecutan contra el código. Si está utilizando una herramienta de generación de código como CodeSmith, también se puede colocar en su proceso de compilación para generar su capa de acceso a los datos con cada compilación, asegurándose de que todas sus capas "coincidan" y no produzcan errores debido a parámetros de SP no coincidentes o columnas faltantes.
Cada compilación tiene su propia colección de scripts SQL que se almacenan en el directorio $ project \ SQL \ en el control de código fuente, se les asigna un prefijo numérico y se ejecutan en orden. De esa manera, practicamos nuestro procedimiento de implementación en cada compilación.
Dependiendo de la tabla de búsqueda, la mayoría de nuestros valores de búsqueda también se almacenan en scripts y se ejecutan para asegurarse de que los datos de configuración sean los que esperamos para, digamos, "código_razón" o "código_país". De esta forma podemos realizar un cambio de búsqueda de datos en el desarrollo, probarlo y luego "promoverlo" a través del control de calidad y la producción, en lugar de utilizar una herramienta para modificar los valores de búsqueda en producción, lo que puede ser peligroso para el tiempo de actividad.
También creamos un conjunto de scripts de "reversión" que deshacen los cambios de nuestra base de datos, en caso de que una compilación para producción salga mal. Puede probar los scripts de reversión ejecutándolos y luego volver a ejecutar las pruebas unitarias para la versión de compilación una debajo de la suya, después de que se ejecuten sus scripts de implementación.
fuente
+1 para Liquibase : LiquiBase es una biblioteca de código abierto (LGPL), independiente de la base de datos para rastrear, administrar y aplicar cambios en la base de datos. Se basa en una premisa simple: todos los cambios de la base de datos (estructura y datos) se almacenan de una manera descriptiva basada en XML y se registran en el control de fuente. El buen punto es que los cambios de DML se almacenan semánticamente, no solo diff, para que pueda rastrear el propósito de los cambios.
Se podría combinar con el control de versiones GIT para una mejor interacción. Voy a configurar nuestro entorno dev-prod para probarlo.
También puede usar Maven, los sistemas de compilación Ant para compilar código de producción a partir de scripts.
El inconveniente es que LiquiBase no se integra en los IDE de SQL generalizados y debe realizar las operaciones básicas usted mismo.
Además de esto, puede usar DBUnit para pruebas de bases de datos: esta herramienta permite que los scripts de generación de datos se utilicen para probar su entorno de producción con limpieza posterior.
EN MI HUMILDE OPINIÓN:
Enfrentamos todos los problemas mencionados con cambios de código, fusión y reescritura en nuestra base de datos de producción de facturación. Este tema es genial para descubrir todas esas cosas.
fuente
Al hacer "preguntas teaser", parece estar más interesado en una discusión que en la opinión de alguien sobre las respuestas finales. La lista de correo activa (> 2500 miembros) agileDatabases ha abordado muchas de estas preguntas y es, en mi experiencia, un foro sofisticado y civil para este tipo de discusión.
fuente
Básicamente estoy de acuerdo con todas las respuestas dadas por van . Para obtener más información, mi línea de base para la gestión de bases de datos es la serie de K. Scott Allen (una lectura obligada, en mi humilde opinión. Y la opinión de Jeff también parece).
Create.sql
. Esto puede incluir la inserción de datos estáticos (listas ...).Create.sql
:Create.cmd
. Su objetivo es principalmente verificar los requisitos previos (herramientas, variables de entorno ...) y enviar parámetros al script SQL. También puede cargar datos estáticos de archivos CSV de forma masiva por problemas de rendimiento.Create.cmd
archivo.En mi humilde opinión, la carga dinámica de datos debería requerir otro paso, dependiendo de su entorno. Los desarrolladores querrán cargar su base de datos con prueba, basura o ningún dato, mientras que en el otro extremo los gerentes de producción querrán cargar datos de producción. También consideraría almacenar datos de prueba en el control de fuente (para facilitar las pruebas unitarias, por ejemplo).
Una vez que la primera versión de la base de datos se haya puesto en producción, no solo necesitará crear scripts (principalmente para desarrolladores), sino también actualizar los scripts (basados en los mismos principios):
Upgrade.sql
archivo (que puede llamar a otros) que permite actualizar la versión N-1 a la versión N (siendo N la versión que se lanza). Guardo este script en una carpeta llamadaN-1
.Upgrade.cmd
. Puede recuperar la versión actual (CV) de la base de datos a través de una simple instrucción SELECT, iniciar elUpgrade.sql
script almacenado en laCV
carpeta y repetir hasta que no se encuentre ninguna carpeta. De esta manera, puede actualizar automáticamente de, digamos, N-3 a N.Los problemas con esto son:
¿En cuanto a qué tipo de objetos de la base de datos desea tener bajo control de código fuente? Bueno, diría tanto como sea posible, pero no más ;-) Si desea crear usuarios con contraseñas, consígales una contraseña predeterminada (inicio de sesión / inicio de sesión, práctica para propósitos de prueba de unidades) y haga que el cambio de contraseña sea una operación manual . Esto sucede mucho con Oracle donde los esquemas también son usuarios ...
fuente
Tenemos nuestro proyecto Silverlight con base de datos MSSQL en control de versiones Git. La forma más sencilla es asegurarse de tener una base de datos reducida (en cuanto al contenido) y hacer un volcado completo de fe Visual Studio. Luego puede hacer 'sqlcmd' desde su script de compilación para recrear la base de datos en cada máquina de desarrollo.
Para la implementación, esto no es posible porque las bases de datos son demasiado grandes: esa es la razón principal para tenerlas en una base de datos en primer lugar.
fuente
Creo firmemente que una base de datos debería ser parte del control de código fuente y, en gran medida, parte del proceso de construcción. Si está en control de fuente, tengo las mismas protecciones de codificación cuando escribo un procedimiento almacenado en SQL que cuando escribo una clase en C #. Hago esto al incluir un directorio de scripts de base de datos debajo de mi árbol de fuentes. Este directorio de scripts no tiene necesariamente un archivo para un objeto en la base de datos. ¡Eso sería un dolor en el trasero! Desarrollo en mi base de datos solo lo haría en mi proyecto de código. Luego, cuando estoy listo para registrarme, hago una diferencia entre la última versión de mi base de datos y la actual en la que estoy trabajando. Utilizo SQL Compare para esto y genera un script de todos los cambios. Luego, este script se guarda en mi directorio db_update con una convención de nomenclatura específica 1234_TasksCompletedInThisIteration donde el número es el siguiente número en el conjunto de scripts que ya están allí, y el nombre describe lo que se está haciendo en este registro. Hago esto de esta manera porque como parte de mi proceso de compilación, comienzo con una base de datos nueva que luego se construye programáticamente usando los scripts en este directorio. Escribí una tarea NAnt personalizada que itera a través de cada script ejecutando su contenido en la base de datos. Obviamente, si necesito algunos datos para ingresar a la base de datos, también tengo scripts de inserción de datos. Esto también tiene muchos beneficios. Uno, todas mis cosas están versionadas. Dos, cada compilación es una compilación nueva, lo que significa que no habrá cosas furtivas que se abran paso en mi proceso de desarrollo (como datos sucios que causan rarezas en el sistema). Tres, cuando se agrega un nuevo chico al equipo de desarrollo, simplemente necesitan obtener lo último y su desarrollador local está construido para ellos sobre la marcha. Cuatro, puedo ejecutar casos de prueba (¡no lo llamé "prueba unitaria"!) En mi base de datos, ya que el estado de la base de datos se restablece con cada compilación (lo que significa que puedo probar mis repositorios sin preocuparme por agregar datos de prueba al db).
Esto no es para todos.
Esto no es para todos los proyectos. ¡Normalmente trabajo en proyectos de campo verde, lo que me permite esta comodidad!
fuente
En lugar de entrar en argumentos de torre blanca, aquí hay una solución que me ha funcionado muy bien en problemas del mundo real.
La creación de una base de datos desde cero se puede resumir en la gestión de scripts SQL.
DBdeploy es una herramienta que comprobará el estado actual de una base de datos, por ejemplo, qué scripts se han ejecutado previamente en ella, qué scripts están disponibles para ejecutar y, por lo tanto, qué scripts se necesitan para ejecutar.
Luego, recopilará todos los scripts necesarios y los ejecutará. Luego registra qué scripts se han ejecutado.
No es la herramienta más bonita ni la más compleja, pero con una gestión cuidadosa puede funcionar muy bien. Es de código abierto y fácilmente extensible. Una vez que la ejecución de los scripts se maneja bien, se pueden agregar fácilmente algunos componentes adicionales, como un script de shell que verifica los últimos scripts y ejecuta dbdeploy contra una instancia en particular.
Vea una buena introducción aquí:
http://code.google.com/p/dbdeploy/wiki/GettingStarted
fuente
Puede encontrar que Liquibase maneja mucho de lo que está buscando.
fuente
Cada desarrollador debe tener su propia base de datos local y usar el control del código fuente para publicar en el equipo. Mi solución está aquí: http://dbsourcetools.codeplex.com/ Diviértete, - Nathan
fuente