视图(VIEW)的使用:创建视图、查询视图、视图与安全、物化视图概念

视图这东西,说白了就是一张虚拟表。我第一次接触视图时觉得它没啥用——不就是把查询结果存起来吗?后来在项目中踩过坑才明白,视图用好了,能省一半的代码量,还能把数据库权限管得明明白白。

今天咱们就聊聊视图的四个核心话题:怎么创建、怎么查、怎么用视图做安全控制,以及物化视图到底是个什么玩意儿。

什么是视图?

视图不存数据,它只存一条 SELECT 语句。你查视图时,数据库会动态执行这条语句,把结果返回给你。所以视图也叫「虚拟表」。

举个例子:

CREATE VIEW v_employee_salary AS
SELECT e.emp_id, e.name, d.dept_name, s.salary
FROM employee e
JOIN department d ON e.dept_id = d.dept_id
JOIN salary s ON e.emp_id = s.emp_id
WHERE s.salary > 5000;

以后你查高薪员工,直接 SELECT * FROM v_employee_salary 就行,不用每次都写那串长长的 JOIN。

我的习惯:视图命名我喜欢加个 v_ 前缀,一眼就能看出是视图还是表。团队协作时,这个习惯能省不少沟通成本。

创建视图的几种方式

创建视图的语法其实很简单,但有几个细节我建议你注意一下。

基本创建

CREATE VIEW v_active_users AS
SELECT user_id, username, email
FROM users
WHERE status = 'active';

带 WITH CHECK OPTION

这个选项有意思。它保证你通过视图插入或修改的数据,仍然能被视图查出来。我遇到过一个问题:有人通过视图插入了一条 status='inactive' 的记录,结果这条记录在视图里看不见了,数据就「丢了」。

CREATE VIEW v_active_users AS
SELECT user_id, username, email, status
FROM users
WHERE status = 'active'
WITH CHECK OPTION;

加了 WITH CHECK OPTION 之后,如果你试图插入 status='inactive' 的记录,数据库会直接报错。嗯,这个坑我踩过一次,后来就再也没忘过。

创建视图的注意事项

  • 视图里不能有 ORDER BY(除非用了 TOP/LIMIT)
  • 视图依赖的表如果被删了,视图会失效
  • 视图可以嵌套,但嵌套太深性能会变差

查询视图

查询视图和查表一模一样。你把它当成普通表用就行。

SELECT * FROM v_active_users WHERE username LIKE '张%';

但有一点要记住:视图只是包装了一层查询。你查视图时,数据库会先执行视图里的 SELECT,再执行你外面的 WHERE。所以如果视图本身就很复杂,外面再加条件,性能可能会翻车。

我曾经踩过的坑:有个视图关联了 8 张表,同事直接在上面做分页查询,结果每次查询都要跑几秒。后来我把视图拆成了两个,加上索引,才把性能拉回来。视图不是万能的,复杂查询该写存储过程还是得写。

视图与安全

视图在安全方面有个很实用的场景:隐藏敏感字段

比如你的员工表里有 salary 字段,但普通用户不该看到。你可以创建一个视图,只暴露非敏感字段:

CREATE VIEW v_employee_public AS
SELECT emp_id, name, dept_id, hire_date
FROM employee;

然后给普通用户只授予视图的查询权限,不给他们查原表。这样他们能看到员工信息,但看不到工资。

我当年做一个人力资源系统时,就是这么干的。财务部的人能查原表,HR 专员只能查视图。权限控制得清清楚楚,审计来查也没问题。

安全要点:
  • 视图可以隐藏敏感列(如密码、工资)
  • 视图可以限制数据行(如只显示本部门数据)
  • 视图可以屏蔽底层表结构变化

物化视图概念

普通视图是虚拟的,每次查询都重新跑 SQL。物化视图不一样——它真的把数据存下来了。

物化视图 = 查询结果 + 物理存储。查它的时候不用再跑 SQL,直接从磁盘读数据,快得很。

但代价是什么?数据不是实时的。你得手动或定时刷新物化视图,才能拿到最新数据。

-- 创建物化视图(以 PostgreSQL 为例)
CREATE MATERIALIZED VIEW mv_sales_summary AS
SELECT product_id, SUM(amount) AS total_sales
FROM sales
GROUP BY product_id;

-- 刷新物化视图
REFRESH MATERIALIZED VIEW mv_sales_summary;

什么时候用物化视图?我总结了几种场景:

  • 报表系统:数据不需要实时,每天凌晨刷新一次就行
  • 大表聚合查询:比如统计上亿条数据的月报,每次都跑太慢
  • 跨库查询:把多个库的数据汇总到一个物化视图里
我的建议:物化视图不是银弹。如果你的数据要求秒级实时,别用它。另外,刷新物化视图时可能会锁表,生产环境要选在业务低峰期执行。

知识体系图

下面这张图帮你理清视图的核心脉络:

视图 (VIEW) 创建视图 CREATE VIEW v_name AS SELECT ... FROM ... WHERE ... 查询视图 SELECT * FROM v_name (和查表一样,但性能要注意) 视图与安全 隐藏敏感字段 限制数据行范围 屏蔽底层表结构 GRANT SELECT ON v_name TO user 物化视图 物理存储 + 定时刷新 适合报表、大表聚合

视图 vs 物化视图

对比项 普通视图 物化视图
数据存储 不存数据,只存 SQL 物理存储查询结果
查询性能 每次重新执行 SQL 直接读磁盘,快
数据实时性 实时 非实时,需刷新
占用空间 几乎不占 占用磁盘空间
适用场景 权限控制、简化查询 报表、数据仓库
一句话总结:普通视图是「快捷方式」,物化视图是「快照」。选哪个,取决于你要实时性还是要性能。

好了,视图这块的内容就聊到这儿。你写代码时不妨试试用视图封装一些常用的复杂查询,既能省代码,又能把权限管好。物化视图嘛,等你的数据量上来了,自然会用到它。


公众号:蓝海资料掘金营,微信deep3321