Saltar al contenido
← Ideas

Cambios de esquema en bases de datos: cómo desplegar sin detener el servicio

Aprende a desplegar cambios de esquema con versiones de aplicación coexistentes, validaciones y una retirada gradual para reducir interrupciones y riesgos.

Diagrama de una modificación de esquema desplegada en etapas, con versiones de aplicación coexistentes y retirada posterior del esquema antiguo.

Modificar una tabla puede parecer un cambio interno, pero una aplicación en producción rara vez tiene un único consumidor de la base de datos. Durante un despliegue pueden convivir versiones distintas del servicio; además, puede haber consultas de informes, integraciones o tareas programadas que dependan del esquema actual. Si una modificación deja de ser compatible con alguno de esos consumidores, el resultado puede ser un error visible o una interrupción.

La estrategia más segura no consiste en cambiar el esquema y el código a la vez, sino en separar el trabajo en pasos compatibles. Así, cada versión puede operar mientras se despliega la siguiente y se comprueba su comportamiento. Este enfoque no elimina todo riesgo: exige conocer las dependencias, observar el sistema y decidir de antemano cómo responder si algo falla.

Por qué una modificación pequeña puede romper el servicio

Por qué una modificación pequeña puede romper el servicio

El esquema es un contrato entre la base de datos y todo el software que la consulta. Una aplicación antigua puede esperar una columna que una migración elimina; una nueva puede asumir que ya existe una columna que todavía no se ha creado. Las dos situaciones son frecuentes cuando el despliegue de la aplicación y el de la base de datos no ocurren exactamente al mismo tiempo.

También importa cómo se ejecuta la operación. Según el motor y la modificación, un cambio puede bloquear escrituras, tardar en completarse o competir por recursos con la carga habitual. No des por hecho que una operación será instantánea o que tendrá el mismo impacto en todos los entornos. Comprueba el comportamiento para tu motor y versión, el tamaño y uso de las tablas y el mecanismo concreto de migración.

Antes de planificar, identifica quién lee y escribe los datos: versiones de la aplicación, servicios conectados, consultas de analítica, procesos por lotes, scripts y operaciones manuales. Revisa también las dependencias menos visibles, como procedimientos almacenados, vistas y restricciones. Si no puedes confirmar qué componentes usan un campo, no lo retires todavía.

Aplicar el patrón expandir y contraer

El patrón de expandir y contraer divide un cambio incompatible en fases. Primero se amplía el esquema de manera aditiva; después se despliega código que puede convivir con el anterior; por último, se elimina el elemento antiguo cuando ya no hay consumidores que lo necesiten. La compatibilidad entre etapas es la condición central: durante la transición, cada versión activa debe poder trabajar con el esquema disponible.

  1. Expandir: añade la nueva columna, tabla o estructura sin eliminar ni cambiar todavía la antigua. Evita introducir de entrada una restricción que los datos existentes o la aplicación antigua no puedan satisfacer.
  2. Preparar la aplicación: publica una versión capaz de manejar el esquema anterior y el nuevo según corresponda. Despliega gradualmente y confirma que las instancias antiguas dejan de estar activas antes de asumir que ya no hay lecturas o escrituras antiguas.
  3. Transicionar: cambia las lecturas o escrituras hacia la nueva representación. Si hace falta mantener ambas columnas, define cuál es la fuente de verdad y cómo se mantienen sincronizadas durante el intervalo.
  4. Contraer: tras verificar que el código y los procesos ya no usan el elemento antiguo, elimínalo en un cambio posterior. Esta fase debe ser independiente del despliegue que inició la transición.

Separar las fases permite que una aplicación desplegada de forma gradual no se encuentre de golpe con un esquema que aún no entiende. También hace más clara la respuesta ante problemas: a menudo se puede detener el cambio de código sin revertir de inmediato una ampliación compatible.

Cómo tratar columnas, renombrados y cambios de tipo

Columnas nuevas: añade primero la columna y despliega código que pueda funcionar si todavía no contiene el valor esperado. Después empieza a escribirla y valida que las nuevas escrituras se producen correctamente. Si hay que completar registros existentes, trata esa tarea como una operación separada: puede consumir tiempo y recursos, y conviene supervisar su avance. Solo cuando los datos estén preparados y el código lea el campo nuevo se puede considerar retirar el anterior.

Renombrados: un renombrado directo suele ser incompatible con versiones que todavía consultan el nombre antiguo. Es más seguro añadir una columna con el nombre nuevo, coordinar temporalmente las escrituras y mover las lecturas por etapas. Retira el nombre antiguo solo después de comprobar que ninguna versión activa ni proceso dependiente lo usa.

Cambios de tipo: no des por sentado que una conversión preservará todos los valores. Define qué ocurre con datos que no encajan, comprueba muestras y planifica una conversión que pueda controlarse y verificarse. Si el tipo nuevo requiere reglas más estrictas, valida los datos existentes antes de aplicarlas.

Restricciones y valores obligatorios: una columna que pasa a ser obligatoria puede fallar si aún hay filas sin valor o escritores que no lo proporcionan. Primero prepara datos y código; después aplica la restricción cuando puedas demostrar que se cumple. La secuencia exacta depende del motor de base de datos y de cómo gestione la validación y los bloqueos.

Validaciones antes, durante y después del despliegue

Una migración exitosa no se define solo porque la sentencia haya terminado. Comprueba que el comportamiento funcional y operativo sigue siendo correcto. Antes del cambio, registra el estado relevante para poder comparar y define qué señales justificarían detener el despliegue.

  • Compatibilidad: confirma qué versiones de aplicación estarán activas en cada etapa y prueba que pueden trabajar con el esquema correspondiente.
  • Datos: verifica recuentos, valores nulos y reglas de negocio pertinentes antes y después. Para una transformación, compara el resultado con criterios conocidos, no solo con la ausencia de errores.
  • Rendimiento: observa duración de la migración, bloqueos, carga y latencia de las operaciones afectadas. Si empeoran, detén la siguiente fase y evalúa el impacto antes de continuar.
  • Errores: revisa fallos en consultas, excepciones de la aplicación y errores en integraciones o trabajos programados. La ausencia de alarmas no prueba por sí sola que todos los consumidores estén cubiertos.
  • Uso del esquema antiguo: busca referencias en código y consultas, y comprueba durante un periodo adecuado si todavía hay lecturas o escrituras en el campo que se quiere retirar.

Ensaya el procedimiento en un entorno representativo cuando sea posible, incluidos los pasos de verificación. El ensayo ayuda a descubrir dependencias y operaciones lentas, aunque no garantiza que producción tenga la misma carga o distribución de datos. Asegura también que la migración sea identificable y que el equipo sepa quién decide continuar, pausar o revertir.

Reversión, corrección hacia delante y límites

Revertir una migración no siempre es seguro. Una ampliación aditiva suele ser más fácil de dejar intacta que de deshacer, especialmente si la aplicación ya ha escrito datos en la nueva columna. Eliminar esos datos para volver al estado anterior puede causar pérdida de información. Por eso, un plan de reversión debe explicar qué se revierte —el código, el esquema o ambos— y qué datos se conservarían.

Si las escrituras nuevas no se pueden traducir de forma fiable al esquema antiguo, puede ser más prudente detener el despliegue y preparar una corrección hacia delante. Define previamente el criterio de decisión: por ejemplo, errores en operaciones críticas, degradación sostenida o datos incoherentes. No prometas una reversión inmediata sin haber probado que es viable para ese cambio concreto.

Lista de comprobación para planificar el cambio

Lista de comprobación para planificar el cambio
  • ¿Están identificados todos los lectores, escritores y procesos que usan el esquema afectado?
  • ¿El cambio inicial es compatible con las versiones que seguirán activas durante el despliegue?
  • ¿Se han separado la ampliación, la transición de código y la retirada del elemento antiguo?
  • ¿Está definida la fuente de verdad si se mantienen dos representaciones temporalmente?
  • ¿Se han establecido comprobaciones de datos, errores y rendimiento, con responsables y criterios para pausar?
  • ¿El plan explica qué se puede revertir y cuándo será necesaria una corrección hacia delante?

Para responder a cómo cambiar el esquema de una base de datos sin detener el servicio, piensa en compatibilidad por etapas, no en una modificación aislada. Añade antes de retirar, mantén operativas las versiones que coexistan y valida cada transición con señales observables. Cuando el cambio no pueda hacerse de forma aditiva, identifica explícitamente el riesgo y prepara una ventana o estrategia de recuperación adecuada; no supongas que todo cambio admite un despliegue sin interrupciones.

Fuentes y referencias

  1. MDN Web DocsMozilla
  2. Web performanceweb.dev
  3. OWASP Cheat Sheet SeriesOWASP Foundation