Thomas Zhang的杂货铺
18 11, 2008
LOB 到 SecureFiles 的移植
作者 tomszrp 10:41 | Permalink 静态链接网址 | Comments 最新回复 (0) | Trackback 引用 (0) | 解决方案

在Oracle Database 11g 引入了一个经过完全重新设计的大对象 (LOB) 数据类型,
此类型显著提高了应用程序开发的效率和可管理性,并简化了应用程序的开发过程。

SecureFile 是一个新的数据库特性,其解决了将数据 保存在数据库之外同时又保证了数据访问的性能
类似与LOB类型,但有更强的功能
比LOB类型快2-10倍
透明加密、压缩和减少重复储存
继承了数据库的安全性、可靠性和扩展性
是LOB的一个超集,LOB类型数据可简单的转换到SecureFile
整合了关系型数据和文件数据
相同的安全模式
相同的数据访问方式
相同的的数据管理

既然已经了解 SecureFiles 是多么有用,您可能希望对现有的表进行转换。最简单的方法是创建一个新表,载入旧表中的数据,然后重命名该表。(当然,这要求这些表在操作期间不可用。)另一种方法是使用 dbms_redefinition 程序包在线重新定义表,不影响可用性。

我们通过一个示例来了解该过程。假设您希望移植原始表 CONTRACTS_BASIC 以存储为 SecureFiles。要实现该目的,执行以下步骤。

1.创建原始环境

  SQL> create table contracts_basic
    2  (
    3    contract_id number(12),
    4    contract_name varchar2(80),
    5    file_size number,
    6    orig_file blob
    7  )
    8   tablespace data_01
    9   lob (orig_file)
   10   store as
   11  (
   12     tablespace data_01
   13     enable storage in row
   14     chunk 4096
   15     pctversion 20
   16     nocache
   17     nologging
   18  );
  
  Table created
  --插入一些数据
  SQL> 
  SQL> declare
    2      l_size      number;
    3      l_file_ptr  bfile;
    4      l_blob      blob;
    5  begin
    6      l_file_ptr := bfilename('SECFILE', 'test.pdf');
    7      dbms_lob.fileopen(l_file_ptr);
    8      l_size := dbms_lob.getlength(l_file_ptr);
    9      for ctr in 1 .. 100 loop
   10          insert into contracts_basic
   11          (
   12              contract_id,
   13              contract_name,
   14              file_size,
   15              orig_file
   16          )
   17          values
   18          (
   19              ctr,
   20              'Contract '||ctr,
   21              null,
   22              empty_blob()
   23          )
   24          returning orig_file into l_blob;
   25          dbms_lob.loadfromfile(l_blob, l_file_ptr, l_size);
   26      end loop;
   27      commit;
   28      dbms_lob.close(l_file_ptr);
   29  end;
   30  /
  
  PL/SQL procedure successfully completed
  
  SQL> select segment_name,segment_type,segment_subtype,tablespace_name,bytes,blocks from user_segments;
  
  SEGMENT_NAME               SEGMENT_TYPE  SEGMENT_SUBTYPE TABLESPACE_NAME       BYTES   BLOCKS
  -------------------------- ------------- --------------- ---------------- ---------- --------
  CONTRACTS_BASIC            TABLE         ASSM            DATA_01               65536        8
  SYS_LOB0000071760C00004$$  LOBSEGMENT    ASSM            DATA_01            38797312     4736
  SYS_IL0000071760C00004$$   LOBINDEX      ASSM            DATA_01               65536        8
  
  SQL> select * from user_lobs;
  
  TABLE_NAME         COLUMN_NAME    SEGMENT_NAME                TABLESPACE_NAME   
  ------------------ -------------- --------------------------- ---------------
  CONTRACTS_BASIC    ORIG_FILE      SYS_LOB0000071760C00004$$   DATA_01           
  
  INDEX_NAME                CHUNK PCTVERSION  RETENTION  FREEPOOLS CACHE  LOGGING 
  ------------------------- ----- ---------- ---------- ---------- ------ ------- 
  SYS_IL0000071760C00004$$   8192         20                       NO     NO      
  
  ENCRYPT COMPRESSION DEDUPLICATION   IN_ROW FORMAT          PARTITIONED SECUREFILE
  ------- ----------- --------------- ------ --------------- ----------- ----------
  NONE    NONE        NONE            YES    NOT APPLICABLE  NO          NO        
  
  
  SQL> 

下面我要考虑借助dbms_redefinition 将LOB向SecureFiles去移植。

2.如果表上没有主键,但方便创建的话,可以创建一个主键,如果如果不方便定义主键,可以考虑采用基于ROWID的方式重定义,比如

alter table contracts_basic add constraint pk_contacts primary key (contract_id);

我在本测试中,采用了ROWID的方式。

3.创建新表

SQL> create table contracts_sec
2 (
3 contract_id number(12),
4 contract_name varchar2(80),
5 file_size number,
6 orig_file blob
7 )
8 tablespace data_01
9 lob (orig_file)
10 store as securefile
11 (
12 tablespace data_01
13 enable storage in row
14 chunk 4096
15 pctversion 20
16 nocache
17 nologging
18 );

Table created

4.启动重定义

SQL> exec dbms_redefinition.can_redef_table('STUDY','CONTRACTS_BASIC',dbms_redefinition.cons_use_rowid);
PL/SQL procedure successfully completed

SQL>
SQL> declare
2 l_col_mapping varchar2(1000);
3 begin
4 l_col_mapping := --字段

5 'contract_id contract_id , '||
6 'contract_name contract_name , '||
7 'file_size file_size, '||
8 'orig_file orig_file';
9 dbms_redefinition.start_redef_table('STUDY', 'CONTRACTS_BASIC', 'CONTRACTS_SEC', l_col_mapping,dbms_redefinition.cons_use_rowid);
10 end;
11 /

PL/SQL procedure successfully completed

5.拷贝依赖关系

  declare
    l_error_count pls_integer := 0;
  begin
    dbms_redefinition.copy_table_dependents( 'STUDY', 'CONTRACTS_BASIC', 'CONTRACTS_SEC',1, TRUE, TRUE, TRUE, FALSE, l_error_count);
    dbms_output.put_line('Errors Occurred := ' ||  to_char(l_error_count));
  end;
   /

所有的相关对象(例如触发器、约束和索引)都利用 COPY_TABLE_DEPENDENTS 过程自动复制到临时表中。

 

6.完成重新定义过程。

   exec dbms_redefinition.finish_redef_table('ARUP', 'CONTRACTS_BASIC', 'CONTRACTS_SEC');
7.确认表已得到转换。 
  SQL> select securefile from dba_lobs where table_name = 'CONTRACTS_BASIC';

  SECUREFILE
  ----------
  YES

  SQL> 

列显示 YES,表明列已转换为 SecureFiles。

 

8.删除临时表 CONTRACTS_SEC

  SQL> drop table CONTRACTS_SEC purge;
  Table dropped.

Comments
发表评论
标题:


称呼:


邮箱地址(可选):


个人主页(可选):


发表评论:
Bold Italic Link authimage




博客日历
« 三月 2010 »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31        
搜索
最新发表
文章分类
文章归档
网站链接
新闻聚合