数据库关于物化视图的思考
昨天代码提交之后,今天没什么任务, 我就看下代码是否有疏漏,有什么问题的地方,看着看着就看到之前写数据库对应dto时遇到的问题。
公司数据库表里发现表A含有表B和表C中相关的几个字段。按照数据库设计规范来说,表A中如果出现表B的多个字段,这样是违反第三范式的,这样会增加数据库内存的消耗,尤其是一旦数据量很大,内存影响还是会存在的。
我曾在德国某公司实习的时候,leader告诉我,虽然要遵守数据库设计规范,但是有些情况下,却是不得不打破这些范式,比如需要用空间来换时间的时候。
牺牲空间来换时间,这个在做算法的时候经常会用到,只要牺牲空间在合理的范围下,争取到大量的时间来平衡,还是算的上不错的优化的。
说到公司的数据库某几张表的设计,就上述提到的那个问题,我去查了一圈,问了一圈,(因为这本是可以用视图来解决的问题),发现普通的视图其实跟建立几张表的连接关系语句去查询是基本一样的时间消耗。
后来问到有物化视图这一存在,oracle本身也是支持物化视图的,那什么是物化视图呢?物化视图的优点和缺点又有什么呢?
MView中文名称为物化视图(Materialized View),相对于普通视图来说,MView的不同之处在于MView的结果会保存在一个普通的数据表中,在对MView进行查询的时候不再会对创建 MView的基表进行查询,而是直接查询MView对应的结果表,然后通过定期的刷新机制来更新MView表中的数据。
这样一来物化视图的优点就很直观了,查询速度相对于普通视图就会大大提升。
当然,按照其定义的,数据存储下来的话,就会和普通表一样占用很大的存储空间了。
事物的存在必有其道理。那这样的话相对于普通表来说,物化视图又有什么优点呢?
1.物化视图有视图的优点,视图可以简化用户的操作,可以隐藏数据表之间的关系(引申出来能够对机密数据提供安全保护),可以对重构数据库提供一定的逻辑独立性等等,具体可参考
http://blog.csdn.net/fm0517/article/details/5625949
2.既然是视图,那就是一条查询语句,这样的话就可以查询出部分的数据,如select top 1000,这样就不需要将全部的数据存储下来,稍微减轻了物化的缺点(此条为为自己考虑到的情况,并未尝试过)
3.既然是会存储数据,那也可以用作数据库复制了
以上是我自己所能理解的,以下为查到的补充:
下面列举了MView在实际中的主要作用:
- 减轻网络负担:通过MV将数据从一个数据库分发到多个不同的数据库上,通过对多个数据库访问来减轻对单个数据库的网络负担。
- 搭建分发环境:通过从一个中央数据库将数据分发到多个节点数据库,达到分发数据的目的。
- 复制数据子集:MV可以进行行级/列级的筛选,这样可以复制需要的那一部分数据。
- 支持离线计算:MV不需要专用的数据库连接,用户可以按照自己的需求来复制所需要的那一部分数据。
MView的刷新:
Oracle支持三种刷新方式,1.完全刷新 2.快速刷新 3.强制刷新
1.完全刷新:将MView的数据全部删除,再根据创建MView时候的查询生成数据插入到MView
2.快速刷新:只刷新上次刷新以来修改的数据,很快(需要建立MView Log)
3.强制刷新:当快速刷新无法进行的时候,系统会进行完全刷新,二者结合就是强制刷新
刷新语句:
exec dbms_mview.refresh('mvt', 'F') ; F为fast C为complete,还有一个Force是默认的
刷新MView:
创建job来刷新, 在创建MView的时候指定REFRESH语句 start with:第一次刷新时间,Next:刷新时间间隔
MView的必要组成部分:
1.基表
2.隐藏的MView对象
3.MView表
4.基表的Index
5.MView的Index
对于需要快速刷新的MView:
6.MView Log
7.维护MLog$_的内部触发器