一、视图的基本概念
视图是从基本表中导出的虚表,数据库中仅存储视图的定义语句,并不存储视图对应的实际数据,视图展示的数据仍存放在原始基本表中。
- 视图的查询结果会随基本表的数据变化而实时变化,因为每次查询视图,本质都是执行其定义中的子查询去基本表中获取最新数据。
- 视图的核心作用:简化复杂查询、实现数据访问控制、屏蔽表结构变化对应用的影响。
二、视图的创建(CREATE VIEW)
1. 基本语法
CREATE VIEW <视图名> [(列名列表)] AS <子查询> [WITH CHECK OPTION];
总结:仅基于单张基本表、无聚合、无派生列、无分组的视图,才能正常执行增删改操作。
五、视图的删除(DROP VIEW)
1. 基本语法
示例:
示例:
⚠️ 注意事项
- 列名列表:可选,若子查询中包含派生列、聚合列,或多表连接有重名列时,必须显式指定;
- WITH CHECK OPTION:关键约束,对视图执行增删改操作时,数据库会自动校验操作的行是否满足子查询的条件,保证操作后的数据仍能被视图查询到。
- 2. 常见创建场景
-
(1)单表创建视图(带 / 不带 WITH CHECK OPTION)
场景:创建信息系学生的视图,仅展示学号、姓名、年龄
— 基础版:无校验,增删改可能导致数据脱离视图范围
CREATE VIEW IS_Student
AS SELECT Sno, Sname, Sage FROM Student WHERE Sdept = 'IS';— 带校验版:增删改时强制校验Sdept='IS'
CREATE VIEW IS_Student
AS SELECT Sno, Sname, Sage FROM Student WHERE Sdept = 'IS' WITH CHECK OPTION;(2)多表连接创建视图
场景:创建信息系选修 1 号课程的学生视图,包含学号、姓名、成绩
— 方式1:多表逗号连接
CREATE VIEW IS_S1 (Sno, Sname, Grade)
AS SELECT Student.Sno, Sname, Grade
FROM Student, SC
WHERE Student.Sno = SC.Sno AND SC.Cno = '1' AND Sdept = 'IS';— 方式2:JOIN显式连接(推荐,可读性更高)
CREATE VIEW IS_S1 (Sno, Sname, Grade)
AS SELECT Student.Sno, Sname, Grade
FROM Student JOIN SC ON Student.Sno = SC.Sno
WHERE SC.Cno = '1' AND Sdept = 'IS';(3)基于视图创建视图(视图嵌套)
场景:创建信息系选修 1 号课程且成绩 90 分以上的学生视图(基于已创建的 IS_S1 视图)
CREATE VIEW IS_S2
AS SELECT Sno, Sname, Grade FROM IS_S1 WHERE Grade >= 90;(4)包含派生属性列的视图
场景:创建学生视图,包含学号、姓名、出生年份(出生年份 = 2014 – 年龄,派生列)
CREATE VIEW BI_S (Sno, Sname, Sbirth)
AS SELECT Sno, Sname, 2014 – Sage FROM Student;(5)分组视图(带聚合函数 + GROUP BY)
场景:创建学生学号及对应平均成绩的视图(聚合函数 AVG+GROUP BY)
CREATE VIEW S_G (Sno, Gavg)
AS SELECT Sno, AVG(Grade) FROM SC GROUP BY Sno;(6)全列筛选创建视图
场景:创建 Student 表中所有女生的视图,显式指定列名
CREATE VIEW F_Student (F_sno, name, sex, age, dept)
AS SELECT * FROM Student WHERE sex = '女';三、视图的查询(SELECT)
查询视图的语法与查询基本表完全一致,数据库会自动将视图查询转换为对基本表的子查询执行。
1. 单视图简单查询
场景:在信息系学生视图中查询年龄小于 20 岁的学生
SELECT Sno, Sage FROM IS_Student WHERE Sage < 20;
— 数据库自动转换为对基本表的查询:
— SELECT Sno, Sage FROM Student WHERE Sdept = 'IS' AND Sage < 20;2. 视图与表连接查询
场景:查询选修 1 号课程的信息系学生(视图 IS_Student 与表 SC 连接)
SELECT IS_Student.Sno, Sname
FROM IS_Student JOIN SC ON IS_Student.Sno = SC.Sno
WHERE SC.Cno = '1';3. 分组视图的查询
场景:在平均成绩视图 S_G 中查询平均成绩 90 分以上的学生
— 分组视图已聚合,直接用WHERE,无需再GROUP BY/HAVING
SELECT Sno, Gavg FROM S_G WHERE Gavg >= 90;— 若直接查基本表,需用HAVING(WHERE不能跟聚合函数)
SELECT Sno, AVG(Grade)
FROM SC
GROUP BY Sno
HAVING AVG(Grade) >= 90;核心区别:WHERE 过滤原始行,不能跟聚合函数;HAVING 过滤分组后的聚合行,可跟聚合函数。
四、视图的更新(INSERT/UPDATE/DELETE)
视图是虚表,对视图的增删改操作,数据库会自动转换为对基本表的对应操作,语法与操作基本表一致。
1. 视图的修改(UPDATE)
场景:将信息系学生视图 IS_Student 中学号 201215122 的姓名改为刘辰
— 操作视图
UPDATE IS_Student SET Sname = '刘辰' WHERE Sno = '201215122';
— 数据库自动转换为操作基本表
UPDATE Student SET Sname = '刘辰' WHERE Sno = '201215122' AND Sdept = 'IS';2. 视图的插入(INSERT)
场景:向信息系学生视图 IS_Student 插入一条学生记录
— 操作视图
INSERT INTO IS_Student VALUES ('201215129', '赵新', 20);
— 数据库自动转换为操作基本表(补充Sdept='IS',符合视图条件)
INSERT INTO Student (Sno, Sname, Sage, Sdept) VALUES ('201215129', '赵新', 20, 'IS');3. 视图的删除(DELETE)
场景:从信息系学生视图 IS_Student 中删除学号 201215129 的记录
— 操作视图
DELETE FROM IS_Student WHERE Sno = '201215129';
— 数据库自动转换为操作基本表
DELETE FROM Student WHERE Sno = '201215129' AND Sdept = 'IS';4. 视图的更新限制
并非所有视图都支持更新,以下场景的视图不可更新(插入 / 修改),部分可删除:
- 视图由两个及以上基本表导出;
- 视图字段来自字段表达式 / 常数(如派生列 2014-Sage),不可插入 / 修改,可删除;
- 视图字段来自聚合函数(如 AVG、SUM、COUNT);
- 视图定义中包含GROUP BY子句、DISTINCT短语;
- 视图定义中有嵌套查询,且内层查询的 FROM 子句涉及导出该视图的基本表;
总结:仅基于单张基本表、无聚合、无派生列、无分组的视图,才能正常执行增删改操作。
五、视图的删除(DROP VIEW)
1. 基本语法
— 普通删除:仅删除当前视图,若有视图基于它创建则报错
DROP VIEW <视图名>;
— 级联删除:删除当前视图及所有由它导出的视图(部分数据库语法:DROP VIEW <视图名> CASCADE;)
DROP VIEW <视图名> CASCADE;2. 删除注意事项
- 基本表被删除后,由该基本表导出的所有视图无法使用,但视图的定义仍会保存在数据库字典中,需手动执行 DROP VIEW 删除;
- 若视图上还导出了其他视图,直接普通删除该视图会被数据库拒绝执行,需使用级联删除。
— IS_S2基于IS_S1创建,普通删除IS_S1会报错
DROP VIEW IS_S1; — 拒绝执行
— 级联删除IS_S1及由它导出的IS_S2
DROP VIEW IS_S1 CASCADE; — 成功执行
— 删除单个无依赖的视图
DROP VIEW BI_S; — 成功执行六、视图的核心使用总结
🌟 优点
- 简化查询:将复杂的多表连接、聚合查询封装为视图,后续查询直接调用视图,减少代码冗余;
- 数据安全:仅向用户开放视图的访问权限,屏蔽基本表中敏感字段(如密码、身份证),实现精细化的访问控制;
- 视图仅存储定义,不存储数据,频繁查询复杂视图可能影响性能(每次查询都要执行子查询);
- WITH CHECK OPTION 是保障视图数据一致性的关键,涉及视图增删改时建议添加;
- 避免多层视图嵌套,过多嵌套会导致查询性能下降,且不易排查问题;
- 分组视图、聚合视图仅用于查询,不可更新,需明确视图的使用场景。
- 解耦表结构:若基本表的结构发生变化(如新增列、修改列名),只需修改视图的定义,无需修改应用程序的查询语句,降低维护成本。



