1 格式:
Create view<视图名>[<列名>,<列名>...]
as <子查询>
[with check option]
with check option表示对视图进行,update,insert和delete操作时
要保证更新.插入.删除的行满足视图定义中的谓词条件(即子查询的条件表达式).
组成视图的属性列名要么全部省略要么全部指定.没有第三种选择.
如果省略了列名,则隐含该视图由子查询select句子目标列的字段组成
.但以下三种情况下必须指定组成视图的所有格式
1.某个某表列不是单纯的属性名,而是聚集函数的表达式
2.多表连接时选出了几个同名列作为视图的字段.
3.需要在视图中为某个列启用新的更合适的名字.
执行Create view语句,只是把视图的定义存入数据字典,并不执行其中的select语句. 只是查询视图时,才按视图的定义从基本表中将数据查出
3.84 建立信息系学生的视图
create view IS_Student
as
select Sno,Sname,Sage
from student
where Sdept = 'IS';
3.85 建立信息系学生的视图,并要求进行修改和插入操作时仍需保证该视图只有信息系的学生
create view IS_Student
as
select Sno,Sname,Sage
from student
where Sdept = 'IS';
with check option;
由于加了with check option以后对该视图进行插入,修改,删除操作时,
关系数据库管理系统会自动加上Sdept = 'IS'的条件
若一个视图是从单个基本表导出,并且只是去掉了基本表的某些行和某些列,但是保留了主码,则称这类视图为行列子集视图
3.86 建立信息系统选修了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';
3.87 建立信息系选修了1号课程切成绩在90分以上的学生的视图.
create view IS_S2
as
select Sno,Sname,Grade
from IS_S1
where Grade >= 90;
3.88 定义一个反映学生出生年份的视图
create view BT_S(Sno,Sname,Sbirth)
as
select sno,sname,2020-Sage -- 带表达式的视图
from Student;
3.89 将学生的学号及平均成绩定义为一个视图
create view S_G(Sno,Gavg)
as
select sno,AVG(Grade)
from sc
group by sno; -- 分组视图
3.90 将student表中所有女生记录定义为一个视图
create view F_Student(F_Sno,name,sex,age,dept)
as
select *
from student
where Ssex = '女';
这里的视图F_Student是由子查询select建立的.
F_Student视图的属性列与Student表的属性列一一对应.
如果以后修改了Student表的结构,映像关系被破坏,视图无法正常工作
为了避免此类问题,最好在修改基本表后删除改视图,重建视图.
格式:
Drop VIEW <视图名> [CASCADE]
cascade表示级联关系,加上这个条件会将跟这个视图有关的视图级联删除.
3.91 删除视图BT_S和视图IS_S1
drop view BT_S; -- 成功执行
drop view IS_S1; -- 拒绝执行
drop view IS_S1 cascade; -- 删除了视图IS_S1和它导出的所有视图
关系数据库管理系统执行对视图的查询时,
首先进行有效性检查,检查查询中涉及的表,视图等是否存在.
如果存在,则从数据字典中取出视图的定义,
把定义中的子查询和用户的查询连接起来
转化成等价的对基本表的查询,然后执行修正了的查询
这个转化过程称为 视图消解
3.92 在信息学生的视图中找出年龄小于20的孩子
select Sno,Sage
from IS_Student
where Sage < 20;
3.93 查询选修了1号课程的信息系学生
select IS_Student.Sno,Sname
from IS_Student,SC
where IS_Student.Sno = SC.Sno and SC.Cno = '1';
3.94 在S_G视图(例3.89中定义的视图)中查询成绩在90分以上的学生学号和平均成绩,语句为
select *
from S_G
Where Gavg >= 90;
或结合S_G中的查询语句实现
3.89 将学生的学号及平均成绩定义为一个视图
create view S_G(Sno,Gavg)
as
select sno,AVG(Grade)
from sc
group by sno; -- 分组视图
select Sno,Avg(Grade>
from sc
group by sno
having avg(Grade)>=90; -- having 不能改为 where
或者如下语句
select *
from (select Sno,AVG(Grade) /*子查询生成一个派生表S_G*/
from sc
group by Sno) As S_G(Sno,Gavg)
where Gavg >= 90;
更新视图是指通过视图来插入,删除和修改数据,
由于视图时不实际存储数据的虚表,因此对视图的更新最终要转换为对基本表的更新.
3.95 将信息系学生视图IS_Student中学号为"201215122"的学生姓名改为"刘辰"
update IS_Student
set Sname = '刘辰'
where Sno = '201215122'
转化后的更新语句为
update Student
set Sname = '刘辰'
where Sno = '201215122' and
Sdept = 'IS';
3.96 向信息系学生视图IS_Student中插入一个新的学生记录,其中学号为'201215129',姓名为'赵新',20岁.
insert
into IS_Student
values('201215129','赵新',20);
转化为对表的更新
insert
into Student(Sno,Sname,Sage,Sdept) -- 补上视图为信息系的约束条件
values('201215129','赵新',20,'IS');
3.97 删除信息系学生视图IS_Student中学号为'201215129'的学生记录
Delete
from IS_Student
where Sno = '201215129';
转化为对基本表的更新
Delete
from Student
where Sno = '201215129'
and Sdept = 'IS';
注意:并非所有视图都可以更新,
有些视图的更新无法转化成对基本表的更新
如:每门课程的平均成绩不能直接在SC表中修改得到
一般来说,行列子集视图时可更新的.
不可更新视图与不允许更新视图时两个概念,
前者指理论上无法更新
后者指系统不支持这种更新
合理使用视图能够带来许多好处
视图机制使用户可以将精力集中在所关心的数据上
重构数据库最常见的就是将一个基本表"垂直"地分成多个基本表,例如:将学生关系Student(Sno,Sname,Sage,Ssex,Sdept)
分为SX(Sno,Sname,Sage)和SY(Sno,Ssex,Sdept)两个关系
这时原表为SX和SY自然连接的结果
例如经常要执行这样的查询,“对每个同学找出他获得最高成绩的课程号”.可以先定义一个视图,求出每个同学获得的最高成绩:
create view VMGRADE
as
select Sno,Max(Grade) Mgrade
from SC
group BY Sno;
然后利用查询求出每个同学获得的最高成绩
Select SC.Sno,Cno,SC.Grade
from sc,VMGRADE
where sc.sno = VMGRADE.Sno
and SC.Grade = VMGRADE.Mgrade;