文章目录
- 一、什么是视图
- 二、视图语法
- 三、学生成绩系统视图案例
-
- [1. 多表关联查询封装为视图](#1. 多表关联查询封装为视图)
- [2. 聚合统计视图](#2. 聚合统计视图)
- [3. 视图与基表联动更新](#3. 视图与基表联动更新)
-
- [① 修改基表 → 视图自动更新](#① 修改基表 → 视图自动更新)
- [② 视图更新 → 基表同步](#② 视图更新 → 基表同步)
- 四、不可更新的视图
- 五、视图的优点
一、什么是视图
视图是基于一张或多张基表/其他视图的查询结果集。特点:
- 虚拟性:不占用物理存储空间,数据实时来自基表,基表变视图同步变;
- 逻辑封装:把复杂多表关联、聚合查询存为一个视图,调用时像查普通表一样简单;
- 权限隔离:可隐藏敏感字段,控制用户可访问的数据范围;
- 双向联动:修改基表影响视图,符合条件的视图修改也会同步到基表。
二、视图语法
sql
-- 1. 创建视图
create view 视图名 [(列名列表)] as 查询语句;
-- 2. 查询视图(和普通表完全一样)
select * from 视图名 [where 条件];
-- 3. 删除视图
drop view 视图名;
三、学生成绩系统视图案例
用 student(学生)、class(班级)、course(课程)、score(成绩)四张表演示。
1. 多表关联查询封装为视图
原始多表查询要写大量关联条件,复用性极差
sql
-- 多表查询
select
s.id, s.name, s.sno, s.age, s.gender, s.enroll_date,
c.id class_id, c.name class_name,
co.id course_id, co.name course_name,
sc.id score_id, sc.score
from student s, class c, course co, score sc
where s.class_id = c.id
and sc.student_id = s.id
and sc.course_id = co.id
order by s.id;
方式1:创建视图并给列起别名
sql
create view v_student_score as
select
s.id, s.name, s.sno, s.age, s.gender, s.enroll_date,
c.id as class_id, c.name as class_name,
co.id as course_id, co.name as course_name,
sc.id as score_id, sc.score
from student s, class c, course co, score sc
where s.class_id = c.id
and sc.student_id = s.id
and sc.course_id = co.id
order by s.id;
方式2:创建时直接指定列名
sql
create view v_student_score_v1
(id, name, sno, age, gender, enroll_date,
class_id, class_name,
course_id, course_name,
score_id, score)
as
select
s.id, s.name, s.sno, s.age, s.gender, s.enroll_date,
c.id, c.name, co.id, co.name, sc.id, sc.score
from student s, class c, course co, score sc
where s.class_id = c.id
and sc.student_id = s.id
and sc.course_id = co.id;
一键查询视图
sql
select * from v_student_score;
select * from v_student_score_v1;
2. 聚合统计视图
隐藏学号、各科成绩,只展示学生姓名与总分。
sql
-- 创建总分视图
create view v_student_total_points as
select
s.id, s.name, sum(sc.score) total
from student s, score sc
where s.id = sc.student_id
group by s.id
order by s.id;
-- 查询视图
select * from v_student_total_points;
3. 视图与基表联动更新
① 修改基表 → 视图自动更新
sql
update score set score = 99 where student_id = 1 and course_id = 1;
select * from v_student_score;
② 视图更新 → 基表同步
sql
-- 含 order by,更新失败
update v_student_score set score = 99 where score_id = 3;
-- 简单视图可更新
update v_student_score_v1 set score = 99 where score_id = 3;
select * from score where student_id = 1 and course_id = 5;
四、不可更新的视图
以下视图不能 update/insert/delete:
- 使用聚合函数(sum/count/avg/min/max)
- 使用 distinct / group by / having
- 使用 union / union all
- 查询列表包含子查询
- 引用不可更新视图
五、视图的优点
- 简化查询:封装复杂多表查询,一行调用
- 数据安全:隐藏敏感字段,控制访问范围
- 逻辑解耦:基表结构变化只需改视图,不影响应用