Oracle 10g R2特性之数据仓库和集成特性(四)

日期: 2008-06-21 来源:TechTarget中国

  通过联机重新定义将LONG转换为LOB


  如果数据仓库数据库已经存在一段时间,并且您要处理大型文本数据,则您可能拥有大量数据类型为LONG的列。毋庸质疑,LONG数据类型在大多数数据操作环境(如通过SUBSTR 进行搜索)中是没有用处的。您肯定需要将它们转换为 LOB 列。


  可以使用DBMS_REDEFINITION 程序包联机执行该操作。但在Oracle数据库10g第2之前,有一个很大的限制。


  将LONG列转换为LOB列时,您很希望获得高性能;您需要使该过程尽可能地快。如果将表进行了分区,则该过程将跨分区并行执行。但如果未将表进行分区,则该过程将串行执行,从而可能持续很长时间。


  幸好,在Oracle数据库10g第2版中,即使表未分区也可以在DBMS_REDEFINITION程序包内部执行从LONG到LOB的联机转换。我们通过一个示例来了解该转换的过程。以下是一个用于保存发送给客户的电子邮件的表。由于邮件正文(存储在 MESG_TEXT 中)通常是较长的文本数据,因此已将该列定义为 LONG。


   SQL> desc acc_mesg
  Name                              Null?Type
   —————————————– ——– ———


  ACC_NO                                    NOT NULL NUMBER
  MESG_DT                                   NOT NULL DATE
  MESG_TEXT                                          LONG


  您需要将该列转换为CLOB。首先,创建一个结构相同的(最后一列除外,它被定义为CLOB)空临时表。


  create table ACC_MESG_INT
  (
  acc_no number,
  mesg_dt  date,
  mesg_text clob
  );


  现在,启动重新定义过程。


  1  begin
  2     dbms_redefinition.start_redef_table (
  3        UNAME        => ’ARUP’,
  4        ORIG_TABLE   => ’ACC_MESG’,
  5        INT_TABLE    => ’ACC_MESG_INT’,
  6        COL_MAPPING  => ’acc_no acc_no, mesg_dt mesg_dt, to_lob(MESG_TEXT) MESG_TEXT’
   7  );
8* end;


  注意第6行,该行已经对列进行了映射。前两列保持不变,但第三列MESG_TEXT已被映射,以便通过对源表的列应用函数TO_LOB来填充目标表的MESG_TEXT 列。


  如果要重新定义的表很大,则需要定期对源表和目标表之间的数据进行同步。该方法加快了最终同步的速度。


  begin
  dbms_redefinition.sync_interim_table( 
  uname      => ’ARUP’,  
  orig_table => ’ACC_MESG’, 
  int_table  => ’ACC_MESG_INT’
       );
  end;
  /


  根据表的大小,您可能需要多次执行以上命令。最后,使用以下代码完成重新定义过程


  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’))

我们一直都在努力坚持原创.......请不要一声不吭,就悄悄拿走。

我原创,你原创,我们的内容世界才会更加精彩!

【所有原创内容版权均属TechTarget,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用。】

微信公众号

TechTarget微信公众号二维码

TechTarget

官方微博

TechTarget中国官方微博二维码

TechTarget中国

电子邮件地址不会被公开。 必填项已用*标注

敬请读者发表评论,本站保留删除与本文无关和不雅评论的权力。

相关推荐