3. 视图:虚拟的专用窗口

视图(View)是一张虚拟表,本身不存数据,数据来自定义它的 SELECT 查询,使用时动态生成。

为什么用视图:① 只暴露表的某一部分;② 给不同用户定制不同查询视图(敏感字段不展示);③ 简化复杂查询。

sql
-- 创建视图:学生姓名 + 课程名 + 成绩
CREATE VIEW myv1 AS
SELECT s.Sname, c.Cname, sc.score
FROM student s
JOIN sc ON s.Sno = sc.Sno
JOIN course c ON sc.Cno = c.Cno;

-- 使用视图(像查表一样)
SELECT * FROM myv1 WHERE Sname LIKE '%风%';

管理:

sql
ALTER VIEW myv1 AS SELECT ... ;   -- 修改
DROP VIEW IF EXISTS myv1;       -- 删除
SHOW CREATE VIEW myv1;            -- 查看定义
💡 视图多用于"方便查询",一般不建议通过它改数据。当视图定义含 DISTINCT、聚合、GROUP BY、JOIN、子查询时,MySQL 不允许对其 INSERT/UPDATE/DELETE。

📝 本节例题

以下例题均基于 教学实例 库(student / course / sc / teacher / grades / dept / emp),开始前先执行 USE 教学实例;。建议先自己写一遍,再展开答案对照。

例 1
创建视图 v_class01,只显示 01 班学生的学号、姓名、性别、年龄,并查询结果。
查看参考答案(可复制)
sql
CREATE OR REPLACE VIEW v_class01 AS
SELECT Sno, Sname, Ssex, sage FROM student WHERE class = '01';

SELECT * FROM v_class01;
💡 视图不存数据,只存一条 SELECT 语句,查询时实时跑。
例 2
创建视图 v_score_detail,把学生、课程、成绩、教师四张表连起来,做成一张“成绩单”。
查看参考答案(可复制)
sql
CREATE OR REPLACE VIEW v_score_detail AS
SELECT s.Sname 姓名, c.Cname 课程, sc.score 成绩, t.Tname 授课教师
FROM sc
JOIN student s ON sc.Sno = s.Sno
JOIN course  c ON sc.Cno = c.Cno
LEFT JOIN teacher t ON c.Tno = t.Tno;

SELECT * FROM v_score_detail LIMIT 10;
💡 把复杂的多表连接封进视图,以后查询只要 SELECT * FROM 视图 即可。
例 3
创建带 WITH CHECK OPTION 的视图 v_class01_check(只能操作 01 班数据),试着通过它插入一名 03 班学生,观察报错。
查看参考答案(可复制)
sql
CREATE OR REPLACE VIEW v_class01_check AS
SELECT Sno, Sname, class FROM student WHERE class = '01'
WITH CHECK OPTION;

INSERT INTO v_class01_check VALUES('099', '测试', '03');   -- 报 1369 错误,被拦截
INSERT INTO v_class01_check VALUES('099', '测试', '01');   -- 正常插入
💡 WITH CHECK OPTION 保证通过视图做的增删改不会超出视图定义的范围。