【MySQL】视图:简化查询、保障安全的虚拟表

文章目录

一、什么是视图

视图是基于一张或多张基表/其他视图的查询结果集。特点:

  • 虚拟性:不占用物理存储空间,数据实时来自基表,基表变视图同步变;
  • 逻辑封装:把复杂多表关联、聚合查询存为一个视图,调用时像查普通表一样简单;
  • 权限隔离:可隐藏敏感字段,控制用户可访问的数据范围;
  • 双向联动:修改基表影响视图,符合条件的视图修改也会同步到基表。

二、视图语法

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

  1. 使用聚合函数(sum/count/avg/min/max)
  2. 使用 distinct / group by / having
  3. 使用 union / union all
  4. 查询列表包含子查询
  5. 引用不可更新视图

五、视图的优点

  1. 简化查询:封装复杂多表查询,一行调用
  2. 数据安全:隐藏敏感字段,控制访问范围
  3. 逻辑解耦:基表结构变化只需改视图,不影响应用
相关推荐
_ku_ku_1 天前
数据库系统原理 · 事务管理与恢复 · 自学总结
数据库·oracle
lifewange1 天前
Redis 集合(Set)运算完全指南
数据库·chrome·redis
TDengine (老段)1 天前
TDengine RAFT共识协议 — 选举、日志复制、快照与仲裁
android·大数据·数据库·物联网·架构·时序数据库·tdengine
Full Stack Developme1 天前
Spring Boot 事务管理完整教程
java·数据库·spring boot
m0_702036531 天前
mysql如何通过索引减少行锁范围_mysql索引与加锁逻辑
jvm·数据库·python
qxwlcsdn1 天前
如何用 IndexedDB 存储从 API 获取的超大列表并实现二级索引
jvm·数据库·python
phltxy1 天前
Redis 主从复制
java·数据库·redis
2301_809244531 天前
C#怎么使用协变和逆变 C#泛型中的in和out关键字协变逆变是什么意思怎么用【语法】
jvm·数据库·python
知识汲取者1 天前
巨量引擎营销 API 完整文档
开发语言·数据库·python
j7~1 天前
【MYSQL】在Centos7和ubuntu22.04环境下安装
数据库·c++·mysql·ubuntu·centos