Schema migrations

Intermediate 10 min read

Change the database structure in small, versioned steps that run the same way everywhere.

Why it matters

Code changes are deployed from Git; the database must follow in lockstep. Migrations are the database's version history, so every environment ends up with the same structure — and a release does not break because someone forgot an ALTER TABLE.

Where it fits

  1. Plan & Design
  2. ● Develop › Data
  3. Version control
  4. Verify
  5. Build & Package
  6. CI/CD
  7. Deploy
  8. Operate

What you will learn

  • Write a migration that adds a table or column.
  • Run migrations as part of a deployment.
  • Change a column without downtime in several steps.

Before you start

2026_10_23_add_status_to_orders.sql
ALTER TABLE orders ADD COLUMN status TEXT NOT NULL DEFAULT 'new';
CREATE INDEX orders_status_index ON orders (status);
Frameworks wrap this in a migration file (Laravel, Django, Rails, Flyway…) that records which migrations already ran.

Changing a live database safely

  1. Add new column
  2. Write to both
  3. Backfill
  4. Read from new
  5. Drop old

Renaming or retyping a column in one step breaks the old version of the app that is still running during a deploy. Splitting it into compatible steps keeps every version working.

  • Every migration is in Git and runs in order.
  • A migration that has run in production is never edited — write a new one.
  • Large tables: check how long the change locks the table before running it.
  • A backup exists before a destructive migration.

Official documentation and references

Documentation

Practise in Zerethon IDE

Learn next

Done with this topic?

Reviewed 2026-10-23. Links go to the official documentation unless marked otherwise.