> 文章列表 > 视图的使用

视图的使用

视图的使用

 为什么引入视图(Views)

如果您读过其他类似的书,可能会看到这些书在介绍视图时列举了许多引入视图的原因。其中认为最重要的原因是维护数据的独立性。那么什么是数据的独立性呢?

早期信息系统的设计与开发多采用模块驱动方式,即设计与开发者首先根据用户的需求建立功能模块(过程和函数),再由这些模块来决定数据结构和存储。以这种方法设计和开发的信息系统在绝大多数情况下是很难维护的。因为在当今这个经济快速发展的社会中,商业环境和市场在不断变化,用户的需求也在不断变化。当然带来的后果也就可想而知了,即相应的模块也要变,随之而来的是数据结构和数据存储都要变。这可以说是牵一发而动全身。在现代化的社会中,变化是不可避免的。也许当今世界上惟一不变的是"变"这个字。

面对变化是不可避免的这一事实时,设计与开发者如何才能设计和开发出相对稳定的信息系统呢?即信息系统的某一局部变化时,不需要修改相应的数据结构和数据存储。研究表明:虽然随着用户的需求的变化,模块的变化几乎是不可避免的,但是信息系统中的数据却几乎是不变的(数据的排列可能会变化)。这样的发现就导致了一种与模块驱动方式完全不同的信息系统设计与开发方法的诞生,这种信息系统设计与开发方法就叫做数据驱动法。

采用数据驱动方式来设计和开发信息系统时,设计和开发者在前期可以完全不考虑系统的硬件、软件(包括操作系统和数据库管理系统)和功能模块(因此也就不用考虑程序设计语言)。设计和开发者在前期要收集信息系统所需的全部数据、化分实体(表)以及定义表与表之间的关系。之后用规范化(Normalization)决定哪些列应该放在哪个表中,最后产生一个基本上只包括了三范式表的实体关系图。当然这是一个漫长和需要多次反复的过程。

许多行家认为一旦完成了这一步,信息系统的设计已完成了一半或以上。因为接下去的工作已经很轻松了,只要将这个图中的实体转换成关系数据库的表,将实体与实体之间的关系转换成关系数据库的约束即可。之后只要将数据装入相应的表中就可以利用SQL语句使用这一信息系统了,只是用户界面不太友好而已。

下面我们用图14.1,一个简化的信息系统设计来说明采用数据驱动方式来设计和开发信息系统给信息系统维护带来的好处。

 

假设在图14.1中的表包含了信息系统所需的全部数据,而且每一个表都是三范式。很显然某一模块所需的数据可能分别存在于多个表中(例如订单)。这时就可以为这一模块创建一个视图,开发人员只能看到和操作通过这一视图所看到的数据,虽然这些数据是来自不同的表,但对于开发人员来说这些数据就好像来自一个表一样。当模块的功能变化需要不同的数据时,需要改变的只是相应的视图而不需要改变真正的表。这样信息系统的维护就简单多了。

从前面的讨论可以看出使用视图有以下的好处:

■ 可以把复杂的SQL语句简单化。您可以看出例14-2中的SQL语句是很复杂的。

在该语句中包含了分组函数(Group Functions),还包含了GROUPBY子句和两个表的连接,并为查询中的每一列取了别名。但用户却可使用像例14-4那样最简单的查询语句从视图average中提取同样的信息。

可以限制数据库的访问。用户通过视图 average只能访问“部门”、“平均工资”、“平均佣金”和“员工数”这4列。

可以使数据独立于应用程序(数据独立性)。见14.1节的讨论。

可以使相同的数据以不同的形式出现在不同的视图中。例如您可以为每一个部门创建一个只包含该部门员工信息的视图,这样当用户使用视图来访问数据时就只能看到他/她所在部门员工的信息。

如何创建视图(Views)

实际上您已经在14.2中创建了一个视图,下面我们给出创建视图比较完整的格式。

CREATE【OR REPLACE】【FORCE|NOFORCE】VIEW 视图名

【(别名】,别名】…)】AS 子查询语句

【WITH CHECK OPTION 【CONSTRAINT约束名】】

[WITH READ ONLY]其中每个选项的含义如下:

OR REPLACE:如果所创建的视图已存在,Oracle系统会重建这个视图。在这里值得注意的一个问题是:可能系统中已有一个同名的视图而且它是一个有用的视图。此时您如果使用OR REPLACE来创建视图就会把系统中有用的视图覆盖掉。因此为了防止这种灾难的发生,您应该在创建视图之前使用SQL*PLUS的DESC 看看这个视图是否已存在。

FORCE:不管所引用的表是否存在,Oracle系统都会创建这个视图。

NOFORCE:只有当所引用的表都存在时,Oracle系统才会创建这个视图(这是■

ORACL系统的默认方式)。视图名:所要创建的视图的名字。

别名:为视图所产生的列定义的列名(别名的个数一定要与视图所产生的列数相等)。

■子查询语句:一个完整的查询语句(您也可以在该语句定义别名)。

WITH CHECK OPTION:所插入或修改的数据行必须满足视图所定义的约束条件。

约束名:WITH CHECK OPTION 中的约束名。

WITHREADONLY:保证在该视图上不能进行任何DML操作。

需要注意的是:在子查询语句中不能包含ORDER BY子句。这可能是因为视图给出的数据并不是最终的结果。如果您想让您的查询结果按某一种有序的方式显示,您可以在查询视图时加入ORDER BY子句。

SQL> CREATE OR REPLACE VIEW acct

2.("名字","工资","职位","雇用日期")

3 AS

4 SELECT ename,sal,job,hiredate

5 FROM emp

6 WHERE deptno = 10;

如何修改视图(Views)

例14-8

SQL> CREATE OR REPLACE VIEW acct

2 ("名字","工资","职位","雇用日期","部门","地点")

3 AS

4 SELECT ename,sal,job,hiredate,dname,loc

5 FROM emp, dept

6 WHERE emp.deptno = dept.deptno

7 AND emp.deptno = 10;

Oracle系统如何管理视图(Views)

当您使用CREATEVIEW语句成功地创建了视图后,这个视图就被存在了Oracle数据字典中。那么一个用户怎样才能知道他/她的账号下有多少个视图,以及这些视图的定义呢?您可以通过查询数据字典user_views来得到这方面的信息(例14-11)。

例14-11

SQL> SELECT view_name,text_length,text

2 FROM user_views;

Oracle系统的执行步骤如下:

(1)从数据字典中取出视图的定义,即查询语句。(2)检查该视图所引用的表的权限。(3)执行视图所定义的查询语句。

从以上Oracle系统的执行步骤可以看出,在使用视图访问数据库时,至少要两次访问硬盘(第一次访问数据字典,第二次访问表中的数据)。因此虽然使用视图给我们带来了诸多的方便,但是它却可能带来一些效率方面的问题。因为磁盘的I/O操作对系统效率的冲击是非常大的。