mysql--视图(view)

本文深入讲解MySQL中的视图概念,包括视图的创建、使用、更新及删除等操作,探讨如何利用视图简化复杂的查询语句,提升数据操作效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原创 大孩子 我们都是小青蛙 2018-07-02
社会我蛙哥,人狠话也多
视图
我们之前唠叨过连接表的查询,比方说下边这个:

image_1chb82o2b15c81t4416291a52cffp.png-123.5kB
我们查询出了一些男学生的基本信息和成绩信息,如果下次还想得到这些信息,我们就不得不把这个又臭又长的查询语句再敲一遍,所以MySQL提供了视图(英文名VIEW)来帮助我们用很容易的方式去复用这些查询语句。

创建视图
一个视图可以理解为一个查询语句的别名,创建视图的语句如下:

CREATE VIEW 视图名 AS 查询语句
比如我们想根据上边那个又臭又长的查询语句来创建一个视图可以这么写:

mysql> CREATE VIEW male_student_info AS SELECT s1.number, s1.name, s1.major, s2.subject, s2.score FROM student_info AS s1 INNER JOIN student_score AS s2 WHERE s1.number = s2.number AND s1.sex = ‘男’;
Query OK, 0 rows affected (0.02 sec)

mysql>
这样,这个名称为male_student_info的视图就代表了那一串又臭又长的查询语句了。

使用视图
视图也被称为虚拟表,因为我们可以对视图进行一些类似表的增删改查操作,只不过我们对视图的相关操作都会被映射到那个又臭又长的查询语句对应的底层的表上。那一串又臭又长的查询语句的查询列表可以被当作视图的虚拟列,比方说male_student_info这个视图对应的查询语句中的查询列表是number、name、major、subject、score,它们也是male_student_info视图的虚拟列。

比如我们可以使用平常的查询语句从视图中查询我们需要的信息可以这么写:

image_1chb8adng129m1qlo15pt1qm8fp1p.png-96.6kB
这里我们的查询列表是*,这也就意味着male_student_info所代表的查询语句的结果集将作为整个查询的结果集返回。从这个例子中我们也可以看到,我们不再需要使用那句又臭又长的连接查询语句了,只需要从它对应的视图中查询即可。

除此之外,我们在真实表中使用的那些查询语句都可以被用到视图这个虚拟表中,比方说这个查询语句:

image_1chb8bn1811ee8csfen1b0f6bl26.png-58.2kB
我们再次强调一遍,视图其实就是某个查询的别名,而不是某个查询的结果集,换句话说就是,创建视图的时候并不会把那个又臭又长的查询语句的结果集维护在硬盘或者内存里!在对视图进行查询时,MySQL服务器将会帮助我们把对视图的查询语句转换为对底层表的查询语句然后再执行,所以上边这个查询其实会被转换成下边这个查询语句去执行:

SELECT subject, AVG(score) FROM student_info AS s1 INNER JOIN student_score AS s2 WHERE s1.number = s2.number AND s1.sex = ‘男’ AND score > 60 GROUP BY subject HAVING AVG(score) > 75;
只不过这个转换的过程我们并不能看到,所以主观上认为硬盘或内存里真的维护了一个视图对应的表而已~ 更复杂的一些查询语句,比如子查询、连接查询什么的,都可以被用到视图上,我们这里就不举例子了。

有一点比较有趣的是,在查询时,视图可以和表一起使用,包括子查询和连接查询,比如这样:

image_1chb8cv3e16hv2g91s2e16261l1f2j.png-89.5kB
所以在使用层面,我们完全可以把视图当作一个表去使用,但是它的实现原理却是在执行语句时转换为对底层表的操作。使用视图的好处也是显而易见的,我们可以复用某个查询语句,从而简化了查询操作,避免了每次查询时都要写一遍又臭又长的语句;对视图的操作更加直观,而不用考虑它底层的查询细节。

利用视图来创建新视图
我们前边说视图是某个查询语句的别名,其实这个查询语句不仅可以从普通的表中查询数据,也可以从另一个视图中查询数据,只要是个合法的查询语句就好了。比方说我们利用male_student_info视图来创建另一个新视图可以这么写:

mysql> CREATE VIEW by_view AS SELECT number, name, score FROM male_student_info;
Query OK, 0 rows affected (0.02 sec)

mysql>
我们查询一下这个从另一个视图中生成的视图:

image_1chb8hku4lko1iqa1t0bn8l1a3g.png-48.1kB
这种利用其他的视图来生成的新视图也被称为嵌套视图,在对某个嵌套视图执行查询时,查询语句会先被转换成对它依赖的视图的查询,再转换成对底层表的查询。

创建视图时指定自定义列名
我们前边说过视图的虚拟列其实是这个视图对应的查询语句的查询列表,我们也可以在创建列表的时候为这些虚拟列自定义列名,这些自定义列名写到视图名后边,用逗号,分隔就好了,不过需要注意的是,自定义列名一定要和查询列表中的查询对象一一对应。比如我们新创建一个自定义列名的视图:

mysql> CREATE VIEW student_info_view(no, n, m) AS SELECT number, name, major FROM student_info;
Query OK, 0 rows affected (0.02 sec)

mysql>
我们的自定义列名列表是no, n, m,分别对应查询列表中的number, name, major。有了自定义列名之后,我们之后对视图的查询语句都要基于这些自定义列名,比如我们可以这么查询:

image_1chb8pca923a1du41448v7uk776d.png-77.9kB
如果仍旧使用与视图对应的查询语句的查询列表中的列名就会报错,比如这样:

mysql> SELECT number, name, major FROM student_info_view;
ERROR 1054 (42S22): Unknown column ‘number’ in ‘field list’
mysql>
查看和删除视图
查看有哪些视图
我们想查看当前数据库中有哪些视图的话,其实和查看有哪些表的命令是一样的:

mysql> SHOW TABLES;
±--------------------+
| Tables_in_xiaohaizi |
±--------------------+
| by_view |
| first_table |
| male_student_info |
| second_table |
| student_info |
| student_info_view |
| student_score |
| t |
| t1 |
| t2 |
| t3 |
| zero_table |
±--------------------+
12 rows in set (0.00 sec)

mysql>
可以看到,我们创建的几个视图,包括by_view、male_student_info、student_info_view就都显示出来了。需要注意的是,因为视图是一张虚拟表,所以新创建的视图的名称不能和当前数据库中的其他视图或者表的名称冲突!

查看视图的定义
因为视图是一张虚拟表,所以用来查看表结构的语句都可以用来查看视图的结构,不过我们经常使用的查看视图定义语句是这个:

SHOW CREATE VIEW 视图名
我们来查看一下student_info_view视图的定义:

mysql> SHOW CREATE VIEW student_info_view\G
*************************** 1. row ***************************
View: student_info_view
Create View: CREATE ALGORITHM=UNDEFINED DEFINER=root@localhost SQL SECURITY DEFINER VIEW student_info_view AS select student_info.number AS no,student_info.name AS n,student_info.major AS m from student_info
character_set_client: utf8
collation_connection: utf8_general_ci
1 row in set (0.00 sec)

mysql>
删除视图
如果某个视图我们不想要了,可以使用这个语句来删除掉它:

DROP VIEW 视图名
比如我们把by_view视图删掉可以这么写:

mysql> DROP VIEW by_view;
Query OK, 0 rows affected (0.00 sec)

mysql>
然后再查看当前数据库中的表:

mysql> SHOW TABLES;
±--------------------+
| Tables_in_xiaohaizi |
±--------------------+
| first_table |
| male_student_info |
| second_table |
| student_info |
| student_info_view |
| student_score |
| t |
| t1 |
| t2 |
| t3 |
| zero_table |
±--------------------+
11 rows in set (0.00 sec)

mysql>
这个视图就不见了!

更新视图
我们前边进行的都是对视图的查询操作,其实也可以对视图进行更新,也就是在视图上执行INSERT、DELETE、UPDATE语句。对视图执行更新语句的本质上是对该视图对应的底层表进行更新。比方说视图student_info_view的底层表是student_info,所以如果我们对student_info_view执行更新语句就相当于对student_info表进行更新,比方说我们执行这个语句:

mysql> UPDATE student_info_view SET n = ‘111’ WHERE no = 20180101;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1 Changed: 1 Warnings: 0

mysql>
我们再到student_info表中看一下这个学生的名称是否被改了:

mysql> SELECT name FROM student_info WHERE number = 20180101;
±-----+
| name |
±-----+
| 111 |
±-----+
1 row in set (0.00 sec)

mysql>
名称的确被更改成功了!

不过并不是可以在所有的视图上执行更新语句的,在生成视图的时候使用了下边这些语句的都不能进行更新:

分组

连接查询

子查询

组合查询

聚集函数

DISTINCT

查询列表上是非列名的表达式

虽然有这么多限制,但是需要我们注意的是,一般情况下,我们只在视图上执行查询操作而不进行更新操作!这里介绍对视图的更新只是为了语法的完整性,并不是建议大家在实际使用过程中使用对视图的更新功能。

### MySQL 视图的基本概念 视图View)是一种虚拟表,其内容由查询定义[^2]。尽管它看起来像真实存在的表,但实际上并没有实际存储数据值集合。当访问视图时,底层会通过执行定义该视图的 `SELECT` 查询来动态生成所需的数据。 #### 视图的特点 - **虚拟性**:视图不占用物理空间,仅保存定义它的 SQL 查询语句。 - **安全性**:可以限制用户只查看特定字段或记录,从而保护敏感数据[^3]。 - **简化复杂查询**:可以通过创建视图隐藏复杂的联结或多层嵌套逻辑,使后续查询更加简单直观。 - **一致性维护**:即使基础表发生变化,只要不影响视图定义的有效性,基于此视图的操作仍然有效[^4]。 --- ### 创建视图的方法 创建视图的核心语法如下: ```sql CREATE [OR REPLACE] [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}] [DEFINER = { user | CURRENT_USER }] [SQL SECURITY { DEFINER | INVOKER }] VIEW view_name [(column_list)] AS select_statement [WITH [CASCADED | LOCAL] CHECK OPTION]; ``` 以下是各部分参数的具体含义: - **`CREATE OR REPLACE`**:如果已存在相同名称的视图,则覆盖原视图- **`ALGORITHM`**:指定视图实现方式,默认为未定义 (`UNDEFINED`);可以选择合并模式 (`MERGE`) 或临时表模式 (`TEMPTABLE`)- **`DEFINER` 和 `SQL SECURITY`**:控制谁有权调用以及如何验证权限。 - **`view_name`**:新视图的名字。 - **`column_list`**:可选项,用来显式声明返回列名。 - **`select_statement`**:构建视图的基础查询语句。 - **`CHECK OPTION`**:确保任何针对视图所做的更改都符合原始查询条件。 下面给出一个简单的例子说明如何建立视图: ```sql -- 建立名为v_employee基本信息展示视图 CREATE VIEW v_employee AS SELECT employee_id, first_name, last_name, department_id FROM employees; ``` 以上命令将从员工表(`employees`)提取四个主要字段形成一个新的视角供以后查阅使用[^2]。 --- ### 使用视图进行查询 一旦建立了视图之后,就可以如同对待常规表格那样对其进行读取操作了。例如继续沿用上面的例子: ```sql SELECT * FROM v_employee WHERE department_id = 90; ``` 这条指令将会筛选出部门编号等于90的所有雇员详情[^4]。 值得注意的是,由于视图依赖于底层数椐源的变化而自动调整显示结果,因此无需额外同步工作即可反映最新状态[^3]。 --- ### 更新与删除视图 除了能够利用视图检索资料外,在某些情况下还可以经由它们完成更新或者移除动作。不过这取决于初始设计时候是否允许此类行为发生,并且要遵循一定的约束规则比如启用 WITH CHECK OPTION 参数等设置。 举个实例演示怎样借助先前设定好的视图去改变某条记录的信息: ```sql UPDATE v_employee SET last_name='Smith' WHERE employee_id=102; ``` 最后别忘了清理不再需要的对象以免造成混乱: ```sql DROP VIEW IF EXISTS v_employee; ``` --- ### 总结 综上所述,MySQL 中的视图提供了一种灵活机制帮助我们更好地管理和交互数据库资源。无论是为了提升用户体验还是加强信息安全防护方面都有不可替代的作用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值