摘要:想象一下,你是一个图书馆的管理员。你不想让每个读者都直接去访问那个巨大、复杂、存放着所有书籍原始信息的总仓库。你更希望为不同类型的读者(比如“历史爱好者”、“科幻迷”)分别创建一个专门的、虚拟的书架,上面只展示他们感兴趣的书籍信息。
想象一下,你是一个图书馆的管理员。你不想让每个读者都直接去访问那个巨大、复杂、存放着所有书籍原始信息的总仓库。你更希望为不同类型的读者(比如“历史爱好者”、“科幻迷”)分别创建一个专门的、虚拟的书架,上面只展示他们感兴趣的书籍信息。
在数据库的世界里,视图 (View) 就扮演着这个“虚拟书架”的角色。
视图本质上是一个存储在数据库中的 SELECT 查询,它被赋予一个名字,表现得就像一张真实的、只读的表。用户可以像查询普通表一样查询视图,但视图本身不存储任何数据。它只是一个窗口,透过它,我们可以看到基表(Underlying Tables)中的数据,但看到的是经过筛选、连接和计算后的结果。
使用视图的好处:
简化复杂性:将一个复杂的、多表 JOIN 的查询封装成一个简单的视图。以后需要这个查询结果时,只需要 SELECT * FROM my_view; 即可,大大降低了使用门槛。逻辑封装:将核心的业务逻辑(比如如何计算“活跃用户”)定义在视图中。所有需要这个逻辑的地方都引用该视图,保证了逻辑的一致性。安全性:可以只对用户开放特定视图的查询权限,而不是底层表的权限。通过视图,你可以精确地控制用户能看到哪些行、哪些列,从而隐藏敏感信息(如薪水、密码哈希等)。向后兼容:当底层表结构发生变化时,只要视图的输出保持不变,依赖于该视图的应用程序就无需修改。场景:在我们的电商应用中,运营人员经常需要查看一份包含订单ID、订单金额、下单用户姓名和邮箱的报告。这个查询需要 JOIN users 和 orders 两张表。
不使用视图的做法:
每次运营人员需要报告时,都得写(或者运行一个保存好的)复杂的 JOIN 查询:
使用视图的做法:
我们可以把上面这个查询逻辑,封装成一个名为 large_orders_report 的视图。
CREATE VIEW view_name AS ... 就是创建视图的语法。
如何使用视图?
创建成功后,我们就可以像查询一张普通的表一样来查询这个视图了!
这条简单的命令,返回的结果和上面那个复杂的 JOIN 查询完全一样!
我们甚至可以在查询视图的基础上,再进行过滤和排序:
SELECT * FROM large_orders_reportWHERE username = 'zhangsan'ORDER BY amount DESC;数据库会自动把视图的 WHERE 条件和我们新加的 WHERE 条件合并起来执行。
视图是如何工作的?
当你查询一个视图时,PostgreSQL 并不会真的去执行 SELECT * FROM large_orders_report。它会把这个查询“展开”,替换成视图定义里的那个原始的、复杂的 JOIN 查询。所以,视图只是一个“查询宏”,一个别名,它本身不占用存储空间(除了定义本身)。
普通视图虽然方便,但有一个缺点:每次查询视图,底层那个复杂的查询都会被重新执行一遍。如果视图的查询逻辑非常耗时,而数据又不是实时变化的,那么每次都重算就太浪费了。
为了解决这个问题,PostgreSQL 提供了一个大杀器——物化视图 (Materialized View)。
物化视图和普通视图的核心区别在于:
它会真实地存储查询结果。当你创建物化视图时,它会执行那个 SELECT 查询,并把结果像一张真实的表一样物理存储下来。查询物化视图时,数据库直接从这个存储好的结果中读取数据,速度极快,因为不需要再计算了。缺点是,数据不是实时的。底层基表的数据发生变化后,物化视图里的数据不会自动更新。你必须手动地去刷新 (Refresh) 它。使用场景:适用于那些对数据实时性要求不高,但查询非常频繁、计算又非常昂贵的报表和统计场景。比如,每日的销售总额统计、每月的用户增长报告等。
创建物化视图:
语法很简单,就是在 CREATE VIEW 中间加一个 MATERIALIZED 关键字。
查询物化视图:
和普通视图一样,就像查询一张表。
这个查询会非常快,无论 orders 表有多大。
刷新物化视图:
当 orders 表有了新数据后,我们需要手动执行 REFRESH 命令来更新 daily_sales_summary。
注意:REFRESH 默认会锁住视图,导致刷新期间无法查询。对于大型物化视图,可以使用 REFRESH MATERIALIZED VIEW CONCURRENTLY ... 来进行并发刷新,但这要求物化视图上有一个 UNIQUE 索引。
本章小结
你已经掌握了如何使用视图来构建一个更简洁、更安全、更高效的数据访问层。
我们学会了创建和使用普通视图 (VIEW),将复杂的查询逻辑封装成一个简单的虚拟表。我们理解了视图在简化查询、保障安全方面的重要作用。我们还学习了强大的物化视图 (MATERIALIZED VIEW),以及如何用它来为耗时的查询“缓存”结果,并通过 REFRESH 来更新它。视图是数据库设计中一个非常优雅的工具。善用视图,能让你的数据库架构层次更分明,逻辑更清晰。
在下一章,我们将探讨数据库性能优化的核心话题——索引 (Indexes)。我们将了解索引是如何像书的目录一样,帮助数据库实现闪电般快速的查询。准备好让你的查询“飞”起来了吗?我们下一章见!
来源:linux运维菜