PostgreSQL 视图
概述
视图(View)是基于 SQL 查询结果定义的虚拟表。视图本身不存储数据,而是在每次查询时动态执行其定义的 SQL 语句。视图的主要用途包括简化复杂查询、提供数据访问安全控制,以及为应用程序提供稳定的数据接口。
创建视图
使用 CREATE VIEW 语句创建视图:
sql
-- 创建简单视图:筛选活跃用户
CREATE VIEW active_users AS
SELECT * FROM users WHERE status = 'active';
-- 创建复杂视图:用户消费汇总
CREATE VIEW user_summary AS
SELECT
u.id,
u.name,
u.email,
COUNT(o.id) AS order_count,
COALESCE(SUM(o.total), 0) AS total_spent
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
GROUP BY u.id;使用 CREATE OR REPLACE VIEW 可以在视图已存在时更新其定义:
sql
-- 创建或替换视图
CREATE OR REPLACE VIEW active_users AS
SELECT id, name, email, created_at
FROM users
WHERE status = 'active';使用视图
视图的使用方式与普通表完全相同:
sql
-- 查询视图
SELECT * FROM active_users;
-- 在视图上添加过滤条件
SELECT * FROM user_summary WHERE total_spent > 1000;
-- 视图可以与其他表进行连接
SELECT
a.name,
a.email,
p.product_name
FROM active_users a
JOIN orders o ON a.id = o.user_id
JOIN products p ON o.product_id = p.id;可更新视图
满足以下条件的简单视图支持 INSERT、UPDATE、DELETE 操作:
- 视图基于单个表
- 不包含聚合函数、
DISTINCT、GROUP BY、HAVING、UNION - 不包含子查询
sql
-- 创建可更新视图
CREATE VIEW simple_users AS
SELECT id, name, email FROM users;
-- 通过视图插入数据
INSERT INTO simple_users (id, name, email)
VALUES (1, 'John', 'john@example.com');
-- 通过视图更新数据
UPDATE simple_users SET name = 'Jane' WHERE id = 1;
-- 通过视图删除数据
DELETE FROM simple_users WHERE id = 1;WITH CHECK OPTION
使用 WITH CHECK OPTION 可以防止通过视图插入或更新不符合视图条件的数据:
sql
-- 创建带检查选项的视图
CREATE VIEW active_users AS
SELECT * FROM users WHERE status = 'active'
WITH CHECK OPTION;
-- 以下操作会失败,因为插入的数据不满足 status = 'active' 条件
INSERT INTO active_users (id, name, status)
VALUES (2, 'Bob', 'inactive'); -- 错误!物化视图
物化视图(Materialized View)与普通视图不同,它会将查询结果实际存储在磁盘上,适合计算量大但数据更新不频繁的场景:
sql
-- 创建物化视图:按月统计销售数据
CREATE MATERIALIZED VIEW monthly_sales AS
SELECT
DATE_TRUNC('month', created_at) AS month,
COUNT(*) AS order_count,
SUM(total) AS revenue
FROM orders
GROUP BY DATE_TRUNC('month', created_at);
-- 刷新物化视图(全量刷新,会锁表)
REFRESH MATERIALIZED VIEW monthly_sales;
-- 并发刷新(不会锁定查询,需要唯一索引)
REFRESH MATERIALIZED VIEW CONCURRENTLY monthly_sales;提示
使用 CONCURRENTLY 选项进行并发刷新时,物化视图上必须有唯一索引。
删除视图
sql
-- 删除视图
DROP VIEW active_users;
-- 删除视图(如果存在)
DROP VIEW IF EXISTS old_view;
-- 级联删除(同时删除依赖该视图的对象)
DROP VIEW user_summary CASCADE;
-- 删除物化视图
DROP MATERIALIZED VIEW monthly_sales;小结
视图要点:
- 视图是基于查询定义的虚拟表,不实际存储数据
- 简化复杂查询,提供数据安全控制
- 简单视图可以执行插入、更新、删除操作
WITH CHECK OPTION确保通过视图修改的数据始终符合视图条件- 物化视图将结果缓存到磁盘,适合计算密集型查询,需手动刷新