数据库---Day9 视图(附完整数据库脚本+练习题)

本系列可作为数据库学习系列的笔记,文中提到的一些练习的代码,小编会将代码复制下来,大家复制下来就可以练习了,方便大家学习。

点赞关注不迷路!您的点赞、关注和收藏是对小编最大的支持和鼓励!

系列文章目录

JAVA初阶---------已更完

JAVA数据结构---------已更完

数据库---Day 1 数据库基础

数据库---Day2 数据库操作

数据库---Day3 数据类型

数据库---Day4 数据表的操作

数据库---Day5 数据表的增删改查

数据库---Day6 数据库约束

数据库---Day7 数据表设计

数据库---Day8 多表联合查询

数据库---Day9 视图


目录

目录

系列文章目录

目录

前言

一、什么是视图(View)

二、为什么要使用视图

[1. 简化复杂SQL](#1. 简化复杂SQL)

[2. 提高安全性](#2. 提高安全性)

[3. 提高可维护性](#3. 提高可维护性)

[4. 提高可读性](#4. 提高可读性)

三、实验环境准备

[3.1 创建数据库](#3.1 创建数据库)

[3.2 创建表结构](#3.2 创建表结构)

班级表

学生表

课程表

成绩表

用户表

[3.3 插入测试数据](#3.3 插入测试数据)

班级数据

学生数据

课程数据

成绩数据

用户数据

四、不使用视图进行查询

五、创建第一个视图

六、查询视图

条件查询

排序查询

七、字段重命名(Alias)

八、使用视图隐藏敏感字段

这是不是视图最常用的手段?

[绝对是!而且是视图 #1 最经典用途!](#1 最经典用途!)

九、统计总分视图

十、视图与真实表的关系

十一、通过视图修改数据

十二、哪些视图不能更新

使用聚合函数

[使用 GROUP BY](#使用 GROUP BY)

[使用 DISTINCT](#使用 DISTINCT)

[使用 UNION](#使用 UNION)

使用子查询

十三、删除视图

十四、企业项目中的真实应用

ERP系统

OA系统

BI报表

十五、课后练习

练习1

练习2

练习3

练习4

练习5

十六、总结

总结


前言

在学习 MySQL 的过程中,很多同学都会接触到一个重要对象------视图(View)

刚开始学习时,大多数人都会认为:

视图不就是把 SQL 保存起来吗?

事实上,视图远不止这么简单。

在实际企业项目中:

  • ERP系统

  • OA办公系统

  • CRM客户管理系统

  • 电商后台

  • BI数据报表系统

都会大量使用视图。

视图不仅能够简化复杂查询,还能实现:

  • 数据权限控制

  • 隐藏敏感字段

  • 降低系统耦合度

  • 统一业务查询逻辑

本文将从零开始,通过完整案例带你掌握:

✅ 创建视图

✅ 查询视图

✅ 修改视图

✅ 删除视图

✅ 不可更新视图

✅ 企业项目中的真实应用

并提供完整数据库脚本和练习题,让初学者边学边练。

一、什么是视图(View)

官方定义:

视图(View)是基于一个或多个表查询结果构成的虚拟表。

特点:

  • 不存储数据

  • 存储查询逻辑

  • 查询时实时访问底层表

理解图:

复制代码
真实表
 ↓
SQL查询
 ↓
视图(View)
 ↓
用户访问

例如:

学生表:

id name
1 张三
2 李四

成绩表:

id student_id score
1 1 90
2 2 85

如果经常需要查询:

复制代码
学生姓名 + 成绩

可以创建视图:

sql 复制代码
CREATE VIEW v_student_score AS
SELECT
    s.name,
    sc.score
FROM student s
JOIN score sc
ON s.id=sc.student_id;

以后直接:

sql 复制代码
SELECT * FROM v_student_score;

即可获得结果。

也可以查看视图定义

sql 复制代码
SHOW CREATE VIEW v_student_score;

二、为什么要使用视图

1. 简化复杂SQL

例如查询:

  • 学生

  • 班级

  • 课程

  • 成绩

需要四表连接:

sql 复制代码
SELECT
s.name,
c.name,
co.name,
sc.score
FROM student s
JOIN class c
ON s.class_id=c.id
JOIN score sc
ON s.id=sc.student_id
JOIN course co
ON sc.course_id=co.id;
sql 复制代码
SELECT
s.name AS student_name,
c.name AS class_name,
co.name AS course_name,
sc.score
FROM student s, class c, course co, score sc
WHERE s.class_id=c.id AND s.id=sc.student_id AND sc.course_id=co.id;

SQL已经比较长。

如果以后变成:

复制代码
学生
班级
课程
教师
院系
成绩
学期

七八张表关联时,SQL会越来越复杂。

视图可以将这些逻辑封装起来。

2. 提高安全性

例如用户表:

sql 复制代码
CREATE TABLE user_account(
    id INT,
    username VARCHAR(50),
    password VARCHAR(100),
    phone VARCHAR(20)
);

普通员工不能看到密码。

创建视图:

sql 复制代码
CREATE VIEW v_user_public AS
SELECT
username,
phone
FROM user_account;

查询:

sql 复制代码
SELECT * FROM v_user_public;

即可隐藏密码字段。

3. 提高可维护性

如果底层表结构发生变化:

sql 复制代码
name

改为:

sql 复制代码
student_name

只需要修改视图即可。

应用程序无需修改。

4. 提高可读性

通过视图可以统一字段名称:

sql 复制代码
student_name
class_name
course_name

比多个:

sql 复制代码
name
name
name

更容易理解。

三、实验环境准备

3.1 创建数据库

sql 复制代码
DROP DATABASE IF EXISTS view_demo;

CREATE DATABASE view_demo
DEFAULT CHARACTER SET utf8mb4;

USE view_demo;

验证:

sql 复制代码
SHOW DATABASES;

3.2 创建表结构

班级表

sql 复制代码
CREATE TABLE class (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50) NOT NULL
);

学生表

sql 复制代码
CREATE TABLE student (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50) NOT NULL,
    sno VARCHAR(30) NOT NULL UNIQUE,
    age INT,
    gender VARCHAR(10),
    enroll_date DATE,
    class_id INT
);

课程表

sql 复制代码
CREATE TABLE course (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50) NOT NULL
);

成绩表

sql 复制代码
CREATE TABLE score (
    id INT PRIMARY KEY AUTO_INCREMENT,
    student_id INT,
    course_id INT,
    score DECIMAL(5,1)
);

用户表

sql 复制代码
CREATE TABLE user_account (
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50),
    password VARCHAR(100),
    phone VARCHAR(20),
    email VARCHAR(100)
);

查看所有表:

sql 复制代码
SHOW TABLES;

结果:

sql 复制代码
class
student
course
score
user_account

3.3 插入测试数据

班级数据

sql 复制代码
INSERT INTO class(name) VALUES
('Java开发一班'),
('Python开发班');

学生数据

sql 复制代码
INSERT INTO student
(name,sno,age,gender,enroll_date,class_id)
VALUES
('唐三藏','S001',30,'男','2024-09-01',1),
('孙悟空','S002',25,'男','2024-09-01',1),
('猪八戒','S003',28,'男','2024-09-01',2);

课程数据

sql 复制代码
INSERT INTO course(name)
VALUES
('Java'),
('MySQL'),
('Linux');

成绩数据

sql 复制代码
INSERT INTO score
(student_id,course_id,score)
VALUES
(1,1,95),
(1,2,88),
(1,3,90),

(2,1,99),
(2,2,92),
(2,3,85),

(3,1,75),
(3,2,80),
(3,3,45);

用户数据

sql 复制代码
INSERT INTO user_account
(username,password,phone,email)
VALUES
('admin','123456',
'13800000001',
'admin@test.com');

四、不使用视图进行查询

查询学生成绩:

sql 复制代码
SELECT
s.name,
c.name,
co.name,
sc.score
FROM student s
JOIN class c
ON s.class_id=c.id
JOIN score sc
ON s.id=sc.student_id
JOIN course co
ON sc.course_id=co.id;

结果:

学生 班级 课程 成绩
唐三藏 Java开发一班 Java 95
唐三藏 Java开发一班 MySQL 88
孙悟空 Java开发一班 Java 99

虽然结果正确,但 SQL 比较复杂。

五、创建第一个视图

sql 复制代码
CREATE VIEW v_student_score AS
SELECT
s.id AS student_id,
s.name AS student_name,
c.name AS class_name,
co.name AS course_name,
sc.score
FROM student s
JOIN class c
ON s.class_id=c.id
JOIN score sc
ON s.id=sc.student_id
JOIN course co
ON sc.course_id=co.id;

创建视图时,指定列名:

sql 复制代码
CREATE VIEW v_student_score (
    student_id,
    student_name,
    class_name,
    course_name,
    score
) AS
SELECT
    s.id,
    s.name,
    c.name,
    co.name,
    sc.score
FROM student s
JOIN class c
    ON s.class_id = c.id
JOIN score sc
    ON s.id = sc.student_id
JOIN course co
    ON sc.course_id = co.id;

查看数据库对象:

sql 复制代码
SHOW FULL TABLES;

结果:

sql 复制代码
v_student_score VIEW

说明:

sql 复制代码
VIEW ≠ TABLE

视图不是普通表。

六、查询视图

sql 复制代码
SELECT * FROM v_student_score;

结果:

student_name class_name course_name score
唐三藏 Java开发一班 Java 95

条件查询

查询所有 Java 成绩:

复制代码
SELECT *
FROM v_student_score
WHERE course_name='Java';

排序查询

复制代码
SELECT *
FROM v_student_score
ORDER BY score DESC;

七、字段重命名(Alias)

原始SQL:

复制代码
SELECT
s.name,
c.name,
co.name

结果会出现:

复制代码
name
name
name

难以区分。

解决:

sql 复制代码
SELECT
s.name AS student_name,
c.name AS class_name,
co.name AS course_name;

视图中经常使用别名提高可读性。

八、使用视图隐藏敏感字段

创建视图:

sql 复制代码
CREATE VIEW v_user_public AS
SELECT
username,
phone,
email
FROM user_account;

查询:

sql 复制代码
SELECT * FROM v_user_public;

结果:

username phone email
admin 13800000001 admin@test.com

密码字段已被隐藏。

这是不是视图最常用的手段?

绝对是!而且是视图 #1 最经典用途!

视图在企业里90% 的场景就是干这件事:

  1. 隐藏敏感字段(密码、身份证、余额)
  2. 只暴露可以公开的字段
  3. 不用创建新表!不用复制数据! 完全虚拟

九、统计总分视图

创建总分视图:

sql 复制代码
CREATE VIEW v_student_total_score AS
SELECT
s.id,
s.name,
SUM(sc.score) AS total_score
FROM student s
JOIN score sc
ON s.id=sc.student_id
GROUP BY s.id;

查询:

sql 复制代码
SELECT * FROM v_student_total_score;

结果:

姓名 总分
唐三藏 273
孙悟空 276
猪八戒 200

十、视图与真实表的关系

很多人认为:

复制代码
视图 = 数据副本

这是错误的。

实际上:

复制代码
视图 ≠ 数据副本

视图只是 SQL。

修改真实表:

sql 复制代码
UPDATE score
SET score=100
WHERE student_id=1
AND course_id=1;

查询视图:

sql 复制代码
SELECT *
FROM v_student_score
WHERE student_id=1;

发现:

复制代码
95 → 100

自动同步。

说明视图不存储数据。

十一、通过视图修改数据

创建可更新视图:

sql 复制代码
CREATE VIEW v_score_update AS
SELECT
id,
student_id,
course_id,
score
FROM score;

更新:

sql 复制代码
UPDATE v_score_update
SET score=99
WHERE id=1;

查看真实表:

sql 复制代码
SELECT * FROM score;

发现:

复制代码
真实表数据同步更新

十二、哪些视图不能更新

以下视图不能执行 UPDATE。

使用聚合函数

复制代码
SUM()
COUNT()
AVG()
MAX()
MIN()

例如:

sql 复制代码
CREATE VIEW v_total AS
SELECT
SUM(score)
FROM score;

不能更新。

使用 GROUP BY

复制代码
GROUP BY

不能更新。

使用 DISTINCT

sql 复制代码
SELECT DISTINCT name

不能更新。

使用 UNION

复制代码
UNION
UNION ALL

不能更新。

使用子查询

复制代码
SELECT
(
SELECT ...
)

不能更新。

十三、删除视图

语法:

sql 复制代码
DROP VIEW 视图名;

例如:

sql 复制代码
DROP VIEW v_student_score;

注意:

删除视图不会删除数据。

十四、企业项目中的真实应用

ERP系统

采购订单汇总视图:

sql 复制代码
v_purchase_order

封装:

  • 供应商

  • 采购单

  • 到货状态

  • 付款状态

OA系统

员工信息视图:

复制代码
v_employee_public

隐藏:

  • 身份证

  • 工资

  • 银行卡

BI报表

销售统计视图:

复制代码
v_sales_report

封装:

复制代码
SUM()
GROUP BY

报表直接查询即可。

十五、视图的优点

视图之所以在企业项目中被广泛使用,主要是因为它具备以下四大优势。

1. 简单性 ------ 简化复杂查询

假设需要查询:

  • 学生姓名
  • 班级名称
  • 课程名称
  • 成绩

使用真实表查询:

复制代码
SELECT
    s.name AS student_name,
    c.name AS class_name,
    co.name AS course_name,
    sc.score
FROM student s
JOIN class c
    ON s.class_id = c.id
JOIN score sc
    ON s.id = sc.student_id
JOIN course co
    ON sc.course_id = co.id;

随着业务复杂度增加:

复制代码
学生表
班级表
课程表
教师表
院系表
成绩表

可能需要关联 5~10 张表。

SQL 会越来越长。

此时创建视图:

复制代码
CREATE VIEW v_student_score AS
SELECT
    s.name AS student_name,
    c.name AS class_name,
    co.name AS course_name,
    sc.score
FROM student s
JOIN class c
    ON s.class_id = c.id
JOIN score sc
    ON s.id = sc.student_id
JOIN course co
    ON sc.course_id = co.id;

以后只需:

复制代码
SELECT * FROM v_student_score;

即可获得结果。

优势

复制代码
复杂SQL → 简单查询

降低开发难度,提高代码可读性。

2. 安全性 ------ 隐藏敏感数据

在实际项目中,很多表都包含敏感信息。

例如用户表:

复制代码
CREATE TABLE user_account(
    id INT,
    username VARCHAR(50),
    password VARCHAR(100),
    phone VARCHAR(20)
);

如果直接开放查询:

复制代码
SELECT * FROM user_account;

用户可以看到:

复制代码
用户名
密码
手机号

存在安全风险。

创建视图:

复制代码
CREATE VIEW v_user_public AS
SELECT
    username,
    phone
FROM user_account;

查询:

复制代码
SELECT * FROM v_user_public;

结果:

复制代码
用户名
手机号

密码字段被隐藏。

优势

复制代码
隐藏敏感字段
控制数据访问权限
提高系统安全性

3. 逻辑数据独立性 ------ 降低系统耦合

假设系统最初设计:

复制代码
student.name

应用程序大量使用:

复制代码
SELECT name FROM student;

后来需求变化:

复制代码
name
↓
student_name

如果直接访问表:

复制代码
所有程序都要修改

工作量巨大。

此时可以通过视图进行适配:

复制代码
CREATE VIEW v_student AS
SELECT
    student_name AS name
FROM student;

应用程序仍然执行:

复制代码
SELECT name FROM v_student;

无需修改代码。

优势

复制代码
数据库结构变化
↓
修改视图
↓
应用程序无需修改

实现数据库与应用程序解耦。

4. 重命名列 ------ 提高可读性

例如:

复制代码
SELECT
    s.name,
    c.name,
    co.name
FROM ...

结果:

复制代码
name
name
name

很难判断:

复制代码
哪个是学生名
哪个是班级名
哪个是课程名

创建视图时

复制代码
CREATE VIEW v_student_score AS
SELECT
    s.name AS student_name,
    c.name AS class_name,
    co.name AS course_name,
    sc.score
FROM ...

查询结果:

student_name class_name course_name score
唐三藏 Java开发一班 Java 95

字段含义一目了然。

优势

复制代码
增强数据可读性
统一字段命名规范
提高维护效率

四大优点总结

优点 作用 典型应用
简单性 简化复杂SQL 多表连接查询
安全性 隐藏敏感字段 用户权限控制
逻辑数据独立性 降低系统耦合 数据库升级
重命名列 提高可读性 数据展示层

十六、课后练习

练习1

创建一个视图:

复制代码
显示学生姓名和班级名称

参考答案:

sql 复制代码
CREATE VIEW v_student_class AS
SELECT
s.name,
c.name
FROM student s
JOIN class c
ON s.class_id=c.id;

练习2

创建一个视图:

复制代码
显示每门课程平均分

参考答案:

sql 复制代码
CREATE VIEW v_course_avg AS
SELECT
course_id,
AVG(score) AS avg_score
FROM score
GROUP BY course_id;

练习3

查询总分最高学生

参考答案:

sql 复制代码
SELECT *
FROM v_student_total_score
ORDER BY total_score DESC
LIMIT 1;

练习4

查询 Java 成绩高于90分的学生

参考答案:

sql 复制代码
SELECT *
FROM v_student_score
WHERE course_name='Java'
AND score>90;

练习5

统计每个班级平均成绩

参考答案:

sql 复制代码
CREATE VIEW v_class_avg_score AS
SELECT
c.name,
AVG(sc.score) avg_score
FROM class c
JOIN student s
ON c.id=s.class_id
JOIN score sc
ON s.id=sc.student_id
GROUP BY c.id;

十七、总结

本文从零开始介绍了 MySQL 视图的完整使用流程:

✔ 创建数据库

✔ 创建表

✔ 插入测试数据

✔ 创建视图

✔ 查询视图

✔ 更新视图

✔ 删除视图

✔ 不可更新视图

✔ 企业应用场景

✔ 实战练习题

记住一句话:

视图本质上是保存起来的 SQL 查询,它不存储数据,而是提供了一种更加安全、简洁、可维护的数据访问方式。

掌握视图后,你已经具备了企业级数据库开发中非常重要的一项技能。后续学习存储过程、触发器、索引优化和权限管理时,视图也会经常出现。祝你学习顺利! 🚀


总结

以上就是今天要讲的内容,本文简单记录了数据库学习内容,仅作为一份简单的笔记使用,大家根据注释理解,您的点赞关注收藏就是对小编最大的鼓励!

相关推荐
sukioe1 小时前
Redis 入门:为什么出现、核心原理与安装配置
数据库·redis·缓存
宇砾1 小时前
浅谈Redis(1)
数据库·redis·缓存
heimeiyingwang1 小时前
【架构实战】Canal数据同步:MySQL数据变更实时捕获
数据库·mysql·架构
cdbqss11 小时前
VB2026 动态生成工具栏类 BqGetToolStrip
数据库·oracle·开源·.net·学习方法·教育电商·basic
AI人工智能+电脑小能手1 小时前
【大白话说Java面试题 第85题】【Mysql篇】第15题:MySQL 的事务中,幻读是怎么解决的?
java·开发语言·数据库·mysql·面试
yoothey2 小时前
MySQL 索引小白面试详解
数据库·mysql
dishugj2 小时前
oracle索引unusable/disable/invisible的区别
oracle
一 乐2 小时前
在线考试|基于Springboot的在线考试管理系统设计与实现(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·毕设·在线考试管理系统
玄米乌龙茶1232 小时前
数据库与缓存核心概念
数据库·缓存