物化视图概述
物化视图(Materialized View)是 PostgreSQL 提供的一个扩展功能,它是介于视图和表之间的一种对象。
物化视图和视图的最大区别是它不仅存储定义中的查询语句,而且可以像表一样存储数据。物化视图和表的最大区别是它不支持 INSERT、UPDATE、DELETE 以及 MERGE 语句,只能通过刷新物化视图进行数据的更新。
物化视图通过提前运行并存储查询结果,通常用于查询优化、数据仓库、数据集成等场景。
另外,PostgreSQL 目前不支持物化视图的实时更新,因此物化视图中的数据通常不是最新数据。
创建物化视图
PostgreSQL 使用 CREATE MATERIALIZED VIEW 语句创建视图:
CREATE MATERIALIZED VIEW [ IF NOT EXISTS ] name
AS query
[ WITH [ NO ] DATA ];
其中,IF NOT EXISTS 可以避免重复创建一个已经存在的物化视图时产生错误;name 是物化视图的名称;query 是物化视图的查询语句。
WITH DATA 表示创建时填充物化视图中的数据,这个是默认选项;WITH NO DATA 表示创建时不填充数据,此时无法查询物化视图中的数据,需要执行 REFRESH MATERIALIZED VIEW 命令刷新物化视图数据之后才能查询。
💡虽然物化视图定义中的查询语句支持 ORDER BY 子句,但是不推荐使用。如果想要以指定顺序显示数据,应该在查询数据时明确指定排序字段,而不应该依赖表中的数据存储顺序。
以下语句创建了一个包含员工统计信息的物化视图:
CREATE MATERIALIZED VIEW emp_stat_mv
AS
SELECT d.department_name, j.job_title, count(*)
FROM employees e
JOIN departments d ON d.department_id = e.department_id
JOIN jobs j ON j.job_id = e.job_id
GROUP BY d.department_name, j.job_title;
物化视图 emp_stat_mv 包含了按照部门和职位统计的员工数量。
我们可以直接查询 emp_stat_mv,获取员工统计信息:
SELECT *
FROM emp_stat_mv
ORDER BY department_name;
department_name |job_title |count|
----------------+-------------------------------+-----+
Accounting |Public Accountant | 1|
Accounting |Accounting Manager | 1|
Administration |Administration Assistant | 1|
Executive |Administration Vice President | 2|
Executive |President | 1|
Finance |Accountant | 5|
Finance |Finance Manager | 1|
Human Resources |Human Resources Representative | 1|
IT |Programmer | 5|
Marketing |Marketing Manager | 1|
Marketing |Marketing Representative | 1|
Public Relations|Public Relations Representative| 1|
Purchasing |Purchasing Clerk | 5|
Purchasing |Purchasing Manager | 1|
Sales |Sales Representative | 29|
Sales |Sales Manager | 5|
Shipping |Stock Manager | 5|
Shipping |Stock Clerk | 20|
Shipping |Shipping Clerk | 20|
物化视图可以像表一样支持索引,实现约束和查询优化。例如,以下语句为 emp_stat_mv 创建了一个唯一索引:
CREATE UNIQUE INDEX uk_emp_stat_mv ON emp_stat_mv(department_name, job_title);
刷新物化视图
PostgreSQL 物化视图不会自动刷新数据,需要手动执行 REFRESH MATERIALIZED VIEW 语句:
REFRESH MATERIALIZED VIEW [ CONCURRENTLY ] name
[ WITH [ NO ] DATA ];
其中,CONCURRENTLY 可以支持刷新物化视图时其他连接的并发读取。使用该选项的前提是物化视图上至少存在一个唯一索引,而且不能是表达式索引或者部分索引。
WITH DATA 表示刷新时填充物化视图中的数据,这个是默认选项;WITH NO DATA 表示刷新时不填充数据,刷新后物化视图处于不可查询状态。
CONCURRENTLY 和 WITH NO DATA 选项不能一起使用。未填充数据的物化视图刷新时不支持 CONCURRENTLY 选项。
💡如果在物化视图定义的查询语句中指定了 ORDER BY 子句,刷新物化视图数据时不会保证数据仍然按照指定顺序进行存储。
例如,我们可以定期执行以下语句刷新物化视图 emp_stat_mv 中的数据:
REFRESH MATERIALIZED VIEW CONCURRENTLY emp_stat_mv;
或者执行以下语句清空物化视图 emp_stat_mv 中的数据:
REFRESH MATERIALIZED VIEW emp_stat_mv
WITH NO DATA;
修改物化视图
ALTER MATERIALIZED VIEW 语句可以修改物化视图的一些属性,例如名称、字段名等:
ALTER MATERIALIZED VIEW [ IF EXISTS ] name
RENAME [ COLUMN ] column_name TO new_column_name;
ALTER MATERIALIZED VIEW [ IF EXISTS ] name
RENAME TO new_name;
ALTER MATERIALIZED VIEW [ IF EXISTS ] name
SET SCHEMA new_schema;
第一个语法用于修改物化视图的字段名称,第二个语法用于修改物化视图的名称,第三个语法用于修改物化视图所在的模式。
例如,以下语句将物化视图 emp_stat_mv 的名称修改为 emp_stat_mv2:
ALTER MATERIALIZED VIEW emp_stat_mv
RENAME TO emp_stat_mv2;
ALTER MATERIALIZED VIEW 语句不能修改物化视图定义中的查询语句;如果想要修改物化视图定义中的查询语句,需要删除并重建物化视图。
ALTER MATERIALIZED VIEW 语句还提供了其他的修改功能,具体可以参考官方文档。
删除物化视图
PostgreSQL 使用 DROP MATERIALIZED VIEW 语句删除物化视图:
DROP MATERIALIZED VIEW [ IF EXISTS ] name [ CASCADE | RESTRICT ];
其中,IF EXISTS 可以避免删除一个不存在的物化视图时产生错误;CASCADE 表示级联删除依赖于该物化视图的对象;RESTRICT 表示如果存在依赖对象则提示错误信息,这是默认值。文章来源:https://www.toymoban.com/news/detail-656997.html
我们可以使用以下语句删除物化视图 emp_stat_mv2:文章来源地址https://www.toymoban.com/news/detail-656997.html
DROP MATERIALIZED VIEW emp_stat_mv2;
到了这里,关于《PostgreSQL 开发指南》第32篇 物化视图的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!