视图的基本概念 视图是从一个或几个基本表(或者视图)导出的表。它与基本表不同,是一个虚表。 数据库只存放视图的定义,而不存放视图对应的数据,这些数据仍存放在原来的基本表中。所以基本表中的数据发生变化,从视图中查询出的数据也就随之改变了。 视图
视图是从一个或几个基本表(或者视图)导出的表。它与基本表不同,是一个虚表。
数据库只存放视图的定义,而不存放视图对应的数据,这些数据仍存放在原来的基本表中。所以基本表中的数据发生变化,从视图中查询出的数据也就随之改变了。
视图一经定义,就可以和基本表一样被查询、被删除。也可以在一个视图之上再定义新的视图,但对视图的更新(增、删、改)操作则有一定的限制。
视图相比基本表有以下优点:
1.视图能够简化用户的操作
视图机制用户可以将注意力集中在所关心的数据上。如果这些数据不是直接来自基本表,则可以通过定义视图,使数据库看起来结构简单、清晰,并且可以简化用户的数据查询操作。
2.视图是用户能以不同的角度看待同样的数据。
对于固定的一些基本表,我们可以给不同的用户建立不同的视图,这样不同的用户就可以看到自己需要的信息了。
3.视图对重构数据库提供了一定程度的逻辑性。
比如原来的A表被分割成了B表和C表,我们仍然可以在B表和C表的基础上构建一个视图A,而使用该数据表的程序可以不变。
4.视图能够对机密数据提供安全保护
比如说,每们课的成绩都构成了一个基本表,但是对于每个同学只可以查看自己这门课的成绩,因此可以为每个同学建立一个视图,隐藏其他同学的数据,只显示该同学自己的数据。
5.适当的利用视图可以更加清晰的表达查询
有时用现有的视图进行查询可以极大的减小查询语句的复杂程度。
说明:本文章中的用来作为示例的数据表有三个:student、course、sc 数据表具体请看:Mysql数据库中的EXISTS和NOT EXISTS
SQL视图建立命令
CREATE VIEW [([,]…)]
AS
[WITH CHECK OPTION];
其中,子查询可以是任意复杂的SELECT语句,但通常不允许包含ORDER BY子句和DISTINCT短语(因为子查询是中间结果)。
组成视图的属性列名可以全部省略或全部指定,如果省略,则隐含由子查询中SELECT目标列中的诸字段组成;
但在下列情况下必须明确指定视图的所有列名:
(1)某个目标列不是单纯的属性名,而是聚集函数或列表达式,或者目标列为*
(2)多表连接时选出了几个同名列作为视图的字段
(3)需要在视图中为某个列启用新的更合适的名字
RDBMS执行CREATE VIEW语句时只是把视图的定义存入数据字典,并不执行其中的SELECT语句。在对视图查询时,按视图的定义从基本表中将数据查出。
建立的视图可以简单的分为以下三类:
若一个视图是从单个基本表导出的,并且只是去掉了基本表的某些行和某些列,但保留了主码,我盟称这类视图为行列子集视图
例子1.1
建立信息系学生的视图
SQL语句:
CREATE VIEW IS_Student AS SELECT Sno, Sname, Sage FROM Student WHERE Sdept= 'IS'
WITH CHECK OPTION表示对视图进行UPDATE、INSERT和DELETE操作时要保证更新、插入或删除的行满足视图定义中的谓词条件(即子查询中的条件表达式)
例子1.2
建立信息系学生的视图,并要求透过该视图进行的更新操作只涉及信息系学生
SQL语句:
CREATE VIEW IS_Student AS SELECT Sno, Sname, Sage FROM Student WHERE Sdept= 'IS' WITH CHECK OPTION;
视图不仅可以建立在单个基本表上,也可以建立在多个基本表上,或者建立在基本表和视图的基础上。
例子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';
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;
还可以用带有聚集函数和GROUP BY子句的查询来定义视图,这种视图称为分组视图。
例子3.1将学生的学号及他的平均成绩定义为一个视图
CREATE VIEW S_G(Sno, Gavg) AS SELECT Sno, AVG(Grade) FROM SC GROUP BY Sno;
由于AS子语句中SELECT语句语句的目标列平均成绩是通过作用聚集函数得到的,所以CREATE VIEW中必须明确定义组成S_G视图的每个属性列名,S_G是一个分组视图。
例子3.2将Student表中所有女生记录定义为一个视图
CREATE VIEW F_Student1(stdnum, name, sex, age, dept) AS SELECT * FROM Student WHERE Ssex='女';
这里的视图F_Student1是由子查询“SELECT *”建立的,需要明确定义组成F_Student1视图的每个属性列名。
视图定义以后,用户就可以像查询基本表一样查询视图了。
因此从用户角度看,查询视图与查询基本表相同。
不过,所有对视图的查询,都会被数据库管理软件解释成对基本数据表的查询,因为视图是在基本表的基础上抽象出来的。
例子4.1在信息系学生的视图中找出年龄小于20岁的学生
SELECT Sno, Sage FROM IS_Student WHERE Sage <br> <p>IS_Student视图的定义(视图定义例1):<br> </p> <p> </p><pre class="brush:php;toolbar:false">CREATE VIEW IS_Student AS SELECT Sno, Sname, Sage FROM Student WHERE Sdept= 'IS';
SELECT Sno, Sage FROM Student WHERE Sdept='IS' AND Sage <br> <h2>更新视图</h2> <p>更新视图是指通过视图插入、删除和修改数据。</p> <p><br> 由于视图是不实际存储数据的虚表,因此对视图的更新最终要转换为对基本表的更新。</p> <p><br> 从用户角度看,更新视图与更新基本表相同;RDBMS将之转化为对基本表的更新操作。</p> <p><br> 为防止用户通过视图对数据进行更新时,有意无意地对不属于视图范围内的基本表数据进行操作,可以在定义视图时加上WITH CHECK OPTION子句。</p> <p>这样在视图上增删改数据时,RDBMS会检查视图定义中的条件,若不满足条件,则拒绝执行该操作。<br> </p> <p><br> </p> <p>例子5.1将信息系学生视图IS_Student中学号95002的学生姓名改为“刘辰”</p> <p> </p><pre class="brush:php;toolbar:false">UPDATE IS_Student SET Sname='刘辰' WHERE Sno='95002';
UPDATEStudent SET Sname='刘辰' WHERE Sno='95002' AND Sdept='IS';
一般地,行列子集视图是可更新的,除此之外,还有一些视图理论上是可更新的,但他们的确切特征还是尚待研究的课题,还有些视图从理论上就是不可更新的。
删除视图的语句格式:DROP VIEW ;
删除视图对生成视图的基本表没有任何影响。
删除基表时,由该基表导出的所有视图定义没有被删除,但已不能使用,必须使用DROP VIEW显式删除。
例子6.1
删除视图BT_S:
DROP VIEW BT_S;
DROP VIEW IS_S1;