# 视图介绍 1). 视图(View)是一种虚拟存在的表。 2). 视图并不在数据库中实际存在,行和列数据来自定义视图的查询中使用的表,并且是在使用视图时动态生成的。(视图只保存sql的逻辑,不保存表数据) 3). 通俗的讲,视图就是一条SELECT语句执行后返回的结果集。所以我们在创建视图的时候,主要的工作就落在创建这条SQL查询语句上。 # 举个例子 普通班级: 张三 李四 王五 马六... 表 奥赛班(虚拟,临时,用的时候才有的): 数据来源班级 -> 张三 王五... 视图 奥赛班 : 查询普通班级而诞生
# 视图的优缺点 1. 优点 1). 简单化: 数据所见即所得 使用视图的用户完全不需要关心后面对应的表的结构、关联条件和筛选条件,对用户来说已经是过滤好的复合条件的结果集 2). 安全性:用户只能查询或修改他们所能见到得到的数据 使用视图的用户只能访问他们被允许查询的结果集,对表的权限管理并不能具体限制到某个行某个列,但是通过视图就可以简单的实现 3). 逻辑独立性: 可以屏蔽真实表结构变化带来的影响 一旦视图的结构确定了,可以屏蔽表结构变化对用户的影响,源表增加列对视图没有影响;源表修改列名,则可以通过修改视图来解决,不会造成对访问者的影响 2. 缺点: 1). 性能较差 视图是在使用过程中动态生成的,所以查询比较慢 2). 增删改不方便 当用户试图修改视图的某些行时,数据库软件必须把它转化为对基本表的某些行的修改。对于简单视图来说,这是很方便的,但是,对于比较复杂的视图,可能修改不了。 3. 总得来说, 视图比普通查询要慢一些, 以牺牲性能为代价,提高数据的安全性和代码的复用性 # 视图的应用场景 1. 多个地方用到同样的查询结果 此时使用视图, 可以简化sql查询,提高开发效率 2. 安全性需要 如果源表中部分数据需要对外保密, 那么可以使用视图屏蔽这些数据 合理利用视图则可以减少很多授权工作和保证数据安全性
-- 准备数据 -- 创建contry表 create table country( id int primary key auto_increment, name varchar(20) ); -- 添加数据 insert into country values(null,'中国'),(null,'美国'),(null,'俄罗斯'); -- 创建city表 create table city( id int primary key auto_increment, name varchar(30), cid int, constraint cc_fk01 foreign key (cid) references country(id) ); -- 添加数据 insert into city values(null,'北京',1),(null,'上海',1),(null,'纽约',2),(null,'莫斯科',3);
查询准备好的数据如下:
mysql> select * from country; +----+-----------+ | id | name | +----+-----------+ | 1 | 中国 | | 2 | 美国 | | 3 | 俄罗斯 | +----+-----------+ rows in set (0.00 sec) mysql> select * from city; +----+-----------+------+ | id | name | cid | +----+-----------+------+ | 1 | 北京 | 1 | | 2 | 上海 | 1 | | 3 | 纽约 | 2 | | 4 | 莫斯科 | 3 | +----+-----------+------+ rows in set (0.00 sec) mysql>
# 视图创建 /* create [or replace] view 视图名称[(列名列表)] as 查询语句 */ -- 创建city_country视图,保存城市和国家的信息 -- 注意: 创建视图的多张表中存在同名字段,那么视图必须取列名 create or replace view city_country(city_id,city_name,country_name) as select c1.id,c1.name,c2.name from city c1, country c2 where c1.cid = c2.id;
执行如下:
image-20210213101959946# 视图查询 /* select * from 视图名称; -- 查看视图数据 show tables; -- 查看表,如果有视图, 也显示视图 show create view 视图名; -- 查看视图的定义 */ -- 查询视图数据 select * from city_country; -- 查看表 和 视图 show tables; -- 查看视图的创建信息 show create view city_country;
# 视图修改 /* update 视图名称 set 列名=值 where 条件; -- 注意 : 修改视图数据后,源表数据也会随之修改 */ -- 修改视图数据,将city_id为1的城市修改成深圳 update city_country set city_name='深圳' where city_id = 1;
# 视图删除 /* drop view [if exists] 视图名称 */ drop view if exists city_country;
/* # 扩展: 视图在很多情况下,是无法更新的, 所以视图一般用来查询, 推荐增删改操作 例如: group by 分组查询 就无法修改 */ -- 1. 创建视图: 国家id,国家name和对应的城市数量 create or replace view country_citynumber(country_id,country_name,city_number) as select c2.id,c2.name,count(*) from city c1, country c2 where c1.cid = c2.id group by c2.id; -- 2. 查询此视图数据 select * from country_citynumber; -- 执行如下: mysql> select * from country_citynumber; +------------+--------------+-------------+ | country_id | country_name | city_number | +------------+--------------+-------------+ | 1 | 中国 | 2 | | 2 | 美国 | 1 | | 3 | 俄罗斯 | 1 | +------------+--------------+-------------+ rows in set (0.00 sec) -- 3. 修改国家id=2的国家名字 -- 错误代码:1288 -- The target table country_citynumber of the UPDATE is not updatable update country_citynumber set contry_name = '英国' where country_id = 2; -- 执行如下: mysql> update country_citynumber set contry_name = '英国' where country_id = 2; ERROR 1288 (HY000): The target table country_citynumber of the UPDATE is not updatable