When adding a new column, the first decision is its definition. Choose the correct data type from the start to avoid costly refactors. Use NOT NULL constraints only when you have a clear default for every row. Otherwise, make it nullable during rollout to prevent locking writes on massive tables.
Create the column in a migration that runs without long locks. In PostgreSQL, adding a nullable column with no default is an instant operation. Setting a default value for existing rows can be done later in a separate background job to prevent table-wide rewrites. On MySQL, engine and version differences mean you should test the migration in a staging clone to measure real execution time.
Every new column needs to be indexed only if it is used in filters, joins, or sorts. Avoid speculative indexing; every index has a write cost. Instead, deploy the column, observe usage in real queries, and create indexes only when justified. This keeps storage lean and write throughput high.