5.1 视图与索引

5.1.1 视图

目的:

定义:

例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_number
FROM 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_2009
WHERE building = 'Watson';
/*等价于*/
CREATE VIEW physics_fall_2009_watson AS
(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,building
FROM 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),这种方法显然是不可行的。
*/

视图可更新的要求:

更新操作的检查:

例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 索引

定义:

例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);

(完)

05-05 20:37