¿Cómo se gestionan las actualizaciones de esquemas en una base de datos de producción?

StackOverflow https://stackoverflow.com/questions/29744

  •  09-06-2019
  •  | 
  •  

Pregunta

Ésta parece ser un área que se pasa por alto y que realmente necesitaría algo de información.¿Cuáles son sus mejores prácticas para:

  • realizar un procedimiento de actualización
  • retroceder en caso de errores
  • sincronización de código y cambios de base de datos
  • pruebas antes de la implementación
  • mecánica de modificación de la mesa

etc...

¿Fue útil?

Solución

Esa es una gran pregunta.(Existe una alta probabilidad de que esto termine en un debate sobre bases de datos normalizadas versus desnormalizadas... que no voy a comenzar...está bien ahora para algunos comentarios.)

algunas cosas que se me vienen a la cabeza que he hecho (agregaré más cuando tenga más tiempo o necesite un descanso)

diseño de cliente: aquí es donde el método VB de sql en línea (incluso con declaraciones preparadas) le mete en problemas.Puedes gastar AÑOS simplemente encontrando esas declaraciones.Si usa algo como Hibernar y coloca tanto SQL en consultas con nombre, tendrá un solo lugar para la mayor parte del SQL (nada peor que intentar probar el SQL que está dentro de alguna declaración IF y simplemente no presiona el "disparador"). criterios en su prueba para esa declaración IF).Antes de usar hibernación (u otros orms), cuando hacía SQL directamente en JDBC u ODBC, colocaba todas las declaraciones SQL como campos públicos de un objeto (con una convención de nomenclatura) o en un archivo de propiedades (también con una convención de nomenclatura). La convención para los valores dice PREP_STMT_xxxx.Y use reflexión o itere sobre los valores al inicio en a) casos de prueba b) inicio de la aplicación (algunos rdbms le permiten precompilar con declaraciones preparadas antes de la ejecución, por lo que al iniciar sesión después del inicio de sesión, precompilaría la preparación). stmts al inicio para que la aplicación se autopruebe.Incluso para cientos de declaraciones en un buen rdbms, eso es solo unos segundos.y sólo una vez.Y me ha salvado mucho el trasero.En un proyecto, los DBA no se comunicaban (un equipo diferente, en un país diferente) y el esquema parecía cambiar TODAS LAS NOCHES, sin ningún motivo.Y cada mañana recibimos una lista de exactamente dónde falló la aplicación al iniciarse.

Si necesita una funcionalidad ad hoc, colóquela en una clase bien nombrada (es decir,Nuevamente, una convención de nomenclatura ayuda con las pruebas automatizadas) que actúa como una especie de fábrica para su consulta (es decir,construye la consulta).De todos modos, tendrás que escribir el código equivalente, simplemente colócalo en un lugar donde puedas probarlo.Incluso puedes escribir algunos métodos de prueba básicos en el mismo objeto o en una clase separada.

Si puede, intente también utilizar procedimientos almacenados.Son un poco más difíciles de probar que los anteriores.Algunas bases de datos tampoco validan previamente el SQL en los procesos almacenados con el esquema en tiempo de compilación, solo en tiempo de ejecución.Por lo general, implica, por ejemplo, tomar una copia de la estructura del esquema (sin datos) y luego crear todos los procesos almacenados en esta copia (en caso de que el equipo de base de datos que realizó los cambios no validó correctamente).De este modo se puede comprobar la estructura.pero como punto de gestión de cambios, los procesos almacenados son excelentes.Al cambiar, todos lo entienden.Especialmente cuando los cambios en la base de datos son el resultado de cambios en los procesos comerciales.Y todos los idiomas (java, vb, etc. obtienen el cambio)

Normalmente también configuro una tabla que uso llamada system_setting, etc.En esta tabla mantenemos un identificador de VERSIÓN.Esto es para que las bibliotecas cliente puedan conectarse y validar si son válidas para esta versión del esquema.Dependiendo de los cambios en su esquema, no querrá permitir que los clientes se conecten si pueden dañar su esquema (es decir,no tienes muchas reglas de referencia en la base de datos, sino en el cliente).Depende de si también va a tener varias versiones de cliente (lo que sucede en aplicaciones NO web, es decir.están ejecutando el binario incorrecto).También podría tener herramientas por lotes, etc.Otro enfoque que también he realizado es definir un conjunto de esquemas para operar versiones en algún tipo de archivo de propiedades o nuevamente en una tabla system_info.Esta tabla se carga al iniciar sesión y luego la usa cada "administrador" (generalmente tengo algún tipo de API del lado del cliente para hacer la mayoría de las cosas de la base de datos) para validar esa operación si es la versión correcta.Por lo tanto, la mayoría de las operaciones pueden tener éxito, pero también puede fallar (lanzar alguna excepción) en métodos desactualizados y le indica POR QUÉ.

gestionando el cambio al esquema -> ¿actualiza la tabla o agrega relaciones 1-1 a las tablas nuevas?He visto muchas tiendas que siempre acceden a los datos a través de una vista por este motivo.Esto permite cambiar los nombres de las tablas, las columnas, etc.He jugado con la idea de tratar las vistas como interfaces en COM.es decir.agrega una nueva VISTA para nuevas funcionalidades/versiones.A menudo, lo que le trae aquí es que puede tener muchos informes (especialmente informes personalizados del usuario final) que asumen formatos de tabla.Las vistas le permiten implementar un nuevo formato de tabla pero admiten aplicaciones cliente existentes (recuerde todos esos molestos informes ad hoc).

Además, es necesario escribir scripts de actualización y reversión.y otra vez PRUEBA, PRUEBA, PRUEBA...

------------ BIEN - ESTE ES UN TIEMPO DE DISCUSIÓN UN POCO ALEATORIO --------------

En realidad tenía un gran proyecto comercial (es decir.tienda de software) donde tuvimos el mismo problema.La arquitectura era de 2 niveles y estaban usando un producto un poco parecido a PHP pero anterior a PHP.La misma cosa.nombre diferente.de todos modos entré en la versión 2....

Estaba costando MUCHO DINERO hacer actualizaciones.Mucho.es decir.Regale semanas de tiempo de consulta gratuita en el sitio.

Y estaba llegando al punto de querer agregar nuevas funciones u optimizar el código.Parte del código existente usaba procedimientos almacenados, por lo que teníamos puntos comunes donde podíamos administrar el código.pero otras áreas eran este marcado SQL incrustado en HTML.Lo cual fue excelente para llegar al mercado rápidamente, pero con cada interacción de nuevas funciones, el costo de prueba y mantenimiento al menos se duplicó.Entonces, cuando estábamos buscando extraer el código de tipo php, colocar capas de datos (esto fue 2001-2002, antes de cualquier ORM, etc.) y agregar muchas características nuevas (comentarios de los clientes), analizamos este problema de cómo diseñar ACTUALIZACIONES. en el sistema.Lo cual es un gran problema, ya que realizar las actualizaciones correctamente cuesta mucho dinero.Ahora, la mayoría de los patrones y todas las demás cosas que la gente discute con cierto grado de energía tienen que ver con el código OO que se está ejecutando, pero ¿qué pasa con el hecho de que sus datos tienen que a) integrarse a esta lógica, b) el significado y también la estructura de los datos pueden cambiar con el tiempo y, a menudo, debido a la forma en que funcionan, terminas con una gran cantidad de subprocesos/aplicaciones en la organización de tu cliente que necesitan esos datos -> informes ad hoc o cualquier informe personalizado complejo, así como trabajos por lotes. que se han realizado para fuentes de datos personalizadas, etc.

Con esto en mente, comencé a jugar con algo un poco fuera de lugar.También tiene algunas suposiciones.a) los datos se leen mucho más que se escriben.b) las actualizaciones ocurren, pero no a nivel bancario, es decir.uno o dos por segundo dicen.

La idea era aplicar una vista COM/Interfaz a cómo los clientes accedían a los datos a través de un conjunto de tablas CONCRETE (que variaban con los cambios de esquema).Puede crear una vista separada para cada tipo de operación: actualizar, eliminar, insertar y leer.Esto es importante.Las vistas se asignarían directamente a una tabla o le permitirían activar una tabla ficticia que realiza las actualizaciones o inserciones reales, etc.Lo que realmente quería era algún tipo de dirección indirecta de nivel atrapable que aún pudiera ser utilizada por informes de cristal, etc.NOTA: para inserciones, actualizaciones y eliminaciones, también puede utilizar procesos almacenados.Y tenías una versión para cada versión del producto.De esa manera, su versión 1.0 tenía su versión del esquema, y ​​si las tablas cambiaban, todavía tendría las VISTAS de la versión 1.0 pero con una NUEVA lógica de backend para asignar a las nuevas tablas según fuera necesario, pero también tenía vistas de la versión 2.0 que soportarían nuevos campos, etc.En realidad, esto fue solo para respaldar los informes ad hoc, lo cual, si eres una persona de NEGOCIOS y no un codificador, probablemente sea la razón por la que tienes el producto.(su producto puede ser una mierda, pero si tiene los mejores informes del mundo aún puede ganar, lo contrario es cierto: su producto puede tener la mejor característica en cuanto a características, pero si es el peor en los informes, puede perder muy fácilmente).

Bien, espero que algunas de esas ideas ayuden.

Otros consejos

Liquibase

liquibase.org:

  1. entiende las definiciones de hibernación.
  2. genera una mejor actualización de esquema sql que hibernar
  3. registra qué actualizaciones se han realizado en una base de datos
  4. maneja cambios de dos pasos (es decir,eliminar una columna "foo" y luego cambiar el nombre de una columna diferente a "foo")
  5. maneja el concepto de actualizaciones condicionales
  6. el desarrollador realmente escucha a la comunidad (con hibernación si no estás entre la multitud "de moda" o eres un novato, básicamente te ignoran).

http://www.liquibase.org

opinión

la aplicación debe nunca manejar una actualización de esquema.Este es un desastre esperando a suceder.Los datos duran más que las aplicaciones y tan pronto como varias aplicaciones intentan trabajar con los mismos datos (la aplicación de producción + una aplicación de informes, por ejemplo), es probable que ambas utilicen las mismas bibliotecas subyacentes de la empresa...y luego ambos programas deciden hacer su propia actualización de la base de datos...divertirse con eso desorden.

Yo soy un gran fan de puerta roja Productos que ayudan a crear paquetes SQL para actualizar esquemas de bases de datos.Los scripts de la base de datos se pueden agregar al control de código fuente para ayudar con el control de versiones y la reversión.

En general mi regla es:"La aplicación debe gestionar su propio esquema".

Esto significa que los scripts de actualización del esquema forman parte de cualquier paquete de actualización de la aplicación y se ejecutan automáticamente cuando se inicia la aplicación.En caso de errores, la aplicación no se inicia y la transacción del script de actualización no se confirma.La desventaja de esto es que la aplicación debe tener acceso completo a la modificación del esquema (esto molesta a los DBA).

He tenido gran éxito al utilizar la función SchemaUpdate de Hibernates para administrar las estructuras de las tablas.Dejar que los scripts de actualización solo manejen la inicialización de datos reales y la eliminación ocasional de columnas (SchemaUpdate no hace eso).

En cuanto a las pruebas, dado que las actualizaciones son parte de la aplicación, probarlas se convierte en parte del ciclo de prueba de la aplicación.

Idea tardía:Teniendo en cuenta algunas de las críticas de otras publicaciones aquí, tenga en cuenta que la regla dice "es propia".Realmente sólo se aplica cuando la aplicación posee el esquema como suele ser el caso con el software vendido como producto.Si su software comparte una base de datos con otro software, utilice otros métodos.

Todos estos son temas importantes, pero aquí está mi recomendación para actualizar.

No especificaste tu plataforma, pero para entornos de compilación NANT uso Tarantino.Para cada actualización de la base de datos que esté listo para confirmar, realice un script de cambio (usando RedGate u otra herramienta).Cuando construyes en producción, Tarantino verifica si el script se ha ejecutado en la base de datos (agrega una tabla a tu base de datos para realizar un seguimiento).En caso contrario, se ejecuta el script.Se necesita todo el trabajo manual (lea:error humano) fuera de la gestión de versiones de bases de datos.

Como dijo Pat, usa liquibase.Especialmente cuando tiene varios desarrolladores con sus propias bases de datos de desarrollo que realizan cambios que se convertirán en parte de la base de datos de producción.

Si solo hay un desarrollador, como en un proyecto en el que estoy ahora (ja), simplemente envío los cambios de esquema como archivos de texto SQL en un repositorio CVS, que reviso en lotes en el servidor de producción cuando entran los cambios de código. .

¡Pero liquibase está mejor organizado que eso!

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top