物化视图不能直接替代触发器做增量同步,但Oracle等支持FAST REFRESH的数据库可构建更稳定轻量的同步链路;PostgreSQL因无原生增量刷新能力,强行使用会导致伪增量或丧失一致性。
物化视图能替代触发器做增量同步吗
不能直接替代,但可以构建更稳定的轻量级同步链路——前提是数据库支持原生物化视图(materialized view)且启用快速刷新(fast refresh)。postgresql 没有原生 materialized view 增量刷新能力,oracle 和 oracle 兼容的数据库(如 oceanbase、opengauss 3.1+)才真正支持基于日志或物化日志(mvlog)的 fast refresh on commit。用 mview 替换触发器,本质是把“行级变更捕获+应用”从应用/触发器逻辑下沉到存储层,降低侵入性和维护成本。
Oracle 中创建可增量刷新的 MVIEW 关键条件
不是建完就能 REFRESH FAST,漏掉任一前提都会退化为全量刷新(COMPLETE),失去增量意义:
- 基表必须有
PRIMARY KEY或ROWID,且不能是JOIN多表无主键关联 - 必须提前创建物化视图日志:
CREATE MATERIALIZED VIEW LOG ONyour_tableWITH PRIMARY KEY, ROWID, SEQUENCE (col1, col2) INCLUDING NEW VALUES; -
SELECT列不能含SYSDATE、ROWNUM、分析函数、子查询(除非满足复杂性限制) - 刷新方式必须显式指定:
REFRESH FAST ON COMMIT或ON DEMAND;默认是COMPLETE
常见错误现象:ORA-12052: cannot fast refresh materialized view —— 通常就是日志缺失、主键不一致或 SQL 写法越界。
和触发器比,MVIEW 同步的延迟与一致性边界
触发器是强同步(事务内完成),MVIEW 是弱同步(依赖刷新时机),但更可控:
-
ON COMMIT模式下,刷新在事务提交后立即触发,延迟毫秒级,但会增加提交开销; -
ON DEMAND+ 定时DBMS_MVIEW.REFRESH更轻量,但延迟取决于调度粒度(如每分钟一次); - 触发器易因异常中断导致数据不一致,而
MVIEW刷新失败会报错并阻塞后续刷新,问题暴露更早; - 触发器修改目标表时可能引发递归调用或死锁,
MVIEW刷新走独立执行路径,无此风险。
性能影响集中在刷新时刻:一次 FAST REFRESH 只扫变更 delta(通过 MLOG$ 表),而触发器每次 DML 都要执行逻辑 —— 高频小更新场景下,MVIEW 实际负载更低。
PostgreSQL 用户别硬套 MVIEW 方案
PG 的 REFRESH MATERIALIZED VIEW 是全量重算,没有 FAST 选项。强行用它做“增量同步”,实际是伪增量:
- 若用
CONCURRENTLY,需加唯一索引,且刷新期间无法写入目标表; - 若靠应用层记录 last_updated 时间戳 + WHERE 过滤,就又退化成手动触发器逻辑,还丢了事务一致性;
- 真要轻量同步,应优先考虑
logical replication(发布/订阅)或pg_recvlogical解析 WAL,而不是模拟 Oracle 的MVIEW流程。
最容易被忽略的一点:MVIEW 不是银弹,它把同步复杂度从代码移到了数据库配置和运维上——日志空间膨胀、刷新锁表、基表结构变更后需重建日志,这些都得持续盯。










