Adding a new column to a production database should be fast, predictable, and safe. But too often, migrations stall deployments, lock tables, or break downstream systems. The right approach is deliberate and repeatable.
First, define the new column with explicit types and constraints. Avoid defaulting to NULL unless missing data is expected. Use database-native data types that match your application logic. If the column is for indexing or filtering, consider its impact on query plans up front.
Second, plan for zero-downtime migration. In PostgreSQL, adding a column without defaults is instant. Adding a column with a default value rewrites the table, which can cause significant delays. In MySQL, similar rules apply but engine differences matter. Break the change into two steps when needed:
- Add the column without a default.
- Backfill data in small batches.
Third, update your application code to handle both states: with and without the new column populated. Deploy the code before the data migration finishes. This avoids mismatched assumptions between app and database.