Altering Tables in PostgreSQL
Overview
ALTER TABLE is used to modify the structure of an existing table, including adding, dropping, or modifying columns, and adding or removing constraints.
Adding Columns
sql
-- Add a single column
ALTER TABLE users ADD COLUMN phone VARCHAR(20);
-- Add a column with a default value
ALTER TABLE users ADD COLUMN status VARCHAR(20) DEFAULT 'active';
-- Add a column with a constraint
ALTER TABLE users ADD COLUMN email VARCHAR(100) NOT NULL;
-- Add multiple columns
ALTER TABLE users
ADD COLUMN created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
ADD COLUMN updated_at TIMESTAMP;Dropping Columns
sql
-- Drop a single column
ALTER TABLE users DROP COLUMN phone;
-- Drop multiple columns
ALTER TABLE users
DROP COLUMN phone,
DROP COLUMN fax;
-- Cascade drop (drop dependent objects)
ALTER TABLE users DROP COLUMN email CASCADE;
-- Drop column if it exists
ALTER TABLE users DROP COLUMN IF EXISTS phone;Modifying Columns
Renaming Columns
sql
-- Rename a column
ALTER TABLE users RENAME COLUMN name TO full_name;
-- Rename multiple columns
ALTER TABLE users RENAME COLUMN addr TO address;
ALTER TABLE users RENAME COLUMN tel TO phone;Changing Data Types
sql
-- Change column data type
ALTER TABLE users ALTER COLUMN age TYPE INTEGER;
-- Convert data using USING
ALTER TABLE users
ALTER COLUMN price TYPE NUMERIC(10,2)
USING price::NUMERIC(10,2);
-- Change string length
ALTER TABLE users ALTER COLUMN name TYPE VARCHAR(200);Setting/Removing Default Values
sql
-- Set default value
ALTER TABLE users ALTER COLUMN status SET DEFAULT 'active';
-- Remove default value
ALTER TABLE users ALTER COLUMN status DROP DEFAULT;
-- Set current timestamp as default value
ALTER TABLE orders ALTER COLUMN created_at SET DEFAULT CURRENT_TIMESTAMP;Setting/Removing NOT NULL Constraints
sql
-- Set NOT NULL constraint
ALTER TABLE users ALTER COLUMN email SET NOT NULL;
-- Remove NOT NULL constraint
ALTER TABLE users ALTER COLUMN phone DROP NOT NULL;Adding Constraints
Primary Key Constraints
sql
-- Add primary key
ALTER TABLE users ADD PRIMARY KEY (id);
-- Add named primary key
ALTER TABLE users ADD CONSTRAINT users_pkey PRIMARY KEY (id);
-- Add composite primary key
ALTER TABLE order_items
ADD PRIMARY KEY (order_id, product_id);Foreign Key Constraints
sql
-- Add foreign key
ALTER TABLE orders
ADD FOREIGN KEY (user_id) REFERENCES users(id);
-- Add named foreign key
ALTER TABLE orders
ADD CONSTRAINT fk_orders_users
FOREIGN KEY (user_id) REFERENCES users(id);
-- Add foreign key with cascade behavior
ALTER TABLE orders
ADD CONSTRAINT fk_orders_users
FOREIGN KEY (user_id) REFERENCES users(id)
ON DELETE CASCADE
ON UPDATE CASCADE;Unique Constraints
sql
-- Add unique constraint
ALTER TABLE users ADD UNIQUE (email);
-- Add named unique constraint
ALTER TABLE users
ADD CONSTRAINT users_email_unique UNIQUE (email);
-- Add composite unique constraint
ALTER TABLE products
ADD CONSTRAINT products_name_category_unique
UNIQUE (name, category_id);Check Constraints
sql
-- Add check constraint
ALTER TABLE products
ADD CHECK (price > 0);
-- Add named check constraint
ALTER TABLE products
ADD CONSTRAINT products_price_check
CHECK (price > 0 AND price < 1000000);
-- Add complex check constraint
ALTER TABLE users
ADD CONSTRAINT users_age_check
CHECK (age >= 18 AND age <= 120);Dropping Constraints
sql
-- Drop primary key
ALTER TABLE users DROP CONSTRAINT users_pkey;
-- Drop foreign key
ALTER TABLE orders DROP CONSTRAINT fk_orders_users;
-- Drop unique constraint
ALTER TABLE users DROP CONSTRAINT users_email_unique;
-- Drop check constraint
ALTER TABLE products DROP CONSTRAINT products_price_check;
-- Cascade drop constraint
ALTER TABLE users DROP CONSTRAINT users_pkey CASCADE;Renaming Tables
sql
-- Rename table
ALTER TABLE users RENAME TO customers;
-- Rename table (if exists)
ALTER TABLE IF EXISTS old_table RENAME TO new_table;Changing Table Ownership
sql
-- Change table owner
ALTER TABLE users OWNER TO new_owner;
-- Change owner of multiple tables
ALTER TABLE users OWNER TO admin;
ALTER TABLE orders OWNER TO admin;Changing Table Tablespace
sql
-- Move table to a different tablespace
ALTER TABLE users SET TABLESPACE fast_storage;
-- Move table and its indexes
ALTER TABLE users SET TABLESPACE fast_storage;Practical Examples
Example 1: Refactoring the Users Table
sql
-- Add new columns
ALTER TABLE users ADD COLUMN last_login TIMESTAMP;
ALTER TABLE users ADD COLUMN login_count INTEGER DEFAULT 0;
-- Modify existing columns
ALTER TABLE users ALTER COLUMN email SET NOT NULL;
ALTER TABLE users ADD CONSTRAINT users_email_unique UNIQUE (email);
-- Add check constraint
ALTER TABLE users ADD CONSTRAINT users_age_check CHECK (age >= 18);
-- Rename column
ALTER TABLE users RENAME COLUMN addr TO address;Example 2: Optimizing the Orders Table
sql
-- Add foreign key constraint
ALTER TABLE orders
ADD CONSTRAINT fk_orders_users
FOREIGN KEY (user_id) REFERENCES users(id)
ON DELETE CASCADE;
-- Add status check
ALTER TABLE orders
ADD CONSTRAINT orders_status_check
CHECK (status IN ('pending', 'processing', 'completed', 'cancelled'));
-- Add amount check
ALTER TABLE orders
ADD CONSTRAINT orders_amount_check
CHECK (total_amount >= 0);
-- Add timestamps
ALTER TABLE orders
ADD COLUMN created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
ADD COLUMN updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP;Example 3: Extending the Products Table
sql
-- Add new fields
ALTER TABLE products
ADD COLUMN description TEXT,
ADD COLUMN image_url VARCHAR(500),
ADD COLUMN is_active BOOLEAN DEFAULT true;
-- Modify price column
ALTER TABLE products
ALTER COLUMN price TYPE NUMERIC(10,2),
ALTER COLUMN price SET NOT NULL;
-- Add constraints
ALTER TABLE products
ADD CONSTRAINT products_price_check CHECK (price > 0),
ADD CONSTRAINT products_stock_check CHECK (stock >= 0);
-- Add unique constraint
ALTER TABLE products
ADD CONSTRAINT products_sku_unique UNIQUE (sku);Best Practices
- Backup Data: Always back up data before modifying table structures
- Use Transactions: Execute ALTER TABLE operations within a transaction
- Name Constraints: Assign meaningful names to constraints
- Test in Staging: Test modifications in a staging environment first
- Avoid Table Locking: Be aware that some operations lock the entire table
- Use IF EXISTS: Use IF EXISTS to avoid errors
Considerations
- ALTER TABLE operations may lock the table
- Some modifications require rewriting the entire table
- A default value must be provided (or ensure no NULL values exist) when adding a NOT NULL column
- Foreign key constraints impact performance
- Structural modifications to large tables may take a significant amount of time
Summary
ALTER TABLE is a powerful tool for modifying table structures in PostgreSQL:
- Add/Drop Columns: Extend or streamline table structures
- Modify Column Properties: Change data types, default values, and NULL constraints
- Manage Constraints: Add or remove primary keys, foreign keys, unique, and check constraints
- Rename: Rename tables and columns
- Other Operations: Change ownership, tablespace, etc.
Using ALTER TABLE appropriately allows flexible adjustment of database structures to meet business requirements.