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);
(完)