根据表的大小,您可能需要多次执行以上命令。最后,使用以下代码完成重新定义过程
begin dbms_redefinition.finish_redef_table ( UNAME => 'ARUP', ORIG_TABLE => 'ACC_MESG', INT_TABLE => 'ACC_MESG_INT' ); end; /
|
表 ACC_MESG 已经发生了变化:
SQL> desc acc_mesg Name Null?Type ----------------------------------------- -------- --------- ACC_NO NOT NULL NUMBER MESG_DT NOT NULL DATE MESG_TEXT
|
注意,MESG_TEXT 列现在为 CLOB 而非 LONG。
该特性对于将错误定义的数据结构或原先遗留的数据结构转换为更容易管理的数据类型非常有用。
联机重组单个分区
假设您有一个包含事务历史的表 TRANS。该表基于 TRANS_DATE 进行分区,每个季度作为一个分区。在正常的业务过程中,最新的分区经常更新。某个季度过后,该分区上可能没有很多活动了,因此可以将它移动到其他位置。但移动本身将需要对表进行锁定,从而拒绝对分区的公共访问。如何在不影响其可用性的情况下移动分区?
在 Oracle 数据库 10g 第 2 版中,可以对单个分区使用联机重新定义。您可以像对整个表执行重新定义(使用 DBMS_REDEFINITION 程序包)一样执行此任务,但底层机制并不相同。常规表是通过对源表创建物化视图重新定义的,而单个分区是通过交换分区方法重新定义的。
我们来看一下它的工作原理。以下是 TRANS 表的结构:
SQL> desc trans Name Null?Type --------------------------------- -------- ------------------------- TRANS_ID NUMBER TRANS_DATE DATE TXN_TYPE VARCHAR2(1) ACC_NO NUMBER TX_AMT NUMBER(12,2) STATUS
|
该表已经按如下所示进行了分区:
partition by range (trans_date) ( partition y03q1 values less than (to_date('04/01/2003','mm/dd/yyyy')), partition y03q2 values less than (to_date('07/01/2003','mm/dd/yyyy')), partition y03q3 values less than (to_date('10/01/2003','mm/dd/yyyy')), partition y03q4 values less than (to_date('01/01/2004','mm/dd/yyyy')), partition y04q1 values less than (to_date('04/01/2004','mm/dd/yyyy')), partition y04q2 values less than (to_date('07/01/2004','mm/dd/yyyy')), partition y04q3 values less than (to_date('10/01/2004','mm/dd/yyyy')), partition y04q4 values less than (to_date('01/01/2005','mm/dd/yyyy')), partition y05q1 values less than (to_date('04/01/2005','mm/dd/yyyy')), partition y05q2 values less than (to_date('07/01/2005','mm/dd/yyyy')) )
|
在某个时刻,您决定将分区 Y03Q2 移动到另一个表空间 (TRANSY03Q2),该表空间可能位于一个不同类型的磁盘(一个慢一点、便宜一点的磁盘)上。为此,请首先确认您可以联机重新定义该表:
begin dbms_redefinition.can_redef_table( uname => 'ARUP', tname => 'TRANS', options_flag => dbms_redefinition.cons_use_rowid, part_name => 'Y03Q2'); end; /
|
此处没有输出,因此您确认可以联机重新定义该表。接下来,创建一个临时表保存该分区的数据:
create table trans_temp ( trans_id number, trans_date date, txn_type varchar2(1), acc_no number, tx_amt number(12,2), status varchar2(1) ) tablespace transy03q2 /
|
请注意,由于表 TRANS 进行了范围分区,因此您已经将该表定义为未分区表。该表在所需的表空间 TRANSY03Q2 中创建。如果表 TRANS 包含一些本地索引,则表示您已经对表 TRANS_TEMP 创建了这些索引(当然是创建为未分区索引)。