MySQL 视图(详解)
文章目录
一,视图概念
视图(view)是一种虚拟存在的表,是一个逻辑表,本身并不包含数据。作为一个select语句保存在数据字典中的。
通过视图,可以展现基表(用来创建视图的表)的部分数据;视图数据来自定义视图的查询中使用的表,使用视图动态生成。
视图(子查询):是从一个或多个表导出的虚拟的表,其内容由查询定义。具有普通表的结构,但是不实现数据存储。
对视图的修改:单表视图一般用于查询和修改,会改变基本表的数据,多表视图一般用于查询,不会改变基本表的数据。
使用视图的原因
1)简单:使用视图的用户完全不需要关心后面对应的表的结构、关联条件和筛选条件,对用户来说已经是过滤好的复合条件的结果集。
2)安全:使用视图的用户只能访问他们被允许查询的结果集,对表的权限管理并不能限制到某个行某个列,但是通过视图就可以简单的实现。
3)数据独立:一旦视图的结构确定了,可以屏蔽表结构变化对用户的影响,源表增加列对视图没有影响;源表修改列名,则可以通过修改视图来解决,不会造成对访问者的影响。
总而言之,使用视图的大部分情况是为了保障数据安全性,提高查询效率。
二,创建视图
(1)基本语法
可以使用 CREATE VIEW 语句来创建视图。
语法格式如下:
CREATE VIEW <视图名> AS
语法说明如下。
- <视图名>:指定视图的名称。该名称在数据库中必须是唯一的,不能与其他表或视图同名。
对于创建视图中的 SELECT 语句的指定存在以下限制:
- 用户除了拥有 CREATE VIEW 权限外,还具有操作中涉及的基础表和其他视图的相关权限。
- SELECT 语句不能引用系统或用户变量。
- SELECT 语句不能包含 FROM 子句中的子查询。
- SELECT 语句不能引用预处理语句参数。
视图定义中引用的表或视图必须存在。但是,创建完视图后,可以删除定义引用的表或视图。可使用 CHECK TABLE 语句检查视图定义是否存在这类问题。
视图定义中允许使用 ORDER BY 语句,但是若从特定视图进行选择,而该视图使用了自己的 ORDER BY 语句,则视图定义中的 ORDER BY 将被忽略。
视图定义中不能引用 TEMPORARY 表(临时表),不能创建 TEMPORARY 视图。
WITH CHECK OPTION 的意思是,修改视图时,检查插入的数据是否符合 WHERE 设置的条件。
(2)创建基于单表的视图
MySQL 可以在单个数据表上创建视图。
查看 test_db 数据库中的 tb_students_info 表的数据,如下所示。
mysql> SELECT * FROM tb_students_info;
±—±-------±--------±-----±-----±-------±-----------+
| id | name | dept_id | age | sex | height | login_date |
±—±-------±--------±-----±-----±-------±-----------+
| 1 | Dany | 1 | 25 | F | 160 | 2015-09-10 |
| 2 | Green | 3 | 23 | F | 158 | 2016-10-22 |
| 3 | Henry | 2 | 23 | M | 185 | 2015-05-31 |
| 4 | Jane | 1 | 22 | F | 162 | 2016-12-20 |
| 5 | Jim | 1 | 24 | M | 175 | 2016-01-15 |
| 6 | John | 2 | 21 | M | 172 | 2015-11-11 |
| 7 | Lily | 6 | 22 | F | 165 | 2016-02-26 |
| 8 | Susan | 4 | 23 | F | 170 | 2015-10-01 |
| 9 | Thomas | 3 | 22 | M | 178 | 2016-06-07 |
| 10 | Tom | 4 | 23 | M | 165 | 2016-08-05 |
±—±-------±--------±-----±-----±-------±-----------+
10 rows in set (0.00 sec)
【实例 1】
在 tb_students_info 表上创建一个名为 view_students_info 的视图,输入的 SQL 语句和执行结果如下所示。
mysql> CREATE VIEW view_students_info
-> AS SELECT * FROM tb_students_info;
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT * FROM view_students_info;
±—±-------±--------±-----±-----±-------±-----------+
| id | name | dept_id | age | sex | height | login_date |
±—±-------±--------±-----±-----±-------±-----------+
| 1 | Dany | 1 | 25 | F | 160 | 2015-09-10 |
| 2 | Green | 3 | 23 | F | 158 | 2016-10-22 |
| 3 | Henry | 2 | 23 | M | 185 | 2015-05-31 |
| 4 | Jane | 1 | 22 | F | 162 | 2016-12-20 |
| 5 | Jim | 1 | 24 | M | 175 | 2016-01-15 |
| 6 | John | 2 | 21 | M | 172 | 2015-11-11 |
| 7 | Lily | 6 | 22 | F | 165 | 2016-02-26 |
| 8 | Susan | 4 | 23 | F | 170 | 2015-10-01 |
| 9 | Thomas | 3 | 22 | M | 178 | 2016-06-07 |
| 10 | Tom | 4 | 23 | M | 165 | 2016-08-05 |
±—±-------±--------±-----±-----±-------±-----------+
10 rows in set (0.04 sec)
默认情况下,创建的视图和基本表的字段是一样的,也可以通过指定视图字段的名称来创建视图。
【实例 2】
在 tb_students_info 表上创建一个名为 v_students_info 的视图,输入的 SQL 语句和执行结果如下所示。
mysql> CREATE VIEW v_students_info
-> (s_id,s_name,d_id,s_age,s_sex,s_height,s_date)
-> AS SELECT id,name,dept_id,age,sex,height,login_date
-> FROM tb_students_info;
Query OK, 0 rows affected (0.06 sec)
mysql> SELECT * FROM v_students_info;
±-----±-------±-----±------±------±---------±-----------+
| s_id | s_name | d_id | s_age | s_sex | s_height | s_date |
±-----±-------±-----±------±------±---------±-----------+
| 1 | Dany | 1 | 24 | F | 160 | 2015-09-10 |
| 2 | Green | 3 | 23 | F | 158 | 2016-10-22 |
| 3 | Henry | 2 | 23 | M | 185 | 2015-05-31 |
| 4 | Jane | 1 | 22 | F | 162 | 2016-12-20 |
| 5 | Jim | 1 | 24 | M | 175 | 2016-01-15 |
| 6 | John | 2 | 21 | M | 172 | 2015-11-11 |
| 7 | Lily | 6 | 22 | F | 165 | 2016-02-26 |
| 8 | Susan | 4 | 23 | F | 170 | 2015-10-01 |
| 9 | Thomas | 3 | 22 | M | 178 | 2016-06-07 |
| 10 | Tom | 4 | 23 | M | 165 | 2016-08-05 |
±-----±-------±-----±------±------±---------±-----------+
10 rows in set (0.01 sec)
可以看到,view_students_info 和 v_students_info 两个视图中的字段名称不同,但是数据却相同。因此,在使用视图时,可能用户不需要了解基本表的结构,更接触不到实际表中的数据,从而保证了数据库的安全。
(3)创建基于多表的视图
MySQL 中也可以在两个以上的表中创建视图,使用 CREATE VIEW 语句创建。
【实例 3】
在表 tb_student_info 和表 tb_departments 上创建视图 v_students_info,输入的 SQL 语句和执行结果如下所示。
mysql> CREATE VIEW v_students_info
-> (s_id,s_name,d_id,s_age,s_sex,s_height,s_date)
-> AS SELECT id,name,dept_id,age,sex,height,login_date
-> FROM tb_students_info;
Query OK, 0 rows affected (0.06 sec)
mysql> SELECT * FROM v_students_info;
±-----±-------±-----±------±------±---------±-----------+
| s_id | s_name | d_id | s_age | s_sex | s_height | s_date |
±-----±-------±-----±------±------±---------±-----------+
| 1 | Dany | 1 | 24 | F | 160 | 2015-09-10 |
| 2 | Green | 3 | 23 | F | 158 | 2016-10-22 |
| 3 | Henry | 2 | 23 | M | 185 | 2015-05-31 |
| 4 | Jane | 1 | 22 | F | 162 | 2016-12-20 |
| 5 | Jim | 1 | 24 | M | 175 | 2016-01-15 |
| 6 | John | 2 | 21 | M | 172 | 2015-11-11 |
| 7 | Lily | 6 | 22 | F | 165 | 2016-02-26 |
| 8 | Susan | 4 | 23 | F | 170 | 2015-10-01 |
| 9 | Thomas | 3 | 22 | M | 178 | 2016-06-07 |
| 10 | Tom | 4 | 23 | M | 165 | 2016-08-05 |
±-----±-------±-----±------±------±---------±-----------+
10 rows in set (0.01 sec)
通过这个视图可以很好地保护基本表中的数据。视图中包含 s_id、s_name 和 dept_name,s_id 字段对应 tb_students_info 表中的 id 字段,s_name 字段对应 tb_students_info 表中的 name 字段,dept_name 字段对应 tb_departments 表中的 dept_name 字段。
(4)查询视图
视图一经定义之后,就可以如同查询数据表一样,使用 SELECT 语句查询视图中的数据,语法和查询基础表的数据一样。
视图用于查询主要应用在以下几个方面:
- 使用视图重新格式化检索出的数据。
- 使用视图简化复杂的表连接。
- 使用视图过滤数据。
DESCRIBE 可以用来查看视图,语法如下:
DESCRIBE 视图名;
【实例 4】
通过 DESCRIBE 语句查看视图 v_students_info 的定义,输入的 SQL 语句和执行结果如下所示。
mysql> DESCRIBE v_students_info;
±---------±--------------±-----±----±-----------±------+
| Field | Type | Null | Key | Default | Extra |
±---------±--------------±-----±----±-----------±------+
| s_id | int(11) | NO | | 0 | |
| s_name | varchar(45) | YES | | NULL | |
| d_id | int(11) | YES | | NULL | |
| s_age | int(11) | YES | | NULL | |
| s_sex | enum(‘M’,‘F’) | YES | | NULL | |
| s_height | int(11) | YES | | NULL | |
| s_date | date | YES | | 2016-10-22 | |
±---------±--------------±-----±----±-----------±------+
7 rows in set (0.04 sec)
注意:DESCRIBE 一般情况下可以简写成 DESC,输入这个命令的执行结果和输入 DESCRIBE 是一样的。
三,查看视图
1、查询表(包括view)
mysql> use iips;
Database changed
mysql> show tables;
±---------------------------+
| Tables_in_iips |
±---------------------------+
| tbepartner |
| tbepartnerconfig |
| tborg |
±---------------------------+
3 rows in set
2、查询视图
mysql> show table status where comment ='view';+-------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+-------------+-------------+------------+-----------+----------+----------------+---------+| Name | Engine | Version | Row_format | Rows | Avg_row_length | Data_length | Max_data_length | Index_length | Data_free | Auto_increment | Create_time | Update_time | Check_time | Collation | Checksum | Create_options | Comment |+-------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+-------------+-------------+------------+-----------+----------+----------------+---------+| tborg | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | VIEW |+-------+--------+---------+------------+------+----------------+-------------+-----------------+--------------+-----------+----------------+-------------+-------------+------------+-----------+----------+----------------+---------+1 row in set
四,修改视图
修改视图是指修改 MySQL 数据库中存在的视图,当基本表的某些字段发生变化时,可以通过修改视图来保持与基本表的一致性。
(1)基本语法
可以使用 ALTER VIEW 语句来对已有的视图进行修改。
语法格式如下:
ALTER VIEW <视图名> AS
语法说明如下:
- <视图名>:指定视图的名称。该名称在数据库中必须是唯一的,不能与其他表或视图同名。
需要注意的是,对于 ALTER VIEW 语句的使用,需要用户具有针对视图的 CREATE VIEW 和 DROP 权限,以及由 SELECT 语句选择的每一列上的某些权限。
修改视图的定义,除了可以通过 ALTER VIEW 外,也可以使用 DROP VIEW 语句先删除视图,再使用 CREATE VIEW 语句来实现。
(2)修改视图内容
视图是一个虚拟表,实际的数据来自于基本表,所以通过插入、修改和删除操作更新视图中的数据,实质上是在更新视图所引用的基本表的数据。
注意:对视图的修改就是对基本表的修改,因此在修改时,要满足基本表的数据定义。
某些视图是可更新的。也就是说,可以使用 UPDATE、DELETE 或 INSERT 等语句更新基本表的内容。对于可更新的视图,视图中的行和基本表的行之间必须具有一对一的关系。
还有一些特定的其他结构,这些结构会使得视图不可更新。更具体地讲,如果视图包含以下结构中的任何一种,它就是不可更新的:
- 聚合函数 SUM()、MIN()、MAX()、COUNT() 等。
- DISTINCT 关键字。
- HAVING 子句。
- UNION 或 UNION ALL 运算符。
- 位于选择列表中的子查询。
- FROM 子句中的不可更新视图或包含多个表。
- WHERE 子句中的子查询,引用 FROM 子句中的表。
- ALGORITHM 选项为 TEMPTABLE(使用临时表总会使视图成为不可更新的)的时候。
【实例 1】
使用 ALTER 语句修改视图 view_students_info,输入的 SQL 语句和执行结果如下所示。
mysql> ALTER VIEW view_students_info
-> AS SELECT id,name,age
-> FROM tb_students_info;
Query OK, 0 rows affected (0.07 sec)
mysql> DESC view_students_info;
±------±------------±-----±----±--------±------+
| Field | Type | Null | Key | Default | Extra |
±------±------------±-----±----±--------±------+
| id | int(11) | NO | | 0 | |
| name | varchar(45) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
±------±------------±-----±----±--------±------+
3 rows in set (0.03 sec)
用户可以通过视图来插入、更新、删除表中的数据,因为视图是一个虚拟的表,没有数据。通过视图更新时转到基本表上进行更新,如果对视图增加或删除记录,实际上是对基本表增加或删除记录。
查看视图 view_students_info 的数据内容,如下所示。
mysql> SELECT * FROM view_students_info;
±—±-------±-----+
| id | name | age |
±—±-------±-----+
| 1 | Dany | 24 |
| 2 | Green | 23 |
| 3 | Henry | 23 |
| 4 | Jane | 22 |
| 5 | Jim | 24 |
| 6 | John | 21 |
| 7 | Lily | 22 |
| 8 | Susan | 23 |
| 9 | Thomas | 22 |
| 10 | Tom | 23 |
±—±-------±-----+
10 rows in set (0.00 sec)
【实例 2】
使用 UPDATE 语句更新视图 view_students_info,输入的 SQL 语句和执行结果如下所示。
mysql> UPDATE view_students_info
-> SET age=25 WHERE id=1;
Query OK, 0 rows affected (0.24 sec)
Rows matched: 1 Changed: 0 Warnings: 0
mysql> SELECT * FROM view_students_info;
±—±-------±-----+
| id | name | age |
±—±-------±-----+
| 1 | Dany | 25 |
| 2 | Green | 23 |
| 3 | Henry | 23 |
| 4 | Jane | 22 |
| 5 | Jim | 24 |
| 6 | John | 21 |
| 7 | Lily | 22 |
| 8 | Susan | 23 |
| 9 | Thomas | 22 |
| 10 | Tom | 23 |
±—±-------±-----+
10 rows in set (0.00 sec)
查看基本表 tb_students_info 和视图 v_students_info 的内容,如下所示。
mysql> SELECT * FROM tb_students_info;
±—±-------±--------±-----±-----±-------±-----------+
| id | name | dept_id | age | sex | height | login_date |
±—±-------±--------±-----±-----±-------±-----------+
| 1 | Dany | 1 | 25 | F | 160 | 2015-09-10 |
| 2 | Green | 3 | 23 | F | 158 | 2016-10-22 |
| 3 | Henry | 2 | 23 | M | 185 | 2015-05-31 |
| 4 | Jane | 1 | 22 | F | 162 | 2016-12-20 |
| 5 | Jim | 1 | 24 | M | 175 | 2016-01-15 |
| 6 | John | 2 | 21 | M | 172 | 2015-11-11 |
| 7 | Lily | 6 | 22 | F | 165 | 2016-02-26 |
| 8 | Susan | 4 | 23 | F | 170 | 2015-10-01 |
| 9 | Thomas | 3 | 22 | M | 178 | 2016-06-07 |
| 10 | Tom | 4 | 23 | M | 165 | 2016-08-05 |
±—±-------±--------±-----±-----±-------±-----------+
10 rows in set (0.00 sec)
mysql> SELECT * FROM v_students_info;
±-----±-------±-----±------±------±---------±-----------+
| s_id | s_name | d_id | s_age | s_sex | s_height | s_date |
±-----±-------±-----±------±------±---------±-----------+
| 1 | Dany | 1 | 25 | F | 160 | 2015-09-10 |
| 2 | Green | 3 | 23 | F | 158 | 2016-10-22 |
| 3 | Henry | 2 | 23 | M | 185 | 2015-05-31 |
| 4 | Jane | 1 | 22 | F | 162 | 2016-12-20 |
| 5 | Jim | 1 | 24 | M | 175 | 2016-01-15 |
| 6 | John | 2 | 21 | M | 172 | 2015-11-11 |
| 7 | Lily | 6 | 22 | F | 165 | 2016-02-26 |
| 8 | Susan | 4 | 23 | F | 170 | 2015-10-01 |
| 9 | Thomas | 3 | 22 | M | 178 | 2016-06-07 |
| 10 | Tom | 4 | 23 | M | 165 | 2016-08-05 |
±-----±-------±-----±------±------±---------±-----------+
10 rows in set (0.00 sec)
(3)修改视图名称
修改视图的名称可以先将视图删除,然后按照相同的定义语句进行视图的创建,并命名为新的视图名称。
五,删除视图
删除视图是指删除 MySQL 数据库中已存在的视图。删除视图时,只能删除视图的定义,不会删除数据。
(1)基本语法
可以使用 DROP VIEW 语句来删除视图。
语法格式如下:
DROP VIEW <视图名1> [ , <视图名2> …]
其中:<视图名> 指定要删除的视图名。DROP VIEW 语句可以一次删除多个视图,但是必须在每个视图上拥有 DROP 权限。
(2)删除视图
【实例】
删除 v_students_info 视图,输入的 SQL 语句和执行过程如下所示。
mysql> DROP VIEW IF EXISTS v_students_info;
Query OK, 0 rows affected (0.00 sec)
mysql> SHOW CREATE VIEW v_students_info;
ERROR 1146 (42S02): Table ‘test_db.v_students_info’ doesn’t exist
可以看到,v_students_info 视图已不存在,将其成功删除。
六,通过视图更新基本表数据
前面内容中,使用视图进行了查询操作。其实视图还可以进行更新操作,包括增加(insert)、删除(delete)和更新(update)数据。更新操作的实际对象是基本表。
(1)INSERT语句通过视图添加数据
基本格式
insert [into] 视图名 [(字段名1, 字段名2, …)] values | value (值1, 值2, …);
【实例1】
insert into view1_emp values (8000, ‘别怡情’, ‘职员’, 7564, ‘2020-05-20’, 20);
执行结果如下:
(2)DELETE语句通过视图删除数据
基本格式
delete from 视图名 [where 条件语句]
【实例2】
delete from view1_emp where ename=‘别怡情’;
执行结果如下:
(3)UPDATE语句通过视图更新数据
基本格式
update 视图名 set 字段名=值 [where 更新条件]
【实例3】
update view1_emp set jobrank=‘副处长’ where ename=‘王美美’;
执行结果如下:
来源地址:https://blog.csdn.net/m0_62617719/article/details/124313392
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341