利用MV的数据迁移最大的特点是比较灵活,可以实现跨平台,跨数据库版本迁移,而且能够实现数据的重组优化。该方式的实现原理要求在源表对象有一个主键,用于MV刷新。在源表上创建MV日志,再在目标数据库创建结构一样的表,然后在目标数据库上采用prebuilt方式创建MV,第一次采用完全刷新,然后一直采用增量刷新,等到要切换的时候,只要刷新增量的日志,删除MV,保留目标表即可。
--创建源表SQL> create table from_table(id number,num number);Table created.--添加主键SQL> alter table from_table add constraint pk_from primary key(id);Table altered.--创建目标表。然后在该表上创建主键或者非空的唯一约束。SQL> create table to_table(id number,num number);Table created.SQL> alter table to_table add constraint pk_to primary key(id);Table altered.SQL> insert into from_table select rownum,rownum*100 from dba_objects where rownum <=10;10 rows created.SQL> commit;Commit complete.--在源表创建MV日志SQL> create materialized view log on from_table;Materialized view log created.--在目标表上采用prebuilt方式创建MVSQL> create materialized view to_table on prebuilt table refresh fast as select * from from_table;Materialized view created.SQL> select count(*) from to_table; COUNT(*)---------- 0--执行完全刷新SQL> exec dbms_mview.refresh('TO_TABLE',method =>'Complete');PL/SQL procedure successfully completed.SQL> select count(*) from to_table; COUNT(*)---------- 10--执行一次增量刷新。增量刷新之前一定要保证源表和目标表上都存在主键,否则无法完成增量刷新SQL> exec dbms_mview.refresh('TO_TABLE');PL/SQL procedure successfully completed.SQL> select * from to_table; ID NUM---------- ---------- 1 100 2 200 3 300 4 400 5 500 6 600 7 700 8 800 9 900 10 100010 rows selected.--创建自动刷新的作业,每30秒同步一次增量日志。SQL> @create_program附:cat create_program.sql begin dbms_scheduler.create_program ( program_name =>'refresh_to_table', program_type =>'PLSQL_BLOCK', program_action =>'begin dbms_mview.refresh(''TO_TABLE'');end;', enabled =>TRUE );end;/PL/SQL procedure successfully completed.SQL> @create_scheduler附:cat create_scheduler.sql begin dbms_scheduler.create_schedule ( schedule_name =>'every_30_seconds', start_date =>systimestamp, repeat_interval =>'FREQ=SECONDLY;INTERVAL=30' );end;/PL/SQL procedure successfully completed.SQL> @create_job附:cat create_job.sql begin dbms_scheduler.create_job ( job_name =>'secondly_refresh', program_name =>'refresh_to_table', schedule_name =>'every_30_seconds', enabled =>TRUE );end;/PL/SQL procedure successfully completed.--运行作业SQL> exec dbms_scheduler.run_job('secondly_refresh');PL/SQL procedure successfully completed.--对源表继续操作SQL> insert into from_table values (11,1);1 row created.SQL> commit; Commit complete.SQL> select count(*) from to_table; COUNT(*)---------- 11SQL> insert into from_table select rownum+11,rownum*1000 from dba_objects where rownum <=9; 9 rows created.SQL> commit;Commit complete.SQL> select count(*) from to_table; COUNT(*)---------- 20SQL> select * from to_table; ID NUM---------- ---------- 1 100 2 200 3 300 4 400 5 500 6 600 7 700 8 800 9 900 10 1000 11 1 ID NUM---------- ---------- 13 2000 14 3000 20 9000 17 6000 18 7000 12 1000 15 4000 16 5000 19 800020 rows selected.SQL> update from_table set num = 1500 where id = 11;1 row updated.SQL> commit;Commit complete.SQL> select * from to_table; ID NUM---------- ---------- 1 100 2 200 3 300 4 400 5 500 6 600 7 700 8 800 9 900 10 1000 11 1500 ID NUM---------- ---------- 13 2000 14 3000 20 9000 17 6000 18 7000 12 1000 15 4000 16 5000 19 800020 rows selected.SQL> exec dbms_scheduler.drop_job('secondly_refresh');PL/SQL procedure successfully completed.SQL> delete from to_table where rownum = 1;delete from to_table where rownum = 1 *ERROR at line 1:ORA-01732: data manipulation operation not legal on this view--等刷新完成,删除MV log与MV。在目标数据库上,删除MV后,表和数据仍然存在SQL> drop materialized view to_table;Materialized view dropped.SQL> drop materialized view log on from_table;Materialized view log dropped.SQL> select * from to_table; ID NUM---------- ---------- 1 100 2 200 3 300 4 400 5 500 6 600 7 700 8 800 9 900 10 1000 11 1500 ID NUM---------- ---------- 13 2000 14 3000 20 9000 17 6000 18 7000 12 1000 15 4000 16 5000 19 800020 rows selected.--最后创建与表有依赖关系的对象