18 ALTER TABLE and DROP
Tables evolve. ALTER TABLE changes an existing table: add or drop a column, rename a column or the table itself, add or drop a constraint, change a column’s type, change its default. DROP TABLE removes the table and every row it contains. Schema changes in PostgreSQL are transactional — a failed ALTER TABLE rolls back cleanly, and you can wrap several ALTERs in a BEGIN ... COMMIT to apply them atomically.
What you’ll learn
- Adding, renaming, and dropping columns
- Adding and dropping constraints
- Changing a column’s type with
USING - Renaming a table
- The locking and rewrite implications of common alterations
Example
Each ALTER TABLE is a single transactional statement. You can also batch multiple operations: ALTER TABLE t ADD COLUMN a int, ADD COLUMN b text, DROP COLUMN c; — running them in one statement is faster because the table is touched once.
Two operations are worth understanding in terms of cost:
- Adding a column with no default (or a constant default) is fast — PostgreSQL just records the new column metadata.
- Many column type changes rewrite the table.
ALTER COLUMN x TYPE bigintreads and rewrites every row. On a large table this can take hours and holds an exclusive lock the whole time. Some binary-compatible changes avoid a rewrite. For a rewrite-heavy change, plan a migration such as new column → backfill → switch;pg_repackdoes not perform arbitrary type conversions.
ALTER TABLE ... ALTER COLUMN col TYPE new_type USING expr lets you specify how to convert the existing value: ALTER COLUMN price TYPE numeric(12,2) USING price::numeric(12,2).
Run the example
To run:
Common pitfalls
- Adding
NOT NULLto an existing column requires that the column already has no NULLs and acquires anACCESS EXCLUSIVElock long enough to verify. Backfill first, thenSET NOT NULL. From PostgreSQL 12, you canALTER COLUMN x SET NOT NULLfaster if a matchingCHECKconstraint exists. - Dropping a column does not reclaim disk space immediately — the column is marked dead. Run
VACUUM FULL(heavyweight) or recreate the table to reclaim it. - Renaming a column updates catalog-tracked dependencies such as views, but can break application SQL and function bodies stored as text. Review those uses before renaming.
ALTER TYPEon anENUMcannot remove values; adding values is fine.
For zero-downtime schema changes, the standard pattern is: add the new column → backfill in batches → make the application write to both → switch reads → drop the old column. Tools like Liquibase, Flyway, or pg_repack help; the database does the locking, you do the choreography.
Add a column back: ALTER TABLE products ADD COLUMN notes text;. Then rename: ALTER TABLE products RENAME COLUMN notes TO remarks;. Then drop: ALTER TABLE products DROP COLUMN remarks;. Inspect with \d products in psql.
Downloads
SQL file: alter-table-and-drop.sql · All lesson files · Setup guide