Adding a new column sounds simple. It is not. In production, every database change is a contract update. A column alters schema, storage, indexes, and query plans. If you do it carelessly, you risk downtime, data corruption, and broken code paths.
A safe new column starts with clarity. Define its type, constraints, default values, and nullability. Decide if it should be indexed. Know how it interacts with existing queries. If a column will get data from a live stream, bulk import, or backfill, plan for locking and throughput impacts before the first ALTER statement runs.
Schema migrations must be reversible. Always write the down migration before running the up migration. Test both on a production-like dataset. Measure latency changes before you deploy. If needed, split the migration into steps: add the column without constraints, backfill in batches, then add constraints and indexes afterward. This avoids long locks, excessive replication lag, and stale reads.
Watch for application-layer changes. Every new column affects serialization, API responses, and ORM mappings. Avoid assumptions about defaults—explicitly handle nulls in code. Deploy application updates in lockstep with the database change, or use feature flags to allow safe rollout.