Parte 2: El nuevo manual de Jen
por Pramod Sadalage y Kevin Hartman
Esta serie revisa la metodología de Evolutionary Database Design, veinte años después. Una limitación clave para los cambios de base de datos como código siempre ha sido el uso compartido de recursos de bases de datos. Con la ramificación copy-on-write en Databricks Lakebase, una rama de un segundo y con almacenamiento cero al crearse de una base de datos de producción a escala de terabytes es ahora una operación O(1), y la limitación que hacía que la Práctica n.º 4 (cada quien tiene su propia instancia de base de datos) fuera solo una aspiración ha desaparecido. En esta serie, los autores describen qué cambia cuando se elimina esta limitación: no la metodología, que se mantiene, sino las prácticas que surgen por primera vez, la gobernanza a escala de equipo que se vuelve automática, la evolución del rol del DBA y la nueva capacidad que los agentes comparten con sus homólogos humanos.
Jen es el personaje de desarrolladora de Evolutionary Database Design. En ese ensayo, implementó una refactorización de base de datos, dividiendo un campo inventory_code en location_code, batch_number y serial_number, como una historia de usuario habitual, lo que ilustra que los DBA y los desarrolladores pueden colaborar, los esquemas pueden evolucionar en pequeños incrementos y las migraciones llevan a cabo el cambio de forma segura.
La serie retoma la historia de Jen veinte años después. La metodología que sigue es la misma que siguió en 2003. Lo nuevo es la capacidad técnica que sustenta su flujo de trabajo, habilitada por la arquitectura de lakebase: la ramificación de bases de datos copy-on-write, que hace que las prácticas sobre las que ha estado leyendo sean operativamente reales a escala de producción. A lo largo de las tres partes de esta serie, es la misma Jen en tres ámbitos: su día a día (Parte 1), su nuevo manual de estrategia (Parte 2) y su equipo (Parte 3).
La Parte 1 guio a Jen a través de una característica. Las prácticas que siguió se describieron en el ensayo de 2003 Evolutionary Database Design, se ampliaron en el libro de 2006 Refactoring Databases y se incorporaron al pipeline de CI/CD en el libro de 2010 Continuous Delivery (Capítulo 12).
El ensayo de 2003 nombraba siete prácticas. Cinco de las siete tuvieron limitaciones en su aplicación hasta 2026.
La tecnología introducida por Databricks Lakebase elimina los obstáculos para la implementación de las prácticas anteriores. Databricks Lakebase es una base de datos Postgres administrada que utiliza la misma capa de almacenamiento de objetos (el data lake) sobre la que se ejecuta el resto del lakehouse de Databricks. Los datos de la base de datos residen en un almacenamiento compartido y duradero, concretamente en buckets de S3; el motor de Postgres se ejecuta como una capa de cómputo independiente sobre él. El cómputo y el almacenamiento se escalan de forma independiente. El motor puede escalar verticalmente bajo carga, reducirse cuando disminuye el tráfico y llegar a cero cuando está inactivo. Lakebase está integrado con Unity Catalog, lo que permite una gobernanza unificada en múltiples entornos.
La ramificación de bases de datos copy-on-write es lo que hace que la arquitectura desacoplada sea práctica a escala. Una rama crea un nuevo puntero al mismo almacenamiento compartido con un marcador de divergencia. Hasta que la rama escribe, comparte todas las páginas con su padre. Cuando la rama escribe, solo divergen las páginas modificadas; el padre permanece intacto. La ramificación es una operación de metadatos, no requiere copia de datos y se completa en aproximadamente un segundo, independientemente del tamaño del padre. Las ramas mantienen los datos únicamente en las páginas modificadas.
Cuando el costo técnico de una rama se desacopla del tamaño de los datos que contiene, se elimina la limitación de la Práctica n.º 4 (cada quien tiene su propia instancia de base de datos). Las ramas por desarrollador, por PR y por experimento se vuelven habituales. La capa de compensación superior puede eliminarse. Los mocks salen del bucle de prueba, reemplazados por Postgres real en una rama por prueba. El entorno de staging compartido deja de ser el único lugar para probar los cambios de esquema. Los sustitutos de bases de datos en memoria (H2, SQLite) salen de la capa de pruebas unitarias. El costo de DevOps para crear contenedores basados en Docker para ejecutar bases de datos locales ya no es necesario, y las colas de tickets de los DBA para el aprovisionamiento se reducen porque las ramas son de autoservicio.
La tecnología es lo que permite optimizar la metodología y cumple el objetivo de las prácticas que sustentan la publicación original de 2003.
La ramificación de bases de datos copy-on-write de Lakebase elimina las limitaciones anteriores de las prácticas originales y permite desarrollar cuatro prácticas adicionales.
Las dos prácticas que más mejoran gracias a la capacidad que proporciona Lakebase son la n.º 4 (cada uno obtiene su propia instancia de base de datos) y la n.º 5 (los desarrolladores integran continuamente los cambios en la base de datos). Ahora no solo todo el mundo tiene una base de datos, sino que se puede disponer de cada PR, cada rama o de varias bases de datos por rama con un coste y un tiempo insignificantes. El mecanismo se puede automatizar mediante dos plantillas de flujo de trabajo de GitHub Actions que se pueden estructurar en cada proyecto.
Creación de ramas por PR. pr.yml se activa con pull_request: [opened, synchronize] y crea ci-pr-<N> bifurcada a partir de la rama base de la PR:
El mismo trabajo aplica las migraciones en la rama de CI y ejecuta el conjunto de pruebas de la aplicación en una base de datos Postgres real. Puedes encontrar un ejemplo completo del flujo de trabajo aquí: pr.yml
Diferencias de esquema publicadas en la PR. El mismo pr.yml trabajo vuelca el esquema de ambas ramas, da formato a las diferencias y las publica como un comentario en la PR. Esto es lo que permite al DBA realizar la revisión de forma asíncrona, como cualquier otro revisor de código (Práctica n.º 1, adaptada):
El DBA, el revisor de código, el equipo y cualquier agente autor de la migración ven el mismo artefacto en la PR.
Limpieza de ramas al fusionar. merge.yml destruye la rama de la pull request de CI ci-pr-<N> y la rama de Lakebase de la rama de características vinculada en el momento en que se fusiona la PR:
Puedes encontrar un ejemplo completo del flujo de trabajo de fusión aquí: merge.yml Con tantas ramas activas, puede valer la pena tener un script de limpieza semanal que elimine las ramas huérfanas y sin usar; puedes encontrar un ejemplo de flujo de trabajo aquí: cleanup-orphans.yml. Por último, si la fusión se realiza en una rama "por niveles" (por ejemplo, utilizada para staging o main/producción; este concepto se detallará más en la parte 3), el flujo de trabajo se puede orquestar para crear una rama nueva a partir del nivel para probar las migraciones en ella antes de aplicar la migración final a cualquier entorno donde haya usuarios activos que añadan datos constantemente.
Juntos, estos flujos de trabajo garantizan que cada PR obtenga su propia base de datos y que las ramas sean efímeras como propiedades del pipeline, no como disciplinas del desarrollador.
Regla. El DBA colabora con los desarrolladores a lo largo de toda la característica, no solo en el momento de la revisión final. La colaboración es asíncrona, integrada en la PR, de la misma manera que participan otros revisores de código.
¿Por qué es un hábito duradero ahora? Las diferencias de esquema y los resultados de las pruebas de migración llegan a cada PR de forma automática (consulta Cómo se ejecuta el flujo de trabajo en CI más arriba). El DBA revisa un artefacto concreto según su propio horario. La migración ya se ha ejecutado en una rama de CI con datos reales, por lo que el DBA no necesita simular mentalmente el cambio.
Mecánica:
migrations/, db/, directorios de prueba de esquemas).Antipatrón. No incluir al DBA en el flujo de la PR cuando hay artefactos legítimos que revisar.
El rol de DBA también adquiere nuevas responsabilidades en la administración de políticas y el gobierno a escala de equipo. La Parte 3 cubre estos aspectos.
Regla. Cada archivo SQL, script de migración y prueba de esquema reside en el mismo repositorio que el código de la aplicación. La diferencia de esquema y los resultados de las pruebas de migración se unen al conjunto de artefactos como resultados en el momento de la PR.
¿Por qué es este un hábito duradero ahora? La creación de ramas (branching) añade dos nuevos artefactos al conjunto: la diferencia de esquema por PR y los resultados de las pruebas de migración de esquema por PR. Ambos son generados por la CI a partir del estado real de la rama. Ambos llegan a la PR como evidencia concreta de lo que cambió y de cómo funcionó el script de migración del cambio.
Mecánica:
migrations/, db/migration/, alembic/versions/, dependiente del framework).Antipatrón. Generar la diferencia de esquema fuera del flujo de la PR (un panel de control independiente que el revisor tiene que abrir). El artefacto debe residir donde se realiza la revisión. Dado que los cambios de esquema están vinculados a los cambios de código, romper esta dependencia genera problemas en etapas posteriores para el despliegue.
Regla. Sin ALTER TABLE manuales contra ningún entorno. Cada cambio de esquema es un script de migración con versión y registrado. Las migraciones son idempotentes.
¿Por qué es este un hábito duradero ahora? La regla de la migración como artefacto no ha cambiado desde 2003. Lo nuevo es la disciplina de autoría de la idempotencia. La misma migración se ejecuta en muchas ramas a lo largo de la vida de una transición, por lo que debe comportarse de la misma manera cada vez. Una migración que falla al volver a aplicarse es un error.
Mecánica:
flyway, liquibase, Knex, Alembic u otros; estos frameworks realizan un seguimiento de qué migraciones se han ejecutado y cuáles no, lo que permite al equipo aplicar un comando como flyway migrate que solo aplica los cambios que no se han aplicado (realizando un seguimiento de los cambios en una tabla de metadatos)Antipatrón. Una migración que depende de que el esquema se encuentre en un estado intermedio específico debido a cambios locales realizados en la rama. La migración debe aplicarse correctamente en cualquier rama principal que incluya migraciones anteriores.
Regla. Cada desarrollador, cada PR, cada experimento y cada ejecución de prueba obtiene su propia rama de Lakebase.
¿Por qué es este un hábito duradero ahora? Ya no es necesario el esfuerzo adicional de crear contenedores de Docker, instalar servidores de bases de datos locales, adquirir licencias ni rellenar bases de datos vacías con esquemas y datos de prueba existentes. Un simple comando de Lakebase create-branch crea una rama de una base de datos de 1 TB en el mismo segundo que una de 1 MB. No se copian datos al crearla; solo las páginas modificadas consumen almacenamiento. Las instancias por desarrollador, por PR y por experimento son algo habitual.
Mecánica:
databricks postgres create-branch o del flujo branch-create de la extensión de SCM.pr.yml), destruidas al fusionar o cerrar (merge.yml). Consulte Cómo se ejecuta el flujo de trabajo en la CI más arriba para ver los fragmentos de código de la PR y de la fusión (merge) .Antipatrón. Compartir una base de datos de desarrollo en todo el equipo "por conveniencia". La serialización impulsada por la contención que se mencionó en la Parte 1 regresa en el momento en que las ramas se fusionan.
Dónde se extiende el ejemplo de Jen. Su rama por desarrollador se bifurcó de staging al inicio de la característica. La rama de la CI se bifurcó de staging al abrir la PR. Sus ramas de exploración A/B (Práctica n.º 9) se bifurcaron de staging en paralelo. Cuatro ramas para una sola característica, todas en segundos, todas aisladas.
Regla. Cada PR se ejecuta a través de la CI contra una rama nueva de Lakebase, con las migraciones aplicadas y las pruebas ejecutadas contra un Postgres real.
¿Por qué es este un hábito duradero ahora? El pipeline de CI ha tenido disciplina de migración desde 2010. Lo nuevo es el aislamiento por pipeline: cada PR obtiene su propia rama, por lo que la integración se ejecuta contra datos con formato real sin contención.
Mecánica:
lakebase-migrate apply.Antipatrón. Ejecutar la validación de la PR contra un entorno de staging compartido. La serialización regresa y se pierde la propiedad de aislamiento por PR.
Regla. Los cambios de esquema siguen patrones de refactorización definidos: Dividir columna, Renombrar columna, Mover columna, Reemplazar tipo, entre otros. Cada uno tiene una mecánica de transición explícita (mantener lo antiguo y lo nuevo en paralelo, rellenar desde lo antiguo, intercambiar lectores, eliminar lo antiguo).
¿Por qué es este un hábito duradero ahora? El catálogo de 2006 en databaserefactoring.com nombra más de 70 refactorizaciones con ejemplos prácticos. Lo nuevo en 2026 es un lugar económico para ensayar la mecánica de transición: una rama de desarrollador absorbe el ensayo, la rama de la CI lo verifica y producción solo ve el resultado verificado.
Mecánica:
Antipatrón. Un cambio de esquema único que no se asigna a una refactorización definida. El catálogo de más de 70 casos cubre las situaciones comunes; si se encuentra fuera de él, es probable que esté combinando varias refactorizaciones en una sola migración y deba dividirlas.
Dónde se extiende el ejemplo de Jen. Su migración V87 es la refactorización de división de columnas (Split Column): dividir inventory_code en location_code, batch_number y serial_number. La página del catálogo en databaserefactoring.com/SplitColumns.html describe la mecánica de transición. Su rama era el espacio de ensayo; la ejecución de CI de la PR fue la verificación.
Regla. Un desarrollador puede actualizar el estado de la base de datos de su rama bajo demanda: restablecer al estado actual de la rama padre, crear una bifurcación limpia a partir de producción, descartar una rama experimental o compartir una rama con un compañero de equipo. Todo en segundos.
¿Por qué es este un hábito duradero ahora? "Bajo demanda" en 2026 significa un segundo, de forma aislada, con datos que tienen la forma de producción. Ninguna de estas operaciones requiere consultar calendarios de operaciones ni colas de DBA.
Mecánica:
databricks postgres create-branch --source production.databricks postgres delete-branch.Antipatrón. Tratar cualquier rama como duradera más allá de su propósito. La migración es el artefacto duradero; la rama es el espacio de trabajo.
Regla. Cuando el radio de impacto de una acción destructiva es cero, las pruebas destructivas se convierten en una opción diaria en lugar de un ejercicio trimestral.
¿Por qué es este un hábito duradero ahora? Una rama se restablece en un segundo. Cualquier cosa que le hagas a una rama se puede deshacer creando una nueva a partir de la misma rama padre. Las pruebas destructivas ya no necesitan calendarios de operaciones ni filtros de aprobación.
Cosas que ahora caben dentro de un ciclo normal de desarrollo de funciones:
Efecto cultural. Cuando restablecer no cuesta nada, los equipos dejan de tratar la base de datos de prueba como un recurso valioso. Las pruebas pueden ser agresivas. Se puede omitir la limpieza, porque la siguiente rama comenzará de cero.
Dónde se extiende el ejemplo de Jen. Antes de abrir su PR, tomó los datos con forma de producción en su rama y corrompió deliberadamente alrededor del uno por ciento de los valores de inventory_code para que parecieran casos extremos: dígitos faltantes, espacios incrustados, espacios en blanco al final. El tipo de artefactos que acumulan los datos históricos. Ejecutó su migración. Dos filas fallaron en sus cálculos de subcadena. Corrigió el script y volvió a ejecutarlo. La rama absorbió la prueba destructiva. Producción nunca la vio.
Regla. Cuando haya dos diseños en disputa, constrúyelos en ramas paralelas, compáralos con datos con forma de producción y quédate con la mejor solución.
¿Por qué es este un hábito duradero ahora? El costo por rama es casi nulo. Explorar dos diseños de esquema ya no requiere elegir uno de antemano, y ya no requiere un proceso de aprovisionamiento que la mayoría de los equipos no realizarían para una pregunta exploratoria.
Mecánica:
Antipatrón. Ejecutar prototipos A/B sin registrar la decisión y el razonamiento. Las ramas desaparecen en un segundo; la decisión de diseño debe ser permanente.
Dónde se extiende el ejemplo de Jen. Consideró dos diseños para la función de ubicación/lote/serie: tres columnas nuevas en la tabla existente inventory, o una tabla de búsqueda independiente inventory_attributes con clave por inventory_id, anticipando que se agregarían más atributos más adelante. Creó ambos diseños en ramas paralelas a partir de staging. Ejecutó la ruta de lectura de la aplicación contra cada uno, midió el rendimiento de las consultas con datos con forma de producción y analizó cómo se escalaría cada migración a volúmenes de producción. La versión de la tabla de búsqueda tuvo un peor rendimiento en la ruta de lectura común porque cada visualización de inventario requería una unión (join). Lanzó la versión de las columnas, descartó la rama de la tabla de búsqueda y dejó una nota en la descripción de la PR: Se consideró la versión de la tabla de búsqueda; se rechazó porque la ruta de lectura común se convierte en una unión (join). Volver a evaluar si se acumulan más de cinco atributos.
Hemos nombrado las siete prácticas de 2003 con las limitaciones que mantuvieron a cinco de ellas como aspiracionales, las hemos reformulado para 2026 una vez que llegó la ramificación (branching), y hemos agregado cuatro prácticas nuevas que la ramificación hace posibles. Once prácticas en total en el nuevo manual para el Desarrollo Evolutivo de Bases de Datos, 9 de las cuales se explican arriba.
En la Parte 1 – La historia de Jen: una función, una base de datos vimos a Jen trabajar en una función: emparejó una rama de código con una rama de Lakebase, ejecutó una migración real con datos con forma de producción en segundos, realizó pruebas sin mocks, abrió una PR con la diferencia de esquema (schema diff) insertada en línea y fusionó con la migración aplicada y las ramas efímeras limpiadas. El cambio de base de datos se convirtió en parte del desarrollo normal.
En la Parte 3 – El equipo de Jen a escala, analizamos el manual con cincuenta desarrolladores, las responsabilidades evolucionadas del DBA en la administración de políticas y gobernanza, y los agentes que crean ramas junto a Jen. Las prácticas n.º 10 y n.º 11 se tratan en detalle allí.
La Guía complementaria: recorrido por el complemento cubre la extensión Lakebase SCM para VS Code y Cursor.
Se lanzará un Lakebase App Dev Kit para agentes, junto con un libro electrónico complementario para profesionales humanos, como continuación.
(Esta entrada del blog ha sido traducida utilizando herramientas basadas en inteligencia artificial) Publicación original
Suscríbete a nuestro blog y recibe las últimas publicaciones directamente en tu bandeja de entrada.