The simplest path is the ALTER TABLE statement:
ALTER TABLE users ADD COLUMN last_login TIMESTAMP;
This works for lightweight changes, but the risk grows with table size. On large datasets, adding a new column can lock writes for seconds or even minutes. Avoid blind updates that backfill every row at once. Use nullable columns or provide a default only if it won’t force an immediate rewrite.
For PostgreSQL, ALTER TABLE ... ADD COLUMN with a default value that is constant and non-null is optimized in recent versions, but understanding version-specific behavior matters. On MySQL, online DDL modes can reduce lock time, but they vary by storage engine and configuration.
Schema migrations require version control in code. Apply database changes in small, reversible steps. Add a new column first, then deploy code that writes to it, and only later backfill data if necessary.