mysql 提供了一种视图表,本质上是虚拟表非物理表(实表),视图通常为一个或多个表的查询结果集,视图有以下几个特点: (1)视图是由一个或多个基本表(实表)产生的表(虚表) (2)视图的建立与删除不会影响基本表(实表) (3)对视图内容更新(添加,删除和修改)直接影响基本表(只涉及到一张表中的字段时) (4)当视图来自多个基本表时,不允许添加删除和修改数据(涉及到多表中字段时) 常用视图语法 #创建视图的语法: create view view_name as (select 语句) #删除视图的语法 drop view if exists view_name; #修改视图语法 alter view view_name as (select 语句) 实际开发中通常用视图存放一下临时数据,用完就会把视图删除。目的是解决复杂的sql,通常使用写法: drop view if exists view_name; create view view_name as (select 语句);
接下在根据视图的主要特点 3和4 写一下案例: 基础数据: 表名:mh_a 表名:mh_b 创建视图: DROP VIEW IF EXISTS a; CREATE VIEW a AS( SELECT a.name,b.work FROM mh_a a JOIN mh_b b ON a.id = b.id ) 查看一下视图中的数据: SELECT * FROM a 特点3:对视图内容更新(添加,删除和修改)直接影响基本表(只涉及到一张表中的字段) UPDATE a SET a.name=‘张三’ WHERE a.name=‘zhangsan’ 更新完后查看视图数据: SELECT * FROM a 然后再查看name字段对应的基本表(实表mh_a) 然后我们再删除视图中的数据: DELETE FROM a WHERE a.name=‘张三’ 执行这个语句的时候 会报错: Can not delete from join view ‘mh615.a’,因为在删除的时候涉及到了多张表的字段,所以不行,我们把视图改一下只涉及到一张表:
DROP VIEW IF EXISTS a; CREATE VIEW a AS( SELECT NAME FROM mh_a ) SELECT * FROM a 然后再次执行删除语句: DELETE FROM a WHERE a.name=‘张三’ #执行成功 查看视图数据 SELECT * FROM a 再查看删除数据的字段对应的实表(mh_a) select * from mh_a 对应name=‘张三’ 的数据已经被删除了
添加(把视图改为原来) DROP VIEW IF EXISTS a; CREATE VIEW a AS( SELECT a.name,b.work FROM mh_a a JOIN mh_b b ON a.id = b.id ) select * from a 添加 INSERT INTO a (NAME) VALUES(‘xin_zeng’) 查看 select * from a 然后再查看 name字段对应的实表 mh_a select * from mh_a 基础表(实表)新增了一条数据。
特点4:当视图来自多个基本表时,不允许添加删除和修改数据(涉及到多表中字段时) 创建视图: DROP VIEW IF EXISTS a; CREATE VIEW a AS( SELECT a.name,b.work FROM mh_a a JOIN mh_b b ON a.id = b.id ) select * from a 删除: DELETE FROM a WHERE a.name=‘lisi’ 报错: 更新: UPDATE a SET a.name=‘李四’ ,a.work=‘huajia’ WHERE a.name=‘lisi’ 报错: 插入: INSERT INTO a (NAME,WORK) VALUES(‘lisi’,‘huajia’) 报错: 上面是关于视图的特点学习和研究,接下来关于视图的创建和删除的研究学习
(1)视图正在被使用时,能不能被删除。 准备数据 user表中存在 11010000条数据 SELECT COUNT(0) FROM USER 创建视图并使用: drop view if exists a; create view a as (select * from user); select * from a 同时删除正在使用的视图 drop view a 使用时间(先执行创建视图并使用的sql,然后紧跟着执行删除视图的sql) 通过好多遍的测试,永远都是 当视图正在被使用时不能立刻被删除。
(2)视图创建所需要的Time: create view a as (select * from user) OK 时间: 0.006s 也就是说创建视图我们可以把它理解成创建了一个公共sql :a = “select * from user” 我们可以在sql中引用a 就相当于我们写了 select * from user 这条sql ,创建视图不会立刻获取里面的数据。
视图的生命周期: 用Navicat 建立连接创建视图: create view a as (select * from user); 用SQLyog 建立连接使用视图 SELECT COUNT(0) FROM a 说明视图的生命周期是全局性的。一旦创建可以全局使用,类似于我们创建了一张表。不过这张表是虚拟表。 总结:视图可以理解为一张虚拟表,也可以理解为一条公共的sql定义。同时要掌握视图的主要特点。如果视图已经存在我们不能再次创建同一名称的视图。 开发经验总结:视图尽量提前创建好,在创建视图不能使用:Create view if not exist官网给出的解决方案是:Create or Replace View ,但是这个原理也是先删除后替换。这种方式会影响并发的性能,因为在删除视图时需要等待当前视图使用被完成才能删除(视图被当前执行的sql占用着),所以存在大量的等待时间,然后再创建然后再删除时再等待,为了避免这种情况的,我们在开发时通常会这样 drop view if exists random_view ; create view random_view as (select 语句) ; 使用该视图(当前执行的sql中使用该视图) drop view if exists random_view ; random_view: 代表一个随机不重复的名称,这样就可以把视图看做一个临时的局部的视图,这样就解决了等待的问题,同时也可以把全局性的视图生命周期看成局部的临时的用完(只会被我当前的执行sql自己使用)就删掉。random_view通常取: 时间戳(建议纳秒)加一英文字母就可以,这种情况通常与java代码联合使用,使用java代码获取随机唯一做 random_view 。