LibraryFirst Way: FlowTools & TechniquesDatabase Change Management

FT-09TOOLFirst Way: Flow

Database Change Management

Databases are the hardest part of continuous delivery. How to version-control schema changes, apply them safely, and deploy without downtime.

Sources:DevOps HandbookEvolutionary Database Design — Fowler & SadalageFlyway / Liquibase docs

Video Lesson

A video lesson for this topic is in development. The library articles and mission exercises cover the same material in the meantime.

01

The database problem

Application code is stateless: you can deploy a new version, roll back, and redeploy without consequence. Databases are stateful: every schema change must be applied to existing data, must be backwards compatible with the current application version, and cannot be rolled back the same way code can.

This asymmetry makes databases the most common source of deployment risk. A rename of a column breaks every query that references the old name. Dropping a column that is still referenced causes a runtime error. Adding a NOT NULL column without a default fails inserts from old application code.

The most dangerous deployment is one that includes both a schema change and application code that depends on it. If the schema migration runs, then the application deployment fails and rolls back — the application is now running against a schema it was not designed for.

02

Evolutionary database design

Martin Fowler and Pramod Sadalage's evolutionary database design treats the schema as a living artifact that changes incrementally — just like application code. The key principles:

Additive changes only

Add columns and tables. Never rename or remove them in the same deployment as the code that uses the new name. Renames are two-step: add new, migrate, remove old.

Backwards compatibility

Every schema change must be compatible with the current running application version. The new schema works with the old code. This enables zero-downtime deploys.

Small, frequent changes

One logical change per migration. Small migrations are easy to review, easy to rollback, and have a small blast radius if they fail.

Version control the schema

Every schema change is a versioned migration script in source control, reviewed in a PR, applied by the pipeline — never applied manually to production.

03

Database migrations

A migration is a versioned SQL script that transforms the schema from one known state to the next. Migration tools like Flyway and Liquibase track which migrations have been applied and apply the pending ones in version order.

# Flyway migration file naming convention

V1__create_users_table.sql

V2__add_email_index.sql

V3__add_premium_tier_column.sql

# V3__add_premium_tier_column.sql

ALTER TABLE users

ADD COLUMN tier VARCHAR(20)

NOT NULL DEFAULT 'free';

Flyway

SQL-first. Migrations are plain SQL files. Simple and predictable. Best for teams that know SQL and want minimal abstraction.

flyway migrate — applies pending migrations

Liquibase

XML/YAML/JSON changelogs with database-agnostic syntax. More powerful rollback support. Best for multi-database environments.

liquibase update — applies pending changesets

04

Zero-downtime migrations

The expand-contract pattern makes schema changes safe for zero-downtime deploys. Instead of a single breaking change, the migration is split into backwards-compatible steps that can be deployed independently:

Expand

Add new_email column (nullable)

Old code still works — reads old_email. New code can start writing new_email.

Migrate

Backfill new_email from old_email

Background job copies data. Both columns exist. Both apps work.

Switch

Deploy code reading new_email

New code in production. Old column still present as safety net.

Contract

Drop old_email column

Only after confirming no code reads old_email. Safe to remove.

Each step can be deployed independently. If any step fails, only that step needs to be addressed — the application continues to function because each step maintains backwards compatibility with the current code version.

05

Common anti-patterns

HIGH

Big bang migration

Applying hundreds of schema changes in a single migration. If it fails partway through, the database is in an unknown state. Migrate incrementally — one logical change per script.

CRITICAL

Direct production changes

Running ALTER TABLE in a production database console. Not version-controlled, not reviewed, not reproducible. Guaranteed to diverge from other environments eventually.

HIGH

No rollback plan

Dropping a column or renaming a table without a tested rollback procedure. Many DDL operations cannot be rolled back automatically — you need a reverse migration ready.

HIGH

Coupled schema + code deploy

Deploying a schema change and the code that depends on it in the same deployment. If the code deploy fails and rolls back, the application is running against the new schema with old code.

MED

Unlocked migration files

Modifying a migration file after it has been applied to any environment. Flyway will detect the checksum mismatch and refuse to proceed. Treat applied migrations as immutable.

06

Further reading

Evolutionary Database Design — Fowler & Sadalage

martinfowler.com/articles/evodb.html. The foundational article on treating database schema as evolutionary, version-controlled artifacts.

DevOps Handbook — Chapter 15

Enable and Practice Continuous Integration of Database Changes. Migrations in the pipeline, zero-downtime patterns.

Flyway Documentation

flywaydb.org/documentation. Complete reference for Flyway migrations, versioning conventions, and pipeline integration.

Liquibase Documentation

docs.liquibase.com. Complete reference including rollback strategies, changeset authoring, and diff-based migrations.