【视图】
视图是从一个或几个基本表导出的表,其是一个虚表
数据库中仅存放视图定义,不存放其具体数据,这些具体数据仍在原来的基本表中,因此基本表中的数据一旦发生变化,从视图中查询出的数据也就随之改变了
视图一经定义,就可以与基本表一样被查询、删除,但对其更新有一定的限制,此外,还可以定义基于视图的视图
视图机制使用户可以将注意力集中在他所关心的数据上,如果这些数据不是直接来自基本表,则可以通过定义视图,使用户眼中的数据库结构简单、清晰,以简化用户的数据查询操作
同时,视图使用户以多种角度看待同一数据,当许多不同种类的用户使用同一个数据库时,这种灵活性是非常重要的
而在设计数据库应用系统时,对不同用户定义不同的视图,使机密数据不出现在不应看到这些数据的用户视图上,这样就由视图的机制自动提供了对机密数据的安全保护功能
此外,视图对重构数据库提供了一定程度的逻辑独立性
【视图定义】
基本语法
在 SQL 中,建立视图的语法如下
1 | CREATE VIEW <视图名> [(<列名1> [,<列名2>]...[,<列名n>])] |
<子查询>
可以是任意的 SELECT
查询语句,RDBMS 执行建立视图的语句时,只是将视图定义存入数据字典,没有执行其中的 SELECT
语句,仅当对数据查询时,才按视图的定义从基本表中将数据查出
列名
<列名>
是要组成视图的列的新名,如果全部省略,则该视图的列名将默认使用 SELECT
子句目标列的列名
如下例,通过基本表 student 建立 CS 系学生的视图 is_student,要求视图中包含学号 Sno、姓名 Sname、年龄 Sage
1 | CREATE VIEW is_student |
该例中省略了组成视图的列,此时视图由子查询中 SELECT
子句中的三个列名组成
如果不省略,则 <列名>
的与 SELECT
子句目标列的一一对应,要求 <列名>
个数与 SELECT
子句目标列的个数相同
如下例,通过基本表 student 建立 CS 系学生的视图 is_student,要求视图中包含基本表中的学号 Sno、姓名 Sname、年龄 Sage,同时要求视图中的列名依次为 number、name、age
1 | CREATE VIEW is_student(number, name, age) |
此外,若视图由 SELECT *
建立,则必须要指定 <列名>
,使用该种方法建立的视图可扩充性差,一旦基本表的结构改变,则基本表与视图的映射将被破坏,只能重新建立视图,因此应尽量避免使用该方法创建视图
例如,通过基本表 student 建立包含所有男生记录的视图 f_student
1 | CREATE VIEW f_student(f_sno, name, sex, age, dept) |
保证谓词条件
WITH CHECK OPTION
代表对视图进行修改、删除、插入操作时,行要满足视图定义的谓词条件(子查询中的条件表达式)
如下例,通过基本表 student 建立 CS 系学生的视图 is_student,要求进行修改和插入操作时仍需保证该视图只有信息系学生
1 | CREATE VIEW is_student |
该例中加上了 WITH CHECK OPTION
子句,这样以后对该视图进行修改、删除、插入操作时,RDBMS 会自动加上 Sdept='IS'
的条件:
- 修改:自动加上
Sdept='IS'
的条件 - 删除:自动加上
Sdept='IS'
的条件 - 插入:自动检查
Sdept='IS'
的条件,若不是,则拒绝该插入操作;若未提供Sdept
属性值,则自动设为'IS'
视图类型
若视图是从单个基本表导出的,且仅是去除了基本表的某些行列,但保留了主码,则称这类视图为行列子集视图
例如,通过基本表 student 建立 CS 系学生的视图 is_student,要求视图中包含学号 Sno、姓名 Sname、年龄 Sage
1 | CREATE VIEW is_student |
若视图是从多个基本表导出的,则称这类视图为基于多个基表的视图
例如,通过基本表 student 和 sc 来建立 CS 系选修了 1 号课程的学生的视图 cs1,要求视图中包含学号 Sno、姓名 Sname、成绩 Grade
1 | CREATE VIEW cs1 (Sno, Sname, Grade) |
视图不仅可以建立在一个或多个基本表上,也可以建立在一个或多个已定义好的视图上,这类视图称为基于视图的视图
例如,通过视图 cs1 来建立成绩在 90 分以上 的学生的视图 cs2
1 | CREATE VIEW cs2 |
由于视图中的数据并不实际存储,因此定义视图时可以根据应用的需要设置一些派生属性列,这些派生属性由于在基本表中并不实际存在,因此被称为虚拟列,这些带虚拟列的视图被称为带表达式的视图
例如,通过基本表 student 建立一个反映学生出生年份的视图 birth,已知该表中所有学生的入学时间都是 2017 年
1 | CREATE VIEW birth(Sno, Sname, Sbrith) |
当使用聚集函数和 GROUP BY
子句的查询来定义视图时,这种视图称为分组视图
例如,通过基本表 sc 建立一个视图 avg_grade,包括学生学号和平均成绩
1 | CREATE VIEW avg_grade(Sno, Gavg) |
【视图删除】
若基本表删除被删除,那么由该基本表导出的所有视图均无法使用,但是视图的定义还没有从数据字典中删除,此时就需要调用视图删除语句,将视图删除
在 SQL 中,删除视图的语法为
1 | DROP VIEW <视图名> [CASCADE]; |
执行该语句后,视图的定义将从数据字典中删除,如果该视图上还导出了其他视图,那么可以使用级联短语 CASCADE
将该视图及其导出的视图一并删除