视图
定义
视图(虚拟表),本身是不具有数据的,它是 SQL 中的一个重要概念。
视图的创建连接了一个或多个数据表,不同的查询应用都可以建立在虚拟表之上。

视图一方面可以帮我们使用表的一部分而不是所有的表,另一方面可以针对不同的用户制定不同的查询视图。
创建、更新和删除视图
视图作为虚拟表,封装了底层与数据表的接口,它相当于是一张表或多张表的数据结果集。
因为这一特点,视图可以简化复杂的 SQL 查询,在编写视图之后,可以直接使用它,而不需要考虑视图中包含的基础查询的细节。同时,也可以根据需要更改数据格式,返回与底层数据表格式不同的数据。
通常情况下,小型项目中可以不使用视图,但是在大型项目中,以及数据表比较复杂的情况下,视图的价值就凸显出来了,它可以帮助我们把经常查询的结果集放到虚拟表中,提升查询效率。
CREATE VIEW
CREATE VIEW view_name AS
SELECT column1, column2, ...
FROM table_name
WHERE condition;
其实就是在查询语句的基础上封装了 VIEW,这样会基于 SQL 语句的结果集形成一张虚拟表。其中 view_name 为视图名称,column1, column2, ... 为视图中的字段,table_name 为基础表,condition 为查询条件。
以 NBA 球员为例,查询比 NBA 球员平均身高高的球员都有那些,显示他们的 ID 和身高。给这个视图起个名字 player_above_avg_height ,那么创建视图可以写成:
CREATE VIEW player_above_avg_height AS
SELECT player_id, height
FROM players
WHERE height > (SELECT AVG(height) FROM players);
当视图创建后,它就相当于一个虚拟表,可以直接使用
SELECT * FROM player_above_avg_height;
嵌套视图
当创建好一张视图之后,还可以在它的基础上继续创建视图,比如 player_above_avg_height 的基础上,找到比这个表中的球员平均身高高的球员,作为新的视图 player_above_avg_height_2, 那么可以写成:
CREATE VIEW player_above_avg_height_2 AS
SELECT player_id, height
FROM player_above_avg_height
WHERE height > (SELECT AVG(height) FROM player_above_avg_height);
ALTER VIEW
修改视图的语法是:
ALTER VIEW view_name AS
SELECT column1, column2, ...
FROM table_name
WHERE condition;
修改视图的语法和创建视图一样,只是对原有视图的更新。比如,要修改 player_above_avg_height ,增加一个新字段,可以写成:
ALTER VIEW player_above_avg_height AS
SELECT player_id, height, weight
FROM players
WHERE height > (SELECT AVG(height) FROM players);
下次在对视图进行查询的,视图结果会更新。
DROP VIEW
删除视图的语法是:
DROP VIEW view_name;
删除刚刚创建的视图,可以写成:
DROP VIEW player_above_avg_height;
使用视图简化 SQL 操作
视图其实就是对 SELECT 语句进行了封装,方便重用它们。
使用视图完成复杂的连接
有两张表, 分别为 player 和 height_grades。 其中 height_grades 记录了不同身高对应的身高等级。这里可以通过创建视图,来完成球员以及对应身高等级的查询。
首先,对 player 表和 height_grades 表进行连接,关联条件是球员的身高 height(在身高等级表规定的最低身高和最高身高之间),这样就可以得到这个球员对应的身高等级,对应的字段为 height_level。 然后通过 SELECT 得到想要查询的字段,分别为 player_name、height、height_level。 然后把查询结果放在视图 player_height_grades 中:
CREATE VIEW player_height_grades AS
SELECT player_name, height, height_level
FROM players
JOIN height_grades ON height >= min_height AND height <= max_height;
以后进行查询的时候,就可以直接通过视图查询,比如像查询身高介于 180cm 到 190cm 的球员,可以写成:
SELECT * FROM player_height_grades
WHERE height >= 180 AND height <= 190;
这样就把一个相对复杂的连接查询转化成了视图查询。
使用视图对数据格式化
如果经常需要输出某个格式的内容,比如想输出球员姓名和对应的球队,对应格式为 player_name(team_name), 那么就可以使用视图来完成数据格式 化的操作:
CREATE VIEW player_team AS
SELECT CONCAT(player_name, '(', team_name, ')') AS player_team
FROM players
JOIN teams ON players.team_id = teams.team_id;
首先将 player 表和 team 表进行连接,关联条件是相同的 team_id。想要的格式使用 concat 函数,将player_name 和 team_name 连接起来,并加上括号,得到 player_team。
这样就可以查询到格式化之后的结果了
SELECT * FROM player_team;
使用视图与计算字段
在数据查询中,有很多统计的需求可以通过视图来完成。
以球员比赛成绩表为例,对应的表是 player_score 表,一种有 19 个字段,代表的含义如下:

如果我想要统计每位球员在每场比赛中的二分球、三分球和罚球的得分,可以通过创建视图完成:
CREATE VIEW game_player_score AS
SELECT game_id,
player_id,
(shoot_hits-shoot_3_hits)*2 AS shoot_2_points,
shoot_3_hits*3 AS shoot_3_points,
shoot_p_hits AS shoot_p_points,
score
FROM player_score
然后就可以查询每位球员在每场比赛中的得分了:
SELECT * FROM game_player_score;
正确使用视图可以简化复杂的 SQL 查询,让 SQL 更加清爽易用。不过,视图是虚拟表,它只是封装了底层的数据查询接口,因此有些 RDBMS 不支持对视图创建索引。
总结
使用视图有很多好处,比如安全、简单清晰。
- 安全性: 虚拟表是基于底层数据表的,在使用视图时,一般不会轻易通过试图对底层数据进行修改,即便是单表视图,也会受到限制,比如计算字段、类型转换等是无法通过视图来对底层数据进行修改的,这也在一定程度上保证了数据表的数据安全性。同时,还可以针对不同用户开放不同的数据查询权限。
- 简单清晰:视图是对 SQL 查询的封装,它可以将原本复杂的 SQL 查询简化,在编写好查询之后,就可以直接重用而不必直到基本的查询细节。同时还可以在视图之上再嵌套视图。
视图是虚拟表,本身并不存储数据,只能用于查询,是对 SQL 查询的一种封装。
和临时表不同,临时表是真实存在的数据表,不过它不用于长期存放数据,只为当前连接存在,连接关闭后,临时表就会自动释放。
