Skip to content

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

  1. Backup Data: Always back up data before modifying table structures
  2. Use Transactions: Execute ALTER TABLE operations within a transaction
  3. Name Constraints: Assign meaningful names to constraints
  4. Test in Staging: Test modifications in a staging environment first
  5. Avoid Table Locking: Be aware that some operations lock the entire table
  6. 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.

Content is for learning and research only.