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 保证通过视图做的增删改不会超出视图定义的范围。