1. 程式人生 > >Oracle 10g通過建立物化檢視實現不同資料庫間表級別的資料同步

Oracle 10g通過建立物化檢視實現不同資料庫間表級別的資料同步

Oracle 10g 物化檢視語法如下:

create materialized view [view_name]
refresh [fast|complete|force]
[
on [commit|demand] |
start with (start_time) next (next_time)
]
as
{建立物化檢視用的查詢語句}

以上是Oracle建立物化檢視(Materialized View,以下簡稱MV)時的常用語法,各引數的含義如下:

  1. refresh [fast|complete|force] 檢視重新整理的方式:

    fast: 增量重新整理.假設前一次重新整理的時間為t1,那麼使用fast模式重新整理物化檢視時,只向檢視中新增t1到當前時間段內,主表變化過的資料。
          為了記錄這種變化,建立增量重新整理物化檢視還需要一個物化檢視日誌表。
          create materialized view log on (主表名)。(多張表時,此語句也生效,建立後,原來的表中會多出兩類視圖表:MLOG$_table_name和RUPD$_table_name)
    
    complete: 全部重新整理。相當於重新執行一次建立檢視的查詢語句。
    
    force: 這是預設的資料重新整理方式。當可以使用fast模式時,資料重新整理將採用fast方式;否則使用complete方式。
    
  2. MV資料重新整理的時間:

    on demand: 在使用者需要重新整理的時候重新整理,這裡就要求使用者自己動手去重新整理資料(可以使用JOB定時重新整理);
    on commit: 當主表中有資料提交的時候,立即重新整理MV中的資料;
    start ……:從指定的時間開始,每隔一段時間(由next指定)就重新整理一次;
    
    全重新整理mv_test物化檢視:
    
begin
     dbms_mview.refresh(TAB=>'MV_TEST',
                        METHOD=>'COMPLETE',
                        PARALLELISM
=>8);
end; /

增量重新整理:

begin
     dbms_mview.refresh(TAB=>'MV_TEST',
                        METHOD=>'FAST',
                        PARALLELISM=>1);
end;
/

或者,也可以這樣執行:

exec dbms_mview.refresh('MV_TEST','F');
dbms_mview.refresh('表名', 'F')   --快速重新整理,也就是增量重新整理
dbms_mview.refresh('表名'
, 'C') --完全重新整理

例項演示:

以下是我通過建立物化檢視,實現不同資料庫間表級別的資料同步的一個過程記錄,(兩臺伺服器A和B,其中要把資料從A節點的表zh_major_item同步到B節點上)。目前實現同步的過程還只是一個單向的過程,也就是從A節點 —> B節點:

主要步驟:

  1. 在A節點建立原表和物化檢視日誌
  2. 在B節點建立連線A節點的遠端連結
  3. 在B節點處,建立目標表和與目標表名稱相同的物化檢視

1. 在A節點建立原表和物化檢視日誌:

--在源A處 建立物化檢視日誌
sqlplus tianzhi_smart/[email protected]:1521/orcl

--原表zh_major_item之前已經存在,這裡就不贅述表建立的過程了
--建立物化檢視日誌
create materialized view log on zh_major_item;

2. 在B節點建立連線A節點的遠端連結:

--在目標B處 建立遠端連線
--如果沒有建立遠端連線的許可權,需要登入sysdba,為使用者授權;

--之所以跟上面一樣,因為我的使用者名稱和密碼相同而已
sqlplus tianzhi_smart/[email protected]:1521/orcl

--建立遠端連線 db_link
create public database link db_link_A 
    connect to tianzhi_smart 
    identified by "tianzhi_smart" 
    using '192.168.56.6:1521/ORCL';

--驗證是否建立成功
select * from [email protected]_link_A ;

3. 在B節點處,建立目標表和與目標表名稱相同的物化檢視:

--B節點處建立目標表bc_major_item
create table bc_major_item 
as select * from [email protected]_link_A where 1=2;

--通過遠端連線向A節點建立一個與目標表(bc_major_item)名稱相同的物化檢視    
--使用on prebuilt table註冊新的物化檢視,注意view名稱必須和表名稱一樣
--使用on prebuilt table建立的物化檢視被刪除後,原來的表不被刪除
--注意這裡我建立是refresh fast on demand 型別的物化檢視
 create materialized view bc_major_item 
 on prebuilt table refresh fast on demand 
 as select * from [email protected]_link_A ;

4.在B節點處,重新整理物化檢視

 --重新整理物化檢視
 exec dbms_mview.refresh('bc_major_item ','C');

 --重新整理後,查詢目標表,比對是否和原表資料相同
 select * from bc_major_item ;

5.升級採用儲存過程+定時任務JOB方式,定時重新整理物化檢視


    --建立儲存過程,進行增量重新整理
    create or replace procedure refresh_bc_major_item
    as
    begin
        dbms_mview.refresh('bc_major_item','F');
    end;
    /

    --建立任務JOB
    SQL> variable job1 number;
    SQL>begin
 dbms_job.submit(:job1,'refresh_bc_major_item;',sysdate,'sysdate+1/(86400)');  
    end;
    /

    --執行JOB
    SQL> begin
       dbms_job.run(:job1);
      end;
      /

6.進一步優化:

可以再寫一個儲存過程+定時任務JOB,定時清空物化檢視日誌。

文章更新記錄

v1.0 – 表面是實現了同步,其實查詢的只是檢視,並沒有完成如題目所指的問題
v2.0 – 將目標表和物化檢視建立聯絡,真正實現資料同步。2016.12.6

參考文章: