视图的基本概念
视图是从一个或几个基本表(或者视图)导出的表。它与基本表不同,是一个虚表。
数据库只存放视图的定义,而不存放视图对应的数据,这些数据仍存放在原来的基本表中。所以基本表中的数据发生变化,从视图中查询出的数据也就随之改变了。
视图一经定义,就可以和基本表一样被查询、被删除。也可以在一个视图之上再定义新的视图,但对视图的更新(增、删、改)操作则有一定的限制。
视图的优点
视图相比基本表有以下优点:
1.视图能够简化用户的操作
视图机制用户可以将注意力集中在所关心的数据上。如果这些数据不是直接来自基本表,则可以通过定义视图,使数据库看起来结构简单、清晰,并且可以简化用户的数据查询操作。
2.视图是用户能以不同的角度看待同样的数据。
对于固定的一些基本表,我们可以给不同的用户建立不同的视图,这样不同的用户就可以看到自己需要的信息了。
3.视图对重构数据库提供了一定程度的逻辑性。
比如原来的A表被分割成了B表和C表,我们仍然可以在B表和C表的基础上构建一个视图A,而使用该数据表的程序可以不变。
4.视图能够对机密数据提供安全保护
比如说,每们课的成绩都构成了一个基本表,但是对于每个同学只可以查看自己这门课的成绩,因此可以为每个同学建立一个视图,隐藏其他同学的数据,只显示该同学自己的数据。
5.适当的利用视图可以更加清晰的表达查询
有时用现有的视图进行查询可以极大的减小查询语句的复杂程度。
说明:本文章中的用来作为示例的数据表有三个:student、course、sc 数据表具体请看:Mysql数据库中的EXISTS和NOT EXISTS
建立视图
CREATE VIEW <视图名>[(<列名>[,<列名>]…)]
AS <子查询>
[WITH CHECK OPTION];
组成视图的属性列名可以 全部省略或全部指定,如果省略,则隐含由子查询中SELECT目标列中的诸字段组成;
(1)某个目标列不是单纯的属性名,而是聚集函数或列表达式,或者目标列为*
(2)多表连接时选出了几个同名列作为视图的字段
(3)需要在视图中为某个列启用新的更合适的名字
RDBMS执行CREATE VIEW语句时只是把视图的定义存入数据字典,并不执行其中的SELECT语句。在对视图查询时,按视图的定义从基本表中将数据查出。
行列子集视图
CREATE VIEW IS_Student AS SELECT Sno, Sname, Sage FROM Student WHERE Sdept= 'IS'本例中省略了视图IS_Student的列名,隐含了由子查询中SELECT子句中的三个列名组成。
CREATE VIEW IS_Student AS SELECT Sno, Sname, Sage FROM Student WHERE Sdept= 'IS' WITH CHECK OPTION;
由于在定义IS_Student视图时加上了WITH CHECK OPTION子句,以后对该视图进行插入、修改和删除操作时,RDBMS会自动加上Sdept='IS'的条件:
- 插入操作:DBMS自动检查Sdept属性值是否为'IS'
- 如果不是,则拒绝该插入操作
- 如果没有提供Sdept属性值,则自动定义Sdept为'IS'
- 修改操作:DBMS自动加上Sdept= 'IS'的条件
- 删除操作:DBMS自动加上Sdept= 'IS'的条件
视图不仅可以建立在单个基本表上,也可以建立在多个基本表上,或者建立在基本表和视图的基础上。
例子1.3 建立信息系选修了1号课程的学生视图
CREATE VIEW IS_S1(Sno, Sname, Grade) AS SELECT Student.Sno, Sname, Grade FROM Student, SC WHERE Sdept= 'IS' AND Student.Sno=SC.Sno AND SC.Cno= '1';
例子1.4建立信息系选修了1号课程且成绩在90分以上的学生的视图
CREATE VIEW IS_S2 AS SELECT Sno, Sname, Grade FROM IS_S1 WHERE Grade>=90;
带表达式的视图
例子2.1 定义一个反映学生出生年份的视图
CREATE VIEW BT_S(Sno, Sname, Sbirth) AS SELECT Sno, Sname, 2000-Sage FROM Student;
分组视图
CREATE VIEW S_G(Sno, Gavg) AS SELECT Sno, AVG(Grade) FROM SC GROUP BY Sno;
CREATE VIEW F_Student1(stdnum, name, sex, age, dept) AS SELECT * FROM Student WHERE Ssex='女';
查询视图
SELECT Sno, Sage FROM IS_Student WHERE Sage<20;
CREATE VIEW IS_Student AS SELECT Sno, Sname, Sage FROM Student WHERE Sdept= 'IS';
SELECT Sno, Sage FROM Student WHERE Sdept='IS' AND Sage<20;
更新视图
由于视图是不实际存储数据的虚表,因此对视图的更新最终要转换为对基本表的更新。
从用户角度看,更新视图与更新基本表相同;RDBMS将之转化为对基本表的更新操作。
为防止用户通过视图对数据进行更新时,有意无意地对不属于视图范围内的基本表数据进行操作,可以在定义视图时加上WITH CHECK OPTION子句。
UPDATE IS_Student SET Sname='刘辰' WHERE Sno='95002';
转换后的语句:
UPDATEStudent SET Sname='刘辰' WHERE Sno='95002' AND Sdept='IS';
在关系数据库中,并不是所有的视图都是可更新的,因为有些视图的更新不能唯一地有意义地转换成对相应基本表的更新。
一般地, 行列子集视图是可更新的,除此之外,还有一些视图理论上是可更新的,但他们的确切特征还是尚待研究的课题,还有些视图从理论上就是不可更新的。
删除视图
删除视图BT_S:
DROP VIEW BT_S;
删除视图IS_S1:
DROP VIEW IS_S1;