MySQL 视图
1. 视图简介
2. 视图使用
1. 视图简介
视图与表(有时为与视图区别,也称表为基本表——Base Table)不同,视图是虚拟的表,即视图所对应的数据并不进行实际存储,数据库中只存储视图的定义,也就是说视图本身没有数据,只是通过执行相应的 select 语句获得相应的数据。
优点
- 重用性:视图就像是函数,那些被经常使用的查询可以被定义为视图,从而使得用户不必为以后的操作每次指定全部的条件。
-
简单性:看到的就是需要的。用户不必理解查询细节。
-
安全性:可以对不同的用户,设定不同的视图。且用户只能以只读视图检索数据,但无法更新。
-
独立性:更改数据格式和表示。视图可返回与基本表的表示和格式不同的数据。
- 重构性:数据库视图可以实现向后兼容。假设我们有一个中央数据库,许多应用程序正在使用它。有一天,我们决定重新设计数据库以适应新的业务需求,希望删除一些表并创建新的表,并且不希望更改影响其他应用程序。在这种情况下,就可以创建与将要删除的旧表相同的模式的数据库视图。
缺点
- 视图不是一种物化视图,它相当于一个虚拟表,本身并不存储数据,视图的所有数据都是从其他表中查出来的。这带来的问题是,使用视图并不能直接将常用数据分离出来(只是查询展示出来)从而优化查询速度。
- 操作视图的很多命令都与普通表一样,这会导致在业务代码中无法通过 SQL 区分表和视图,使代码变得复杂。
- 实现视图的算法有两种,分别为合并算法和临时表算法:
- 合并算法是指查询视图时将视图定义的 SQL 合并到查询 SQL 中,比如 create view v1 as select * from user where sex=m; 当我们要查询视图时,会将 select id,name from v1; 合并成 select id,name from user where sex=m……;
- 临时表算法是先将视图查出来的数据保存到一个临时表中,查询的时候查这个临时表。
- 不管是合并算法和临时表算法都会带来额外的开销,而且使用临时表后会使 MySQL 的优化变得很困难,比如索引。
- 当然,视图在某些情况下可以帮助提升性能,但视图的性能很难预测。且在 MySQL 的优化器中,视图的代码执行路径也完全不同,无法直观的预测其执行性能。
视图的使用场景
- 在 Web+MySQL 设计中,由于追求高伸缩性,不依赖于数据库本身实现,一般不使用视图来做数据查询,而是 Web 程序拼好 SQL 字符串,让数据库执行。这样将业务逻辑写在程序代码中,方便调试、修改、分布式运行。
- 在 Web+MySQL 设计中,如果支持多种数据库,这个是由 ORM 或类似 mybatis 配置来实现的,这样不用每个数据库写一个视图查询,做到了低耦合。低耦合,也就是不和具体数据库绑死。
- 视图可以作为镜像表,如 a 数据库镜像 b 数据库中的表,可以在这个视图中进行增删改查,这个功能在一些系统设计中是有用的,如我在 b 数据库中做开发,可以镜像 a 数据库中的表过来,不用每次手工同步,在上线时直接指向 a 数据库即可。
- 如果你做一些数据分析或数据仓库查询,可以使用视图,这样不用写程序和写 SQL 来实现。有的管理工具有视图创建工具,可以做可视化设计,提高工作效率。
视图的使用规则
- 与表名一样,视图必须唯一命名。
- 可创建的视图数目没有限制。
- 为了创建视图必须有足够的权限。
- 视图可以嵌套,即可以使用其它视图来构造一个视图。
- ORDER BY 可以用在视图中,但如果从该视图检索数据的 SELECT 语句中也含有 ORDER BY,那么视图中的 ORDER BY 将被覆盖。
- 视图无法创建索引,也不能有关联的触发器或默认值。
- 视图可以和表一起使用。
2. 视图使用
创建视图
CREATE VIEW v_ecs_order_info AS SELECT order_id, order_sn, order_amount, consignee FROM ecs_order_info;
-- 使用视图来查询数据
select * from v_ecs_order_info;
查看视图
show table status where comment='view'; -- 查看现有的视图及其信息
删除视图
DROP VIEW v_ecs_order_info;
更新视图
--方式1:先用 DROP 删除视图,再用 CREATE 创建视图。
--方式2:使用 CREATE OR REPLACE VIEW -- 如果要更新的视图不存在则会创建一个视图,若存在则会替换原来的视图 CREATE OR REPLACE VIEW v_ecs_order_info AS SELECT order_id, order_sn, order_amount, pay_status, consignee FROM ecs_order_info;
-- 方式3:使用 ALTER ALTER VIEW v_ecs_order_info AS SELECT order_id, order_sn, order_amount, pay_status, consignee FROM ecs_order_info;