物化视图

年前项目中跟一个Domain的数据查询数据没及时刷新的问题。后来就考虑使用物化视图,然后每天刷新两次来保持同步。这里整理下。


视图

视图是指计算机数据库中的视图,是一个虚拟表,其内容由查询定。比如下边代码就是创建一个视图,然后每次查询都直接基于视图,查询语句也会简单化。

CREATE VIEW view_name AS
SELECT column_name(s)
FROM table_name
WHERE condition

优点:
1. 减少程序中的SQL。复杂的查询可以被限定在数据库内部,对使用者透明。

2. 安全。可以通过视图授权给不同用户,而且多个表关联只允许查看,不允许修改。(单表可以设置WITH READ ONLY)。


物化视图

我们知道,普通视图是虚拟表,只有结构没有数据。而基于视图的查询,最后都是变成SQL的查询。因此在SQL性能优化中,我们都只能是优化SQL语句。
物化视图(material view)其实是一个物理表,能存储数据,因此在一些复杂或者费时的查询中,利用它可以加快查询速度。

简单来说,物化视图就是一个查询结果的数据库对象,是一些查询结果的副本,或者说快照。然后在这个副本上进行查询,速度会快一些。

创建一个简单物化视图:

CREATE MATERIALIZED VIEW MY_MATERIALIZED_VIEW AS SELECT * FROM MY_TABLE;

然后就可以基于上边这个物化视图进行查询。

SELECT * FROM  MY_MATERIALIZED_VIEW;

然后执行下边的SQL,发现已经是我们的视图了。

SELECT * FROM USER_MVIEWS WHERE mview_name = 'MY_MATERIALIZED_VIEW';

在执行下边的SQL,就会发现物化视图也是个物理表

SELECT t.TABLE_NAME, t.* FROM USER_TABLES t where t.TABLE_NAME = 'MY_MATERIALIZED_VIEW';

现在我们向原始表插入数据,然后分别在原始表和物化视图上查询:

SELECT * FROM  MY_MATERIALIZED_VIEW;
SELECT * FROM MY_TABLE;

此时就会发现:物化视图查到的数据比原始表查到的数据少了最新的一条。也就是说:物化视图保留了查询结果的副本。原始表的更新没有同步到物化视图中。

现在,通过以下SQL在物化视图上执行更新:

UPDATE SPSI_CMS_CHANGE_MONITOR_VIEW SET REC_UPD_DT = SYSDATE -3 ;

此时会出现以下错误:

SQL Error: ORA-01732: data manipulation operation not legal on this view
01732. 00000 -  "data manipulation operation not legal on this view"
*Cause:    

*Action:

也就是说,物化视图是查询结果的只读副本

语法

先看下创建物化视图的语法,不过在这之前,要给当前用户赋予创建物化视图的权限:

GRANT CREATE MATERIALIZED VIEW TO user_name; 
此时就可以利用这个用户创建物化视图了。

创建语法如下:

CREATE MATERIALIZED VIEW mv_name [选项n] AS SELECT * FROM table_name;

[选项n]是参数,解释如下:

选项解释
BUILD [immediate,deferred]是否在创建视图时生成数据,默认生成。deferred为不生成数据,然后在需要的时候生成。
refresh [fast|complete|force|never]fast是增量刷新,或者叫快速刷新;
complete为全表刷新;
force为如果增量刷新可以使用则使用增量刷新,否则全表刷新;
never则是不进行刷新(不使用)
on [demand,commit]即手工刷新和提交时刷新。commit表示自动刷新,原表有数据提交就刷新。
start with varDate next varDate2通知数据库完成从主表到本地表第一次复制的时间为varDate。
指明了刷新的时间间隔。时间间隔 = 下次刷新的时间 -上次执行完成的时间
with 例如:with rowid 创建基于rowid的物化视图,对应的是 primary key

知道语法了,我们将上边的刷设置为自动刷新,在这之前,先打开SQL/Plus将物化视图刷新:

dbms_mview.REFRESH(TAB=>'SPSI_CMS_CHANGE_MONITOR_VIEW', 'complete');

否则会因为数据不一致报以下错误:

32337. 00000 -  "cannot alter materialized view with pending changes refresh on commit"
*Cause:    There are some pending changes in the detail tables
*Action:   Execute an on-demand refresh on the materialized view to
           synchronize the data between the materialized view and the detail
           tables and then issue an ALTER MATERIALIZED VIEW statement.

刷新了物化视图的数据后,修改为每天自动刷新:

ALTER MATERIALIZED VIEW MY_MATERIALIZED_VIEW REFRESH FORCE ON DEMAND START WITH SYSDATE NEXT SYSDATE +1 ;

特征

我们知道,在表上边是可以建索引的。同样,物化视图上边也可以建索引,语法与在表上创建索引相同。

CREATE UNIQUE INDEX MY_MATERIALIZED_VIEW_INDEX ON MY_MATERIALIZED_VIEW (UPDATE_IODT) ;

删除

物化视图也可以被删除,不过与表有点不一样。我在表上右键选择‘drop’时,不能删除物化视图。只能用SQL删除:

DROP MATERIALIZED VIEW MY_MATERIALIZED_VIEW;













  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值