您的位置:首页 > 数据库

视图操作基础

2011-10-31 20:52 204 查看
博客转移:http://vivianke.blog.163.com/blog/static/2971527120078112135634/

 

说明:视图是关系数据库系统提供给用户以多种角度观察数据库中数据的重要机制。从原理上说,它是一个或几个普通表导出的表,其与普通表最大吧不同在于它是一个虚表。数据库在管理时仅仅存放有关视图的定义,而不存放视图对应的数据,这些数据揖让存放在原来的表中。因此,一旦原来的表发生变化,那么视图也ui跟着发生变化。

注意,视图一旦定义了,就可以和普通表一样被查询、删除。当然,根据需要,也可以依据已存在的视图继续定义新的视图,此时,这个视图的更新可能也有一定的限制。

1、建立视图

建立视图的语句与表的建立具有相似行,但是从本质上来说是不一样的,它的语法如下:

CREATE VIEW <视图名>[(<列名>[, <列名>]...)]

    AS <子查询>[WITH CHECK OPTION]

其中子查询可以是任意复杂的SELECT语句,但通常不允许含有ORDER BY子句和DISTINCT语句。

WITH CHECK OPTION表示视图进行UPDATE,INSERT和DELETE 操作时候要保证更新、插入或删除的元祖满足视图定义中的条件(即子查询中条件表达式)。

组成视图的属性列名或者全部省略或者全部指定,没有第三种选择。如果省略了视图的各个属性列名,则隐含该视图由子查询中SELECT 子句目标列中的诸字段组成。但是下列三种情况必须明确指定组成视图的所有列名:

(1)需要在视图中为某个列启用新的更合适的名字时。

(2)某个目标列不是单纯的属性名,而是实用函数或列表达式的情况下。

(3)多表连接时选出了几个同名列作为视图的字段时。

在数据库中建立视图是很方便的。例如要建立物理系学生的视图PH_Student,用到SQL语句如下:

CREATE VIEW PH_Student

    AS

    SELELCT SNo,SName,SAge

    FROM StudentInfo

    WHERE Sdept='物理'

注意,数据库系统执行CREATE VIEW 语句的结果只是吧视图的定义存入数据字典中,但此时不执行其中的SELECT语句。只有在对视图查询时,才按视图的定义从普通表中将数据查出。

假设现在要建立化学系学生的视图,并要求进行修改和插入操作时仍需要保证该视图只有化学系的学生,则可以使用带WITH CHECK OPTION的SQL语句。

CREATE VIEW CH_Student

    AS

    SELECT SNo,SName,SAge

    FROM StudentInfo

    WHERE Sdept='化学'

    WITH CHECK OPTION

以上的语句建立从StudentInfo上定义的化学系学生视图。它与前面物理系的视图最大不同就在于,这个视图可以通过Where从句来保证视图的增删改操作都是针对化学系学生的,这也是WITH CHECK OPTION的最大作用。

在建立视图时,若这个视图是从单个普通表中导出的,并且只是去掉了普通表的某些行和某些列,但保留俩主键,这时它被称为行列子集视图。如刚才建立的CH_Student视图就是一个行列子集视图。这一类视图在更新时具有某些优良的性质。

要建立物理系选修了1号课程的学生的视图,则可以使用SQL语句定义如下:

CREATE VIEW PH_C1(SNo,SName,STotal)

    AS

    SELECT SNo,SName,STotal

    FROM Student,SC WHRER SDept='物理' AND

    Student.SNo=SC.SNo AND SC.CNo='1'

如果要需要在刚才定义的PH_C1视图的接触上建立物理系选修俩1号课程且成绩在90分以上的学生的视图,则可以使用SQL语句定义如下:

CREATE VIEW PH_C2

    AS

    SELECT SNo,SName,SGrade

    FROM PH_C1

    WHERE SGrade>=90

在实际应用数据库时,为了减少数据库中的冗余数据,定义普通表时只会存放一些基本数据,而由基本数据经过各种计算派生的数据一般四不存储的。但是由于视图中的数据并不实际存储,所以定义视图时可以根据应用的需要,设置一些派生属性列。这些派生属性由于在普通表中并不实际存在也称它们为虚拟列。带虚拟列的视图也称为带表达式的视图。例如,定义一个反映学生出生年份的视图V1_S,其SQL语句如下:

CREATE VIEW V1_S(SNo,SName,SBirth)

    AS

    SELECT SNo,SName,1996-SAge

    FROM Student

当然还可以带由实用函数和GROUP BY 子句的查询来定义视图,这种视图称为分组视图。比如,将学生的学号及他们的平均成绩定义为一个视图,其SQL语句如下:

CREATE VIEW S_G(SNo,Gavg)

    AS SELECT SNo,AVG(Grade)

    FROM SC

    GROUP BY SNo

2、删除视图

删除视图与删除表的语法类似,其语法如下:

DROP VIEW <视图>

视图删除以后视图的定义将从数据字典中删除。但由该视图导出的其他视图定义仍在数据字典中,但已经失效,不能使用,应该将它们一一删除。如要删除前面定义的视图PH_Student,可以使用如下的SQL语句。

DROP VIEW PH_Student

3、查询视图

视图定义后,就可以像对普通表一样对视图进行查询了。例如要在物理系学生的视图中找出年龄小于20岁的学生,可以使用如下SQL语句。

SELECT SNo,SAge

    FROM PH_Student

    WHERE SAge<20

数据库系统在执行对视图的查询时,首先进行有效性检查,即检查查询的表、视图等是否存在。如果存在,则从数据字典中取出视图的定义,把定义中的子查询和用户查询结合起来,转换成等价的对普通表的查询,然后再执行修正后的查询。这一转换过程称为“视图消解”。

上面的例子在经过数据库系统转换后的查询语句如下:

SELECT SNo,SAge

    FROM Student

    WHERE Sdept='PH' AND Sage<20

在一般情况下,视图查询的转换是直截了当的,但是有些情况下,这种转换不能直接进行,导致查询时出现问题。如在前面定义的关于学生成绩的视图S_G查询平均成绩在60分以上的学生学号和平均成绩,其SQL语句如下:

SELECT * FROM S_G

    WHERE Gavg>=60

根据前面S_G视图的的SQL语句:

SELECT SNo,AVG(Grade)

    FROM SC

    GROUP BY SNo

在视图消解时,DBMS会将上面查询语句与子查询结合,形成下列查询语句。

SELECT SNo,AVG(Grade)

    FROM SC

    WHERE AVG(Grade)>=60

    GROUP BY SNo

但是,SQL中规定WHERE子句中不能用实用函数作为查询条件表达式,因此执行此修正后的查询将会出现语法错误。目前多数关系数据库系统对行列子集视图的查询均能进行正确转换。但对非行列子集的查询就不一定能做转换了,因此这类查询应该直接对普通表进行。

4、更新视图

更新视图是指通过视图来插入(INSERT)、删除(DELETE)和修改(UPDATE)数据。由于视图是不实际存储数据的虚表,因此对视图的更新最终要转换称对普通表的更新。

为了防止用户通过视图对数据进行更新、删除、修改时,有意无意地对不属于视图范围内的普通表数据进行操作,可在定义视图时加上WITH CHECK OPTION子句。这样在视图上增、删改数据时,DBMS会检查视图定义中的条件,若不满足条件,则拒绝执行该操作。假设要将前面定义的物理系学生视图PH_Student中学号为04001的学生姓名改为“王立”,可以使用如下的SQL语句对视图进行更新:

UPDATE PH_Student

    SET SName="王立"

    WHERE SNo='04001'

DBMS进过”视图消解“这个步骤的转换后,对应的单表更新语句如下:

UPDATE Student

    SET SName='王立'

    WHERE SNo='04001' AND Sdept='PH'

对于视图的删除操作,DBMS也会使用同样的方法。假设要删除物理系学生视图PH_Student中学号为050193的记录,使用的SQL语句如下:

DELETE

    FROM PH_Student

    WHERE SNo='050193'

经DBMS转换为对单表的删除操作如下:

DELETE

    FROM Student

    WHERE SNo='050193' AND Sdept='PH'

但是,经研究发现,数据库中并不是所有的视图都是可更新的,因为有些视图的更新不能有意义地转换称对相应普通表的更新。例如前面定义的视图S_G是由”学号“和”平均成绩“两个属性列组成的,其中平均成绩一项是有Student表中对元组分组后计算平均值得来的。要把视图S_G中学号为050013的学生的平均成绩改为60分,使用的SQL语句如下:

UPDATE S_G

    SET Gavg=60

    WHERE SNo='050013'

对视图的更新是无法转换成对普通表的更新的。因为系统无法修改各科成绩,以使平均成绩为60。所以S_G视图是不可更新的。一般地,行列子集视图是可更新的,这是这类视图的重要特点。

5、视图的作用

视图机制使数据库管理员可以将注意力集中在所关心的数据上。如果这些数据不是直接来自普通表,则可以通过定义视图使数据库看起来结果简单、清晰,并且可以简化数据查询操作。例如那些定义了若干张表连接的视图,就将表与表之间的连接操作对使用者隐藏起来了。换句话说,用户可所做的只是对一个虚表的简单查询,而这个虚表是怎么得来的,用户无需了解。

视图使用户能以多种角度看待同一数据,并且对重构数据库提供了一定程度的逻辑独立性。在一定程度上也能够对机密数据提供安全保护。

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息