PostgreSQL - 视图
PostgreSQL - 视图 (Views)
Section titled “PostgreSQL - 视图 (Views)”在 PostgreSQL 中,视图(View)是一个存储的 SELECT 查询,它充当虚拟表。它本身不存储数据,而是从一个或多个底层基表派生其数据。视图通常用于简化复杂查询、强制实施安全性以及提供一致的数据接口。
- 数据抽象:视图隐藏了底层表结构和连接的复杂性,以简单、逻辑的格式呈现数据。
- 安全性:您可以授予用户访问视图的权限,而无需授予他们访问底层表的权限,从而有效地将他们限制在特定的列或行。
- 简洁性:视图可以封装一个复杂的、多表
JOIN查询,允许用户像查询单个表一样查询它。
视图是使用 CREATE VIEW 语句创建的。OR REPLACE 子句通常用于更新现有视图定义,而无需先删除它。
CREATE [ OR REPLACE ] [ TEMP | TEMPORARY ] VIEW view_name ASSELECT column1, column2, ...FROM table_nameWHERE [condition];TEMP 或 TEMPORARY 关键字创建一个视图,该视图在当前会话结束时自动删除。
示例:创建简单视图
Section titled “示例:创建简单视图”假设我们有一个 employees 表:
CREATE TABLE employees ( id SERIAL PRIMARY KEY, first_name VARCHAR(50), last_name VARCHAR(50), email VARCHAR(100) UNIQUE, salary NUMERIC(10, 2), department_id INT);
INSERT INTO employees (first_name, last_name, email, salary, department_id)VALUES('Alice', 'Williams', 'alice.w@example.com', 75000.00, 1),('Bob', 'Johnson', 'bob.j@example.com', 82000.00, 1),('Charlie', 'Brown', 'charlie.b@example.com', 68000.00, 2);现在,我们来创建一个视图,它只显示员工姓名和电子邮件,隐藏敏感的薪资信息。
CREATE OR REPLACE VIEW employee_directory ASSELECT first_name, last_name, emailFROM employeesORDER BY last_name, first_name;您现在可以像查询表一样查询此视图:
SELECT * FROM employee_directory;这将产生以下结果:
first_name | last_name | email------------+-----------+----------------------- Charlie | Brown | charlie.b@example.com Bob | Johnson | bob.j@example.com Alice | Williams | alice.w@example.com(3 rows)可更新视图与 INSTEAD OF 触发器
Section titled “可更新视图与 INSTEAD OF 触发器”如果视图满足某些条件,它将自动可更新(即,您可以在其上运行 INSERT、UPDATE 或 DELETE 操作),主要条件是它基于单个表,并且不使用聚合、DISTINCT、GROUP BY 等。对于复杂的、不可更新的视图,您可以定义 INSTEAD OF 触发器来指定尝试修改时应发生什么。
注意:过去有时会为此目的使用 RULE,但 INSTEAD OF 触发器是现代且更灵活的最佳实践。
物化视图 (Materialized Views)
Section titled “物化视图 (Materialized Views)”对于性能关键型查询,PostgreSQL 提供了物化视图(MATERIALIZED VIEW)。与标准视图不同,物化视图物理存储其结果集。这提供了更快的读取访问速度,但需要您手动 REFRESH(刷新)视图才能看到底层表的更改。
CREATE MATERIALIZED VIEW high_earners ASSELECT id, first_name, last_name FROM employees WHERE salary > 80000;
-- 要更新物化视图中的数据:REFRESH MATERIALIZED VIEW high_earners;要删除视图,请使用 DROP VIEW 语句。使用 CASCADE 可以自动删除依赖于该视图的任何对象。
DROP VIEW view_name; -- 如果其他对象依赖于它,则失败(默认是 RESTRICT)DROP VIEW view_name CASCADE; -- 删除视图及依赖对象要删除我们创建的 employee_directory 视图:
DROP VIEW employee_directory;