视图
数据库中的视图是一个虚拟表。同真实的表一样,视图包含一系列带有名称的行和列数据。行和列数据来自由定义视图查询所引用的表,并且在引用视图时动态生成。
1、视图概述
视图是从一个或者多个表中导出的,视图的行为与表非常相似,但视图是一个虚拟表。在视图中用户可以使用SELECT语句查询数据,以及使用INSERT、UPDATE和DELETE修改记录。从MySQL 5.0开始可以使用视图,视图可以使用户操作方便,而且可以保障数据库系统的安全。
1.1、视图的含义
视图是一个虚拟表,是从数据库中一个或多个表中导出来的表。视图还可以从已经存在的视图的基础上定义。
视图一经定义便存储在数据库中,与其相对应的数据并没有像表那样在数据库中再存储一份,通过视图看到的数据只是存放在基本表中的数据。对视图的操作与对表的操作一样,可以对其进行查询、修改和删除。当对通过视图看到的数据进行修改时,相应的基本表的数据也要发生变化;同时,若基本表的数据发生变化,则这种变化也可以自动反映到视图中。
下面有一个student表和stu_info表,在student表中包含了学生的id号和姓名,stu_info表中包含了学生的id号、班级和家庭住址,而现在公布分班信息只需要id号、姓名和班级,该如何解决呢?
表设计如下:
create table student
(
s_id int,
name varchar(40)
);
create table stu_info
(
s_id int,
glass varchar(40),
addr varchar(90)
);
通过DESC命令可以查看表的设计,可以获得字段、字段的定义、是否为主键、是否为空、默认值和扩展信息。
视图提供了一个很好的解决方法。创建一个视图,这些信息来自表的部分信息,其他的信息不取,这样既能满足要求也不破坏表原来的结构。
1.2、视图的作用
与直接从数据表中读取相比,视图有以下优点:
- 简单化:看到的就是需要的。视图不仅可以简化用户对数据的理解,也可以简化它们的操作。那些被经常使用的查询可以被定义为视图,从而使得用户不必为以后的操作每次指定全部的条件。
- 安全性:通过视图用户只能查询和修改他们所能见到的数据。数据库中的其他数据则既看不见也取不到。数据库授权命令可以使每个用户对数据库的检索限制到特定的数据库对象上,但不能授权到数据库特定行和特定的列上。通过视图,用户可以被限制在数据的不同子集上:
- 使用权限可被限制在基表的行的子集上。
- 使用权限可被限制在基表的列的子集上。
- 使用权限可被限制在基表的行和列的子集上。
- 使用权限可被限制在多个基表的连接所限定的行上。
- 使用权限可被限制在基表中的数据的统计汇总上。
- 使用权限可被限制在另一视图的一个子集上,或是一些视图和基表合并后的子集上。
- 逻辑数据独立性:视图可帮助用户屏蔽真实表结构变化带来的影响。
2、创建视图
视图中包含了SELECT查询的结果,因此视图的创建基于SELECT语句和已存在的数据表。视图可以建立在一张表上,也可以建立在多张表上
2.1、创建视图的语法形式
创建视图使用CREATE VIEW语句,基本语法格式如下:
CREATE [ OR REPLACE ] [ ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
VIEW view_name {(column_list)]
as select_statement
[WITH [CASCADED | LOCAL ] CHECK OPTION]
- CREATE表示创建新的视图;
- REPLACE表示替换已经创建的视图;
- ALGORITHM表示视图选择的算法;
UNDEFINED表示MySQL将自动选择算法;MERGE表示将使用的视图语句与视图定义合并起来,使得视图定义的某一部分取代 语句对应的部分;TEMPTABLE表示将视图的结果存入临时表,然后用临时表来执行语句。
- view_name为视图的名称
- column_list为属性列;
- SELECT_statement表示SELECT语句;
- WITH [CASCADED | LOCAL] CHECKOPTION参数表示视图在更新时保证在视图的权限范围之内。CASCADED与LOCAL为可选参数。
CASCADED为默认值,表示更新视图时要满足所有相关视图和表的条件;LOCAL表示更新视图时满足该视图本身定义的条件即可。
该语句要求具有针对视图的CREATE VIEW权限,以及针对由SELECT语句选择的每一列上的某些权限。对于在SELECT语句中其他地方使用的列,必须具有SELECT权限。如果还有OR REPLACE子句,必须在视图上具有DROP权限。
视图属于数据库。在默认情况下,将在当前数据库创建新视图。要想在给定数据库中明确创建视图,创建时应将名称指定为db_name.view_name。
2.2、在单表上创建视图
MySQL可以在单个数据表上创建视图。
在t表上创建一个名为view_t的视图,代码如下:
首先创建基本表并插入数据,语句如下:
create table t
(
quantity int,
price int
);
insert into t values(3, 50);
创建视图语句为:
create view view_t as
select quantity, price, quantity * price
from t;
查询视图,执行如下:
select * from view_t;
+----------+-------+------------------+
| quantity | price | quantity * price |
+----------+-------+------------------+
| 3 | 50 | 150 |
+----------+-------+------------------+
默认情况下创建的视图和基本表的字段是一样的,也可以通过指定视图字段的名称来创建视图。
在t表格上创建一个名为view_t2的视图,代码如下:
create view view_t2 (qty, price, total) as
select quantity, price, quantity * price
from t;
语句执行成功后,查看view_t2视图中的数据:
select * from view_t2;
+-----+-------+-------+
| qty | price | total |
+-----+-------+-------+
| 3 | 50 | 150 |
+-----+-------+-------+
可以看到,view_t2和view_t两个视图中的字段名称不同,但数据却是相同的。因此,在使用视图的时候,可能用户根本就不需要了解基本表的结构,更接触不到实际表中的数据,从而保证了数据库的安全。
2.3、在多表上创建视图
MySQL中也可以在两个或者两个以上的表上创建视图,可以使用CREATE VIEW语句实现。
在表student和表stu_info上创建视图stu_glass,代码如下:
首先向两个表中插入数据,输入语句如下:
insert into student values
(1, 'wanglin1'),
(2, 'gaoli'),
(3, 'zhanghai');
insert into stu_info values
(1, 'wuban', 'henan'),
(2, 'liuban', 'hebei'),
(3, 'aiban', 'shangdong');
创建视图stu_glass,语句如下:
create view stu_glass(id, name, glass) as
select student.s_id, student.name, stu_info.glass
from student, stu_info
where student.s_id = stu_info.s_id;
select * from stu_glass;
+----+----------+--------+
| id | name | glass |
+----+----------+--------+
| 1 | wanglin1 | wuban |
| 2 | gaoli | liuban |
| 3 | zhanghai | aiban |
+----+----------+--------+
这个例子就解决了刚开始提出的那个问题,通过这个视图可以很好地保护基本表中的数据。这个视图中的信息很简单,只包含了id、姓名和班级,id字段对应student表中的s_id字段,name字段对应student表中的name字段,glass字段对应stu_info表中的glass字段。
3、查看视图
查看视图是查看数据库中已存在的视图的定义。查看视图必须要有SHOW VIEW的权限,MySQL数据库下的user表中保存着这个信息。
查看视图的方法包括:
- DESCRIBE
- SHOW TABLE STATUS
- SHOW CREATEVIEW
3.1、使用DESCRIBE语句查看视图基本信息
DESCRIBE可以用来查看视图,具体的语法如下:
DESCRIBE 视图名;
通过DESCRIBE语句查看视图view_t的定义,代码如下:
describe view_t;
+------------------+--------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------------+--------+------+-----+---------+-------+
| quantity | int | YES | | <null> | |
| price | int | YES | | <null> | |
| quantity * price | bigint | YES | | <null> | |
+------------------+--------+------+-----+---------+-------+
结果显示出了视图的字段定义、字段的数据类型、是否为空、是否为主/外键、默认值和额外信息。
DESCRIBE一般情况下都简写成DESC,输入这个命令的执行结果和输入DESCRIBE的执行结果是一样的。
3.2、使用SHOW TABLE STATUS语句查看视图基本信息
查看视图的信息可以通过SHOW TABLESTATUS的方法完成,具体的语法如下:
SHOW TABLE STATUS LIKE '视图名';
使用SHOW TABLE STATUS命令查看视图信息,代码如下:
show table status like 'view_t' \G;
***************************[ 1. row ]***************************
Name | view_t
Engine | <null>
Version | <null>
Row_format | <null>
Rows | <null>
Avg_row_length | <null>
Data_length | <null>
Max_data_length | <null>
Index_length | <null>
Data_free | <null>
Auto_increment | <null>
Create_time | 2026-06-25 20:29:37
Update_time | <null>
Check_time | <null>
Collation | <null>
Checksum | <null>
Create_options | <null>
Comment | VIEW
执行结果显示,表的说明Comment的值为VIEW,说明该表为视图,其他的信息为NULL,说明这是一个虚表。用同样的语句来查看一下数据表t的信息,执行结果如下:
show table status like 't' \G;
***************************[ 1. row ]***************************
Name | t
Engine | InnoDB
Version | 10
Row_format | Dynamic
Rows | 1
Avg_row_length | 16384
Data_length | 16384
Max_data_length | 0
Index_length | 0
Data_free | 55574528
Auto_increment | <null>
Create_time | 2026-06-25 20:28:22
Update_time | 2026-06-25 20:28:22
Check_time | <null>
Collation | utf8mb3_general_ci
Checksum | <null>
Create_options |
Comment |
从查询的结果来看,这里的信息包含了存储引擎、创建时间等,Comment信息为空,这就是视图和表的区别。
3.3、使用SHOW CREATE VIEW语句查看视图详细信息
使用SHOW CREATE VIEW语句可以查看视图详细定义,语法如下:
SHOW CREATE VIEW 视图名;
使用SHOW CREATE VIEW查看视图的详细定义,代码如下:
show create view view_t \G;
***************************[ 1. row ]***************************
View | view_t
Create View | CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`%` SQL SECURITY DEFINER VIEW `view_t` AS select `t`.`quantity` AS `quantity`,`t`.`price` AS `price`,(`t`.`quantity` * `t`.`price`) AS `quantity * price` from `t`
character_set_client | utf8mb4
collation_connection | utf8mb4_0900_ai_ci
执行结果显示视图的名称、创建视图的语句等信息。
3.4、在views表中查看视图详细信息
在MySQL中,information_schema数据库下的views表中存储了所有视图的定义。通过对views表的查询,可以查看数据库中所有视图的详细信息,查询语句如下:
select * from information_schema.views \G;
4、修改视图
修改视图是指修改数据库中存在的视图,当基本表的某些字段发生变化的时候,可以通过修改视图来保持与基本表的一致性。
MySQL中通过CREATE OR REPLACE VIEW语句和ALTER语句来修改视图。
4.1、使用CREATE OR REPLACE VIEW语句修改视图
在MySQL中修改视图,可使用CREATE ORREPLACE VIEW语句,语法如下:
CREATE [OR REPLACE] [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
VIEW view_name [(column_list)]
as select_statement
[WITH [CASCADED | LOCAL] CHECK OPTION]
可以看到,修改视图的语句和创建视图的语句是完全一样的。当视图已经存在时,修改语句对视图进行修改;当视图不存在时,创建视图。下面通过一个实例来说明。
修改视图view_t,代码如下:
create or replace view view_t as
select * from t;
首先通过DESC查看一下更改之前的视图,以便与更改之后的视图进行对比。执行的结果如下:
desc view_t;
+----------+------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+------+------+-----+---------+-------+
| quantity | int | YES | | <null> | |
| price | int | YES | | <null> | |
+----------+------+------+-----+---------+-------+
从执行的结果来看,相比原来的视图view_t,新的视图view_t少了1个字段。
4.2、使用ALTER语句修改视图
ALTER语句是MySQL提供的另外一种修改视图的方法,语法如下:
ALTER [ALGORITHM = {UNDEFINED | MERGE | TEMPTABLE}]
VIEW view_name [(column_list)]
as select_statement
[WITH [CASCADED | LOCAL] CHECK OPTION]
这个语法中的关键字和前面视图的关键字是一样的,这里就不再介绍了。
使用ALTER语句修改视图view_t,代码如下:
alter view view_t as
select quantity
from t;
执行结果如下:
desc view_t;
+----------+------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+------+------+-----+---------+-------+
| quantity | int | YES | | <null> | |
+----------+------+------+-----+---------+-------+
通过ALTER语句同样可以达到修改视图view_t的目的,从上面的执行过程来看,视图view_t只剩下一个quantity字段,修改成功。
5、更新视图
更新视图是指通过视图来插入、更新、删除表中的数据,因为视图是一个虚拟表,其中没有数据。通过视图更新的时候都是转到基本表上进行更新的,如果对视图增加或者删除记录,实际上是对其基本表增加或者删除记录。
视图更新的3种方法:
- INSERT
- UPDATE
- DELETE
使用UPDATE语句更新视图view_t,代码如下:
update view_t set quantity = 5;
查看视图更新之后,基本表的内容如下:
select * from t;
+----------+-------+
| quantity | price |
+----------+-------+
| 5 | 50 |
+----------+-------+
select * from view_t;
+----------+
| quantity |
+----------+
| 5 |
+----------+
select * from view_t2;
+-----+-------+-------+
| qty | price | total |
+-----+-------+-------+
| 5 | 50 | 250 |
+-----+-------+-------+
对视图view_t更新后,基本表t的内容也更新了,同样当对基本表t更新后,另外一个视图view_t2中的内容也会更新。
使用INSERT语句在基本表t中插入一条记录,代码如下:
insert into t values(3, 5);
执行结果如下:
select * from t;
+----------+-------+
| quantity | price |
+----------+-------+
| 5 | 50 |
| 3 | 5 |
+----------+-------+
select * from view_t2;
+-----+-------+-------+
| qty | price | total |
+-----+-------+-------+
| 5 | 50 | 250 |
| 3 | 5 | 15 |
+-----+-------+-------+
向表t中插入一条记录,通过SELECT查看表t和视图view_t2,可以看到其中的内容也跟着更新,视图更新的不仅仅是数量和单价,总价也会更新。
使用DELETE语句删除视图view_t2中的一条记录,代码如下:
delete from view_t2
where price = 5;
执行结果如下:
select * from t;
+----------+-------+
| quantity | price |
+----------+-------+
| 5 | 50 |
+----------+-------+
select * from view_t2;
+-----+-------+-------+
| qty | price | total |
+-----+-------+-------+
| 5 | 50 | 250 |
+-----+-------+-------+
在视图view_t2中删除price=5的记录,视图中的删除操作最终是通过删除基本表中相关的记录实现的,查看删除操作之后的表t和视图view_t2,可以看到通过视图删除其所依赖的基本表中的数据。
当视图中包含有如下内容时,视图的更新操作将不能被执行:
- 视图中不包含基表中被定义为非空的列。
- 在定义视图的SELECT语句后的字段列表中使用了数学表达式。
- 在定义视图的SELECT语句后的字段列表中使用聚合函数。
- 在定义视图的SELECT语句中使用了DISTINCT、UNION、TOP、GROUP BY或HAVING子句。
6、删除视图
当视图不再需要时,可以将其删除。删除一个或多个视图可以使用DROP VIEW语句,语法如下:
DROP VIEW [IF EXISTS]
view_name [, view_name] ...
[RESTRICT | CASADE]
view_name是要删除的视图名称,可以添加多个需要删除的视图名称,各个名称之间使用逗号分隔开。删除视图必须拥有DROP权限。
删除stu_glass视图,代码如下:
drop view if exists stu_glass;
如果名称为stu_glass的视图存在,那么该视图将被删除。使用SHOW CREATE VIEW语句查看操作结果:
show create view stu_glass;
(1146, "Table 'test_db.stu_glass' doesn't exist")
可以看到,stu_glass视图已经不存在,删除成功。
7、常见问题
7.1、两者的区别
- 视图是已经编译好的SQL语句,是基于SQL语句结果集的可视化表,而表不是。
- 视图没有实际的物理记录,而表有。
- 表是内容,视图是窗口。
- 表占用物理空间,而视图不占用物理空间。视图只是逻辑概念的存在,表可以及时修改,但视图只能用创建的语句来修改。
- 视图是查看数据表的一种方法,可以查询数据表中某些字段构成的数据,只是一些SQL语句的集合。从安全的角度来说,视图可以防止用户接触数据表,因而用户不知道表结构。
- 表属于全局模式中的表,是实表;视图属于局部模式的表,是虚表。
- 视图的建立和删除只影响视图本身,不影响对应的基本表。
7.2、两者的联系
视图(view)是在基本表之上建立的表,它的结构(所定义的列)和内容(所有记录)都来自基本表,它依据基本表存在而存在。一个视图可以对应一个基本表,也可以对应多个基本表。视图是基本表的抽象和在逻辑意义上建立的新关系。

4098

被折叠的 条评论
为什么被折叠?



