<>5.1 视图与索引

<>5.1.1 视图

目的:

* 在某些情况下,让所有用户看到整个逻辑模型是不合适的 。
* 考虑一个职员需要知道教师的标识、姓名和所在系名,但是没有权限看到教师的工资值。
* 视图就提供了这种机制:向用户隐藏特定的数据。
* SQL允许通过查询来定义“虚关系”,它在概念上包含查询的结果, 但并不预先计算并存储。像这种作为虚关系对用户可见的关系称为视图(view)
定义:

* 命令格式为:CREATE VIEW v AS < query expression >
* < query expression >可以是任何合法的查询表达式 。
* v 表示视图名。
* 对应地,删除视图,使用命令:DROP VIEW v
例1,考虑需要访问 instructor 关系中除 salary 之外的所有数据:
CREATE VIEW faculty AS SELECT ID,name,dept_name FROM instructor
例2,列出Physics系在2009年秋季学期开设的所有课程,以及每个课程在哪栋建筑的哪个房间授课的信息:
CREATE VIEW physics_fall_2009 AS SELECT course.course_id,sec_id,building,
room_numberFROM course,section WHERE course.course_id = section.course_id AND
course.dept_name='Physics' AND section.semester='Fall' AND section.year='2009';
例3,列出每个系中所有教师的工资总和:
/* * 视图的属性名也可以按下述方式显示指定 */ CREATE VIEW departments_total_salary(dept_name,
total_salary) AS SELECT dept_name,SUM(salary) FROM instructor GROUP BY dept_name
; /* * 当我们定义一个视图时,数据库系统存储视图定义本身, * 而不存储定义该视图的查询表达式的执行结果 */
例4,使用视图physics_fall_2009,找到所有于2009年秋季学期在Watson 大楼开设的Physics课程 :
/* * 一旦定义了一个视图,就可以用视图名指代该视图生成的虚关系。 * 由于数据库只存储视图定义本身,那么当视图关系出现在查询中时, *
它就会被已存储的查询表达式代替。 */ SELECT course_id,room_number FROM physics_fall_2009 WHERE
building= 'Watson';
例5,定义视图physics_fall_2009_Watson,列出于2009年秋季学期在 Watson大楼开设的所有Physics课程的标识和教室号
CREATE VIEW physics_fall_2009_watson AS SELECT course_id,room_number FROM
physics_fall_2009WHERE building = 'Watson'; /*等价于*/ CREATE VIEW
physics_fall_2009_watsonAS (SELECT course_id,room_number FROM (SELECT course.
course_id,building,room_number FROM course,section WHERE course.course_id=
section.course_id AND course.dept_name='Physics' AND section.semester='Fall' AND
section.year='2009') WHERE building = 'Watson';
视图更新:
例1,假设我们向视图 faculty 插入一条新元组:
INSERT INTO faculty VALUES('30765','Green','Music'); /* *
但这个插入必须表示为对instructor关系的插入,即必须给出salary的值。 * 存在两种合理的解决方法: * 1.
拒绝插入,并向用户返回一个错误信息。 * 2. 向instructor关系插入元组(‘30765’,‘Green’,‘Music’, null)。 */
例2,通过视图修改数据库的另一类问题发生在这样的视图:
/*这个视图列出了大学里每个教师的ID、name和建筑名*/ CREATE VIEW instructor_info AS SELECT ID.name,
buildingFROM instructor,department WHERE instructor.dept_name=departmenty.
dept_name; /*若执行以下视图插入: */ INSERT INTO instructor_info VALUES ('69987','White',
'Taylor'); /* * 假设没有标识为69987的教师,也没有位于Taylor大楼的系, * 唯一的解决办法是: * 1.
向instructor中插入元组('69987','White',null,null) * 2.
向department中插入元组(null,'Taylor',null),这种方法显然是不可行的。 */
视图可更新的要求:

* from子句中只有一个数据库关系。
* select子句中只包含关系的属性名,不包含任何表达式、聚集或distinct声明。
* 任何没有出现在select子句中的属性可以取空值;即这些属性上没有not null约束,也不构成主码的一部分 。
* 查询中不含有group by或having子句 。
更新操作的检查:

* WITH CHECK OPTION
例1,
CREATE VIEW history_instructors AS SELECT * FROM instructor WHERE dept_name=
'History'; INSERT INTO history_instructors VALUE('25566','Brown','Biology',100
000); /*上述插入的元组不符合视图中WHERE子句的要求,但SQL默认允许执行上述操作*/ /*可以通过在视图定义的末尾加上with check
option子句来定义视图,对更新操作进行检查*/
物化视图:

* 特定数据库系统允许存储视图关系。
* 物化视图维护:保持物化视图一直在最新状态的过程。
视图维护的三种方式:

* 当构成视图定义的任何关系被更新时,进行视图维护。
* 当视图被访问时,才进行视图维护。
* 周期性地进行视图维护(在这种情况下,访问的数据可能是过时的)。
<>5.1.2 索引

定义:

* 用create index命令,为关系中的某些属性创建索引,它允许数据库系统高效地找到关系中那些在索引属性上取给定值的元组,而不用扫描关系中的所有元组。
* 用drop index命令,删除一个索引。
例1,为instructor表的ID属性创建名为ins_index的索引:
CREATE INDEX ins_index ON instructor(ID);
例2,为instructor表的ID和name属性创建名为ins_ID_name_index的索引:
CREATE INDEX ins_ID_name_index ON instructor(ID,name);
例3,为关系中的某些属性创建唯一索引:
CREATE UNIQUE INDEX uni_stu_index on student(ID);
(完)

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:637538335
关注微信