编程SQL开发者 / 数据库架构师

SQL中有什么类型的视图(VIEW)?物化视图是如何工作的,它们与普通视图有什么区别?何时使用它们是合理的?

用 Hintsage AI 助手通过面试

答案

在SQL中有两种类型的视图:

  • 普通视图(View): 逻辑虚拟表。它们不存储数据,对VIEW的每次查询都会生成对源表的子查询。
  • 物化视图(Materialized View): 物理存储查询结果的结果在一个单独的表中,该表定期更新。

普通视图适合于抽象复杂性、简化访问、合并来自多个来源的数据。由于每次都是即时生成的,它们不会加速查询。

物化视图在处理复杂报告和分析时提高性能,因为重要的是不必每次都等待聚合和连接。必须手动或按计划进行更新,以确保数据不会过时。

普通VIEW示例:

CREATE VIEW active_users AS SELECT id, name FROM users WHERE status = 'active';

物化VIEW示例(PostgreSQL):

CREATE MATERIALIZED VIEW active_users_agg AS SELECT country, COUNT(*) as cnt FROM users WHERE status = 'active' GROUP BY country; -- 更新: REFRESH MATERIALIZED VIEW active_users_agg;

诱导性问题

可以在VIEW中更新数据吗,这取决于VIEW的类型吗?

人们常常错误地认为VIEW在可更新性方面与表完全相同。 实际上:

  • 普通VIEW通常不允许更新:只有在没有聚合、分组或复合/计算字段时(且没有JOIN和子查询的情况下)。
  • 物化VIEW不能直接更新——只能通过 REFRESH,否则会导致数据不一致。

由于对主题细节不了解而造成的真实错误示例


故事 1

BI报告通过普通VIEW与多个JOIN和聚合构建。随着负载增加,报告构建时间增加到几十分钟。系统分析师提议使用物化视图,立即将时间减少到几秒钟,因为数据被存储在单独的表中。


故事 2

开发人员在迁移到Oracle时尝试通过普通VIEW进行UPDATE,导致错误:“具有GROUP BY的视图不可更新”。原因是视图中使用了GROUP BY。


故事 3

在一家公司,员工在导入新数据后忘记更新物化视图,这导致不同用户之间的报告不一致,因为分析师使用的是该VIEW中的旧数据。之后添加了按计划进行的自动 REFRESH