PostgreSQL 修改表
概述
ALTER TABLE 用于修改现有表的结构,包括添加、删除或修改列,添加或删除约束等。
添加列
sql
-- 添加单个列
ALTER TABLE users ADD COLUMN phone VARCHAR(20);
-- 添加带默认值的列
ALTER TABLE users ADD COLUMN status VARCHAR(20) DEFAULT 'active';
-- 添加带约束的列
ALTER TABLE users ADD COLUMN email VARCHAR(100) NOT NULL;
-- 添加多个列
ALTER TABLE users
ADD COLUMN created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
ADD COLUMN updated_at TIMESTAMP;删除列
sql
-- 删除单个列
ALTER TABLE users DROP COLUMN phone;
-- 删除多个列
ALTER TABLE users
DROP COLUMN phone,
DROP COLUMN fax;
-- 级联删除(删除依赖对象)
ALTER TABLE users DROP COLUMN email CASCADE;
-- 如果存在则删除
ALTER TABLE users DROP COLUMN IF EXISTS phone;修改列
重命名列
sql
-- 重名列列
ALTER TABLE users RENAME COLUMN name TO full_name;
-- 重命名多个列
ALTER TABLE users RENAME COLUMN addr TO address;
ALTER TABLE users RENAME COLUMN tel TO phone;更改数据类型
sql
-- 更改列类型
ALTER TABLE users ALTER COLUMN age TYPE INTEGER;
-- 使用USING转换数据
ALTER TABLE users
ALTER COLUMN price TYPE NUMERIC(10,2)
USING price::NUMERIC(10,2);
-- 更改字符串长度
ALTER TABLE users ALTER COLUMN name TYPE VARCHAR(200);设置/删除默认值
sql
-- 设置默认值
ALTER TABLE users ALTER COLUMN status SET DEFAULT 'active';
-- 删除默认值
ALTER TABLE users ALTER COLUMN status DROP DEFAULT;
-- 设置当前时间戳为默认值
ALTER TABLE orders ALTER COLUMN created_at SET DEFAULT CURRENT_TIMESTAMP;设置/删除NOT NULL
sql
-- 设置NOT NULL约束
ALTER TABLE users ALTER COLUMN email SET NOT NULL;
-- 删除NOT NULL约束
ALTER TABLE users ALTER COLUMN phone DROP NOT NULL;添加约束
主键约束
sql
-- 添加主键
ALTER TABLE users ADD PRIMARY KEY (id);
-- 添加命名主键
ALTER TABLE users ADD CONSTRAINT users_pkey PRIMARY KEY (id);
-- 添加复合主键
ALTER TABLE order_items
ADD PRIMARY KEY (order_id, product_id);外键约束
sql
-- 添加外键
ALTER TABLE orders
ADD FOREIGN KEY (user_id) REFERENCES users(id);
-- 添加命名外键
ALTER TABLE orders
ADD CONSTRAINT fk_orders_users
FOREIGN KEY (user_id) REFERENCES users(id);
-- 添加带级联的外键
ALTER TABLE orders
ADD CONSTRAINT fk_orders_users
FOREIGN KEY (user_id) REFERENCES users(id)
ON DELETE CASCADE
ON UPDATE CASCADE;唯一约束
sql
-- 添加唯一约束
ALTER TABLE users ADD UNIQUE (email);
-- 添加命名唯一约束
ALTER TABLE users
ADD CONSTRAINT users_email_unique UNIQUE (email);
-- 添加复合唯一约束
ALTER TABLE products
ADD CONSTRAINT products_name_category_unique
UNIQUE (name, category_id);检查约束
sql
-- 添加检查约束
ALTER TABLE products
ADD CHECK (price > 0);
-- 添加命名检查约束
ALTER TABLE products
ADD CONSTRAINT products_price_check
CHECK (price > 0 AND price < 1000000);
-- 添加复杂检查约束
ALTER TABLE users
ADD CONSTRAINT users_age_check
CHECK (age >= 18 AND age <= 120);删除约束
sql
-- 删除主键
ALTER TABLE users DROP CONSTRAINT users_pkey;
-- 删除外键
ALTER TABLE orders DROP CONSTRAINT fk_orders_users;
-- 删除唯一约束
ALTER TABLE users DROP CONSTRAINT users_email_unique;
-- 删除检查约束
ALTER TABLE products DROP CONSTRAINT products_price_check;
-- 级联删除约束
ALTER TABLE users DROP CONSTRAINT users_pkey CASCADE;重命名表
sql
-- 重命名表
ALTER TABLE users RENAME TO customers;
-- 重命名表(如果存在)
ALTER TABLE IF EXISTS old_table RENAME TO new_table;更改表所有者
sql
-- 更改表所有者
ALTER TABLE users OWNER TO new_owner;
-- 更改多个表的所有者
ALTER TABLE users OWNER TO admin;
ALTER TABLE orders OWNER TO admin;更改表空间
sql
-- 移动表到不同的表空间
ALTER TABLE users SET TABLESPACE fast_storage;
-- 移动表及其索引
ALTER TABLE users SET TABLESPACE fast_storage;实际示例
示例1:用户表重构
sql
-- 添加新列
ALTER TABLE users ADD COLUMN last_login TIMESTAMP;
ALTER TABLE users ADD COLUMN login_count INTEGER DEFAULT 0;
-- 修改现有列
ALTER TABLE users ALTER COLUMN email SET NOT NULL;
ALTER TABLE users ADD CONSTRAINT users_email_unique UNIQUE (email);
-- 添加检查约束
ALTER TABLE users ADD CONSTRAINT users_age_check CHECK (age >= 18);
-- 重命名列
ALTER TABLE users RENAME COLUMN addr TO address;示例2:订单表优化
sql
-- 添加外键约束
ALTER TABLE orders
ADD CONSTRAINT fk_orders_users
FOREIGN KEY (user_id) REFERENCES users(id)
ON DELETE CASCADE;
-- 添加状态检查
ALTER TABLE orders
ADD CONSTRAINT orders_status_check
CHECK (status IN ('pending', 'processing', 'completed', 'cancelled'));
-- 添加金额检查
ALTER TABLE orders
ADD CONSTRAINT orders_amount_check
CHECK (total_amount >= 0);
-- 添加时间戳
ALTER TABLE orders
ADD COLUMN created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
ADD COLUMN updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP;示例3:产品表扩展
sql
-- 添加新字段
ALTER TABLE products
ADD COLUMN description TEXT,
ADD COLUMN image_url VARCHAR(500),
ADD COLUMN is_active BOOLEAN DEFAULT true;
-- 修改价格列
ALTER TABLE products
ALTER COLUMN price TYPE NUMERIC(10,2),
ALTER COLUMN price SET NOT NULL;
-- 添加约束
ALTER TABLE products
ADD CONSTRAINT products_price_check CHECK (price > 0),
ADD CONSTRAINT products_stock_check CHECK (stock >= 0);
-- 添加唯一约束
ALTER TABLE products
ADD CONSTRAINT products_sku_unique UNIQUE (sku);最佳实践
- 备份数据:在修改表结构前始终备份数据
- 使用事务:在事务中执行 ALTER TABLE 操作
- 命名约束:为约束指定有意义的名称
- 测试环境:先在测试环境中测试修改
- 避免锁表:注意某些操作会锁定整个表
- 使用 IF EXISTS:使用 IF EXISTS 避免错误
注意事项
- ALTER TABLE 操作可能会锁定表
- 某些修改需要重写整个表
- 添加 NOT NULL 列时需要提供默认值或确保无 NULL 值
- 外键约束会影响性能
- 大表的结构修改可能需要很长时间
小结
ALTER TABLE 是 PostgreSQL 中修改表结构的强大工具:
- 添加/删除列:扩展或精简表结构
- 修改列属性:更改数据类型、默认值、NULL 约束
- 管理约束:添加或删除主键、外键、唯一和检查约束
- 重命名:重命名表和列
- 其他操作:更改所有者、表空间等
合理使用 ALTER TABLE 可以灵活地调整数据库结构以适应业务需求。