español - oracle sql developer
¿Cómo se gestionan las actualizaciones de esquema a una base de datos de producción? (8)
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 (ha), solo confirmo los cambios de esquema como archivos de texto SQL en un repositorio de CVS, que reviso en lotes en el servidor de producción cuando los cambios de código entran .
¡Pero liquibase está mejor organizado que eso!
Esta parece ser un área pasada por alto que realmente podría usar alguna información. ¿Cuáles son sus mejores prácticas para:
- haciendo un procedimiento de actualización
- retrocediendo en caso de errores
- código de sincronización y cambios en la base de datos
- prueba antes de la implementación
- Mecánica de modificar la tabla
etc ...
En general, mi regla es: "La aplicación debe gestionar su propio esquema".
Esto significa que los scripts de actualización de esquema son parte de cualquier paquete de actualización para 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 de modificación completo al esquema (esto molesta a los DBA).
He tenido un gran éxito al utilizar la función Hibernates SchemaUpdate para administrar las estructuras de la tabla. Dejando los scripts de actualización solo para manejar la inicialización de los datos reales y la eliminación ocasional de las columnas (SchemaUpdate no hace eso).
Con respecto 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.
Pensamiento de último momento: teniendo en cuenta algunas de las críticas en otros mensajes aquí, tenga en cuenta que la regla dice "es propio". Solo se aplica realmente cuando la aplicación posee el esquema, como generalmente ocurre con el software vendido como producto. Si su software comparte una base de datos con otro software, use otros métodos.
Esa es una gran pregunta. (Hay una gran posibilidad de que esto termine en un debate de base de datos normalizado versus denormalizado ... que no voy a comenzar ... está bien ahora para obtener información).
algunas cosas fuera de mi cabeza cosas que he hecho (agregarán más cuando tenga algo más de tiempo o necesite un descanso)
diseño del cliente: aquí es donde el método VB de sql en línea (incluso con declaraciones preparadas) le ocasiona problemas. Puede gastar EDAD solo encontrando esas declaraciones. Si usa algo como Hibernate y pone tanto SQL en consultas con nombre, tiene un lugar único para la mayoría de los sql (nada peor que tratar de probar sql que está dentro de alguna instrucción IF y simplemente no toca 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 o ODBC, ponía todas las sentencias sql como campos públicos de un objeto (con una convención de nomenclatura) o en un archivo de propiedad (también con un nombre) La convención para los valores dice PREP_STMT_xxxx. Y usa ya sea reflexión o iteración sobre los valores al inicio en a) casos de prueba b) inicio de la aplicación (algunos rdbms te permiten precompilar con declaraciones preparadas antes de la ejecución, así que al inicio Precompilaría las prep-stmts al inicio para que la aplicación se autodiagnostique. Incluso para las declaraciones de 100 en un rdbms bueno solo son unos pocos segundos. Y solo una vez. Y me ha salvado mucho el trasero. En un proyecto, el DBA no se comunicaba (un equipo diferente, en un país diferente) y el esquema parecía cambiar NOCHE, sin ningún motivo. Y cada mañana recibimos una lista de dónde exactamente rompió la aplicación, al inicio.
Si necesita funcionalidad adhoc, colóquela en una clase bien nombrada (es decir, una vez más, una convención de nomenclatura ayuda con las pruebas automáticas) que actúa como una especie de fábrica para su consulta (es decir, genera la consulta). Vas a tener que escribir el código equivalente de todos modos, solo ponlo en un lugar donde puedes probarlo. Incluso puede escribir algunos métodos de prueba básicos en el mismo objeto o en una clase separada.
Si puede, intente usar procedimientos almacenados. Son un poco más difíciles de probar que los anteriores. Algunos db tampoco validan previamente el sql en los procesos almacenados contra el esquema en tiempo de compilación solo en tiempo de ejecución. Normalmente implica, por ejemplo, tomar una copia de la estructura de esquema (sin datos) y luego crear todos los procesos almacenados contra esta copia (en caso de que el equipo de db que realiza los cambios no valide correctamente). Por lo tanto, la estructura se puede verificar. pero como punto de cambio, los procesos almacenados de administración son geniales. En cambio todos lo entienden Especialmente cuando los cambios de db son el resultado de cambios en el proceso de negocios. 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 guardamos un identificador VERSION. 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 desea permitir que los clientes se conecten si pueden dañar su esquema (es decir, no tiene muchas reglas referenciales en el DB, sino en el cliente). Depende si también vas a tener múltiples versiones de cliente (lo que sucede en aplicaciones que no son web, es decir, están ejecutando el binario incorrecto). También podría tener herramientas por lotes, etc. Otro enfoque que también he hecho es definir un conjunto de esquemas para las versiones de operación en algún tipo de archivo de propiedades o de nuevo en una tabla system_info. Esta tabla se carga al iniciar sesión, y luego la usa cada "administrador" (normalmente tengo algún tipo de API del lado del cliente para hacer la mayoría de las cosas del DB) 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 (arrojar alguna excepción) en métodos desactualizados y le dice POR QUÉ.
gestionar el cambio a esquema -> ¿actualizas la tabla o agregas relaciones 1-1 a nuevas tablas? 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, columnas, etc. He jugado con la idea de tratar vistas como interfaces en COM. es decir. agrega una nueva VISTA para nuevas funcionalidades / versiones. A menudo, lo que lo lleva 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 de cliente existentes (recuerde todos esos molestos informes adhoc).
Además, necesita escribir secuencias de comandos de actualización y retrotracción. y nuevamente TEST, TEST, TEST ...
------------ OKAY - ESTE ES UN TIEMPO DE DISCUSIÓN ALEATORIO BIT --------------
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 usaban un producto un poco como PHP pero pre-php. La misma cosa. nombre diferente. de todos modos entré en la versión 2 ...
Le costaba MUCHO DINERO hacer actualizaciones. Mucho. es decir. regalar 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 en común donde podíamos administrar el código. pero otras áreas fueron este marcado sql incorporado en html. Lo cual fue genial para llegar al mercado rápidamente, pero con cada interacción de nuevas funciones, el costo al menos se duplicó para probar y mantener. Así que cuando estábamos buscando sacar el código de tipo php, poner capas de datos (esto fue 2001-2002, antes de cualquier ORM, etc.) y agregar muchas características nuevas (comentarios de los clientes) miramos este problema de cómo diseñar UPGRADES en el sistema. Lo cual es un gran problema, ya que las actualizaciones cuestan mucho dinero para hacerlo correctamente. Ahora, la mayoría de los patrones y todas las demás cosas que la gente discute con un grado de energía trata con el código OO que se está ejecutando, pero ¿qué pasa con el hecho de que sus datos deben 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 los datos, terminas con una gran cantidad de subprocesos / aplicaciones en la organización de tus clientes que necesitan esa información: informes ad hoc o cualquier informe personalizado complejo, así como trabajos por lotes que se han hecho para los datos de alimentación personalizados, etc.
Con esto en mente, comencé a jugar con algo un poco dejado de campo. También tiene algunas suposiciones. a) los datos se leen mucho más que escribir. b) las actualizaciones suceden, pero no en niveles bancarios, es decir. uno o dos por segundo.
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 CONCRETAS (que variaban con los cambios de esquema). Puede crear una vista separada para cada operación de tipo: actualizar, eliminar, insertar y leer. Esto es importante. Las vistas se asignarían directamente a una tabla, o le permitirían desencadenar una tabla ficticia que realice las actualizaciones o inserciones reales, etc. Lo que en realidad quería era algún tipo de indirección de nivel capturable que aún pudiera ser utilizada por los informes cristalinos, etc. NOTA - Para inserciones, actualizaciones y eliminaciones, también puede usar procs almacenados. Y tuviste una versión para cada versión del producto. De esta forma, su versión 1.0 tenía su versión del esquema, y si las tablas cambiaban, todavía tendría las versiones de la versión 1.0 pero con NUEVA lógica backend para asignar a las nuevas tablas según sea necesario, pero también tenía vistas de la versión 2.0 que soportarían nuevos campos, etc. Esto fue solo para respaldar los informes ad hoc, que si eres una persona de NEGOCIOS y no un codificador, probablemente sea el objetivo de por qué tienes el producto. (Su producto puede ser una porquería, pero si tiene la mejor información del mundo aún puede ganar, lo contrario es cierto: su producto puede ser la mejor opción en cuanto a características, pero si es peor al informar puede perderse muy fácilmente).
de acuerdo, espero que algunas de esas ideas te ayuden.
Escuché cosas buenas sobre el sistema de migración de esquemas iBATIS 3 :
Guía del usuario: http://svn.apache.org/repos/asf/ibatis/java/ibatis-3/trunk/doc/en/iBATIS-3-Migrations.pdf
Estos son todos los temas de peso, pero esta es mi recomendación para la actualización.
No especificó su plataforma, pero para los entornos de compilación NANT utilizo Tarantino . Para cada actualización de base de datos que esté listo para comprometerse, se crea una secuencia de comandos de cambio (usando RedGate u otra herramienta). Cuando compila a producción, Tarantino comprueba si el script se ejecutó en la base de datos (agrega una tabla a su base de datos para realizar un seguimiento). Si no, la secuencia de comandos se ejecuta. Se necesita todo el trabajo manual (léase: error humano) para gestionar las versiones de la base de datos.
liquibase.org:
- entiende las definiciones de hibernación.
- genera una mejor actualización de esquema sql que hibernate
- registra qué actualizaciones se han realizado en una base de datos
- maneja cambios de dos pasos (es decir, elimina una columna "foo" y luego cambia el nombre de una columna diferente a "foo")
- maneja el concepto de actualizaciones condicionales
- el desarrollador realmente escucha a la comunidad (con hibernación si no estás en el grupo de "adentro" o un novato, básicamente eres ignorado).
opinión
la aplicación nunca debe manejar una actualización de esquema. Este es un desastre esperando a suceder. Los datos duran más que las aplicaciones y, en el momento en que varias aplicaciones intentan trabajar con los mismos datos (la aplicación de producción + una aplicación de informes, por ejemplo), es probable que ambos utilicen las mismas bibliotecas subyacentes de la empresa ... y luego ambos programas deciden hacer su propia actualización de db ... divertirse con ese desastre.