关系数据库管理系统执行CREATE VIEW语句的结果只是把视图的定义存入数据字典,并不执行其中的SELECT语句。只是在对视图查询时,才按视图的定义从基本表中将数据查出。
基本表中的数据改变,视图中的数据也会发生改变。
[例3.85] 建立信息系学生的视图,并要求进行修改和插入操作时仍需保证该视图只有信息系的学生。
CREATE VIEW V_IS_Student AS SELECT Sno, Sname, Sage FROM student WHERE Sdept = 'IS' WITH CHECK OPTION ; SELECT * FROM V_IS_Student;
- 由于在定义视图时加上了WITH CHECK OPTION子句,以后对该视图进行插入、修改和删除操作时,关系数据库管理系统会自动加上Sdept='IS’的条件。
若一个视图是从单个基本表导出的,并且只是去掉了基本表的某些行和某些列,但保留了主码,则称这类视图为行列子集视图。
视图不仅可以建立在单个基本表上,也可以建立在多个基本表上。
[例3.86] 建立信息系选修了1号课程的学生的视图(包括学号、姓名、成绩)。
插入数据:
insert into SC values ('201215125', 1, 92), ('201215121', 2, 85), ('201215121', 3, 88), ('201215122', 2, 90), ('201215122', 3, 80); SELECT * FROM SC;
# 创建或者替换 CREATE OR REPLACE VIEW IS_S1(Sno, Sname, Grade) AS SELECT student.Sno, Sname, Grade FROM student, sc WHERE sc.Sno = student.Sno AND student.Sdept = 'IS'; SELECT * FROM IS_S1;
由于视图 IS_S1 的属性列中包含了Student 表与SC表的同名列Sno,所以必须在视图名后面明确说明视图的各个属性列名。
视图可以建立在一个或多个已定义好的视图上,或建立在基本表与视图上。
[例3.87] 建立信息系选修了 1号课程且成绩在90分以上的学生的视图。
CREATE VIEW IS_S2 AS SELECT Sno, Sname, Grade FROM IS_S1 WHERE Grade>90; SELECT * FROM IS_S2;
由于视图中的数据并不实际存储,所以定义视图时可以根据应用的需要设置一些派生属性列。
这些派生属性由于在基本表中并不实际存在,也称它们为虚拟列。
带虚拟列的视图也称为带表达式的视图。
[例3.88] 定义一个反映学生出生年份的视图。
CREATE VIEW BT_S(Sno, Sname, Sbirth) AS SELECT Sno, Sname, 2022-Sage FROM student; SELECT * FROM BT_S;
还可以用带有聚集函数和GROUP BY子句的查询来定义视图,这种视图称为分组视图。
[例3.89] 将学生的学号及平均成绩定义为一个视图。
CREATE VIEW S_G(Sno, Gavg) AS SELECT Sno, AVG(Grade) FROM sc GROUP BY Sno; SELECT * FROM S_G;
如果以后修改了基本表的结构,视图的映像关系就会被破坏,该视图就不能正常工作了。为避免出现这类问题,最好在修改基本表之后删除由该基本表导出的视图,然后重建这个视图。
2. 删除视图
该语句的格式为:
DROP VIEW 视图名 [CASCADE];
- 视图删除后视图的定义将从数据字典中删除。
- 如果该视图上还导出了其他视图,则使用CASCADE级联删除语句把该视图和由它导出的所有视图一起删除。
- 基本表删除后,由该基本表导出的所有视图均无法使用了,但是视图的定义没有从字典中清除。
- 删除这些视图定义需要显式地使用DROP VIEW语句。
[例3.91]删除视图BT S和视图IS_ S1:
DROP VIEW bt_s; DROP VIEW is_s1; # mysql不会拒绝执行 DROP VIEW is_s1 CASCADE; # is_s2没有被删除
3.7.2 查询视图
视图定义后像基本表那样查询。
关系数据库管理系统执行对视图的查询时,首先进行有效性检查,检查查询中涉及的表、视图等是否存在。
如果存在,则从数据字典中取出视图的定义,把定义中的子查询和用户的查询结合起来,转换成等价的对基本表的查询,然后再执行修正了的查询。这一转换过程称为视图消解。
但是有些情况下,这种转换不能直接进行,查询时会出现问题。(视图消解法的局限性)
MySQL可以进行正确的转换( 8.0 )
SELECT * FROM S_G WHERE Gavg>90;
定义视图并查询视图与基于派生表的查询是有区别的。
视图一旦定义,其定义将永久保存在数据字典中,之后的所有查询都可以直接引用该视图。而派生表只是在语句执行时临时定义,语句执行后该定义即被删除。
3.7.3 更新视图
更新视图是指通过视图来插入(INSERT)、 删除(DELETE) 和修改(UPDATE)数据。
由于视图是不实际存储数据的虚表,因此对视图的更新最终要转换为对基本表的更新。
对视图的更新操作也是通过视图消解,转换为对基本表的更新操作。
为防止用户通过视图对数据进行增加、删除、修改时,有意无意地对不属于视图范围内的基本表数据进行操作,可在定义视图时加上WITH CHECK OPTION子句。
这样在视图上增、删、改数据时,关系数据库管理系统会检查视图定义中的条件,若不满足条件则拒绝执行该操作。
[例3.96] 向信息系学生视图IS_ Student 中插入-一个新的学生记录,其中学号为“201215129”,姓名为“赵新”,年龄为20岁。
INSERT INTO V_IS_Student VALUES ( '201215129', '赵新', 20 );
mysql会插入失败,因为插入该数据时,系为null,与视图建立的条件(视图中的学生为信息系的),会发生冲突,with check option会进行插入检查,所以插入失败。
一般行列子集视图是可以进行更新的。行列子集视图只是基本表的选择或投影。
3.7.4 视图的作用
- 1.视图能够简化用户的操作
- 2.视图使用户能以多种角度看待同一数据
- 3.视图对重构数据库提供了一定程度的逻辑独立性
- 4.视图能够对机密数据提供安全保护
- 5.适当利用视图可以更清晰地表达查询