# 视图
视图和表是类似的,两者唯一区别是:表保存的是实际的数据,而视图保存的是一条select语句(视图本身并不存储数据)。用最简单的一句话来说就是:视图是一个临时表或虚拟表。
特点:
- 简化复杂查询:通过将复杂的查询封装在视图中,可以简化查询语句。
- 增强安全性:可以通过授予用户对视图的权限,而不是直接对基础表的权限,从而控制数据访问。
- 提供数据独立性:如果底层表结构发生变化,只要视图的定义保持不变,依赖该视图的应用程序就不需要修改。
- 逻辑数据独立性:视图可以隐藏数据的具体实现细节,只暴露必要的信息。
# 创建视图
可以将又长又臭的select语句保存到“视图”中去,以便下次快速使用。
create view 视图名
as 查询语句;
2
视图主要有以下3个方面的应用场景:
- 聚焦特定数据
- 提高重用性
- 提高安全性
# 示例
- 创建表
创建学生表,课程表,
CREATE TABLE students (
sno INT PRIMARY KEY,
name VARCHAR(50),
major VARCHAR(50)
);
CREATE TABLE courses (
course_id INT PRIMARY KEY,
course_name VARCHAR(50)
);
CREATE TABLE enrollments (
enrollment_id INT AUTO_INCREMENT PRIMARY KEY,
sno INT,
course_id INT,
grade CHAR(2),
FOREIGN KEY (sno) REFERENCES students(sno),
FOREIGN KEY (course_id) REFERENCES courses(course_id)
);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- 插入数据
INSERT INTO students (sno, name, major) VALUES
(1, 'Alice', 'Computer Science'),
(2, 'Bob', 'Mathematics');
INSERT INTO courses (course_id, course_name) VALUES
(101, 'Database Systems'),
(102, 'Algorithms');
INSERT INTO enrollments (sno, course_id, grade) VALUES
(1, 101, 'A'),
(1, 102, 'B'),
(2, 102, 'B');
2
3
4
5
6
7
8
9
10
11
12
- 创建视图
student_enrollments
视图通过连接 students
、enrollments
和 courses
表,提供了每个学生及其选修课程的详细信息
-- 创建 student_enrollments 视图
CREATE VIEW student_enrollments AS
-- 指定了从查询中选择的列
SELECT s.sno, s.name, c.course_name, e.grade
FROM students s
-- 将 students 表与 enrollments 表进行连接,接条件是 students 表中的 sno 列与 enrollments 表中的 sno 列相等
JOIN enrollments e ON s.sno = e.sno
-- 将 enrollments 表与 courses 表进行连接,连接条件是 enrollments 表中的 course_id 列与 courses 表中的 course_id 列相等
JOIN courses c ON e.course_id = c.course_id;
2
3
4
5
6
7
8
9
执行上述查询后,输出结果将是:
sno | name | course_name | grade |
---|---|---|---|
1 | Alice | Database Systems | A |
1 | Alice | Algorithms | B |
2 | Bob | Algorithms | B |
# 修改视图
在MySQL中,如果想要修改一个视图,我们有以下两种方式:
-- 方式1
CREATE OR REPLACE VIEW 视图名
AS 查询语句;
-- 方式2
ALTER VIEW 视图名
AS 查询语句;
2
3
4
5
6
7
对于一个表来说,修改数据的操作包括:插入(insert)、更新(update)、删除(delete)。对于一个视图来说,我们同样可以对其进行这3种操作。
特别注意
在使用 union
、inner
join
、子查询的视图中,不能执行 insert
和 update
这两个操作。而对于普通 select
语句的视图,insert
和 update
则是允许的。
并不是所有视图都可以对其进行修改数据的(包括插入、更新、删除)。对于MySQL来说,以下几种情况的视图不允许修改数据:
- 包含聚合函数的视图。
- 包含子查询的视图。
- 包含distinct、group by、having、union、union等的视图。
- 由不可更新的视图所创建的视图。
笔记
视图保存的是一条select语句,那么是不是说任意的select语句都可以呢? 并不是这样的,对于视图保存的select语句,存在以下3个限制。这里简单了解一下就可以了,不必过于深究。
- select语句不能包含from子句中的子查询。
- select语句不能引用系统变量或用户变量。
- select语句不能引用预处理语句参数。
# 示例
向现有的 student_enrollments
视图中添加一个新列 major
,显示每个学生的专业,并且只包含成绩为 'A' 的记录:
-- 修改视图:添加 major 列并过滤成绩为 'A' 的记录
CREATE OR REPLACE VIEW student_enrollments AS
SELECT s.sno, s.name, s.major, c.course_name, e.grade
FROM students s
JOIN enrollments e ON s.sno = e.sno
JOIN courses c ON e.course_id = c.course_id
WHERE e.grade = 'A';
2
3
4
5
6
7
更改后的视图:
sno | name | major | course_name | grade |
---|---|---|---|---|
1 | Alice | Computer Science | Database Systems | A |
# 查看视图
在 MySQL
中,如果想要查看一个视图的基本信息,我们有3种方式:
-- 方式1
describe 视图名;
-- 方式2
show table status like '视图名';
-- 方式3
show create view 视图名;
2
3
4
5
6
7
8
# 删除视图
想要删除一个表,我们可以使用drop table语句来实现。而想要删除一个视图,我们可以使用drop view语句来实现:
drop view 视图名;
# 多表视图
多表视图,本质上是连接多个表选取若干列来创建一个视图,所以多表视图肯定会涉及多表查询。
多表视图和单表视图的语法没有任何区别,都是使用create view语句来实现。
create view 视图名
as 查询语句;
2
当前示例其实就是一个多表视图示例:
-- 创建 student_enrollments 视图
CREATE VIEW student_enrollments AS
-- 指定了从查询中选择的列
SELECT s.sno, s.name, c.course_name, e.grade
FROM students s
-- 将 students 表与 enrollments 表进行连接,接条件是 students 表中的 sno 列与 enrollments 表中的 sno 列相等
JOIN enrollments e ON s.sno = e.sno
-- 将 enrollments 表与 courses 表进行连接,连接条件是 enrollments 表中的 course_id 列与 courses 表中的 course_id 列相等
JOIN courses c ON e.course_id = c.course_id;
2
3
4
5
6
7
8
9