ITPub博客

首页 > Linux操作系统 > Linux操作系统 > Oracle大对象数据存储简介

Oracle大对象数据存储简介

原创 Linux操作系统 作者:byfree 时间:2009-10-20 14:21:20 0 删除 编辑

1.Oracle大对象数据类型简介
在Oracle的早期版本中,使用LONG和LONG RAW类型存放大对象数据。从8i版本开始,Oracle引入了LOB数据类型,并且Oracle建议开发人员尽量去使用LOB类型而不去使用LONG和LONG RAW。LOB类型和LONG、LONG RAW类型相比有几个不同的地方。如:
        LOB(除了NCOLB)可以作为对象类型的一个属性,但LONG类型不可以。
        LOB的最大值是4G,而LONG只有2G。
        LOB支持随机访问数据,但LONG只支持顺序访问。
LOB包括内部LOB和外部LOB,其中内部LOB(BLOB CLOB NCLOB)的数据存放到数据库中,而外部LOB(BFILE)的数据存放在操作系统的文件中。
具体说明如下:
BLOB:存放二进制格式的数据,如:图像、音频、视频等。
CLOB:存放数据库字符集格式的字符数据,如:大的文本数据。
NCLOB:存放Unicode字符集的字符数据。
BFILE:存放指向操作系统文件的指针,并且该文件即可以是文本文件,也可以是二进制文件。当我们访问该类型所表示的列时,只能读取数据,不能修改。

以上CLOB、BLOB、NCLOB三种为内部LOB,从存储和选项来看,它们都是一样的。只不过CLOB和NCLOB支持文本信息,而BLOB支持二进制信息。不论基类型是什么,所指定的选项(CHUNKSIZE、PCTVERSION等)和要考虑的问题都是一样的。为此以下只以其中一类做详细说明。

2. 详细说明LOB存储属性

SQL> create table test (id int primary key,txt clob);

表已创建。

SQL> set line 120
SQL> col SEGMENT_NAME format a40
SQL> select segment_name,segment_type from user_segments;

SEGMENT_NAME                             SEGMENT_TYPE                                                                  
---------------------------------------- ------------------                                                            
SYS_C005393                              INDEX                                                                         
SYS_IL0000052546C00002$$                 LOBINDEX                                                                      
SYS_LOB0000052546C00002$$                LOBSEGMENT                                                                    
TEST                                     TABLE                                                                         
这里可以看到LOB字段有两个单独的segment,类型分别为lobindex、lobsegment,lobindex用于存放索引数据,lobsegment用于存放lob数据。普通字段只有在指明字段为主键、外键或指定索引等情况下,才会出现table segment和index segment两部分。

SQL> set pagesize 999 long 2000
SQL> select dbms_metadata.get_ddl('TABLE','TEST') from dual;

DBMS_METADATA.GET_DDL('TABLE','TEST')                                                                                  
--------------------------------------------------------------------------------                                       
                                                                                                                       
  CREATE TABLE "TEST"."TEST"                                                                                           
   ( "ID" NUMBER(*,0),                                                                                                 
 "TXT" CLOB,                                                                                                           
  PRIMARY KEY ("ID")                                                                                                   
  USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255                                                                       
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645                                                
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)                                                     
  TABLESPACE "TEST"  ENABLE                                                                                            
   ) PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING                                                  
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645                                                
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)                                                     
  TABLESPACE "TEST"                                                                                                    
 LOB ("TXT") STORE AS (                                                                                                
  TABLESPACE "TEST" ENABLE STORAGE IN ROW CHUNK 8192 PCTVERSION 10                                                     
  NOCACHE LOGGING                                                                                                      
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645                                                
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT))
以上用不同颜色标明了LOB字段的四个主要属性:
          TABLESPACE
          ENABLE STORAGE IN ROW
          CHUNK 8192
          PCTVERSION 10
          NOCACHE

TABLESPACE
这里指定的TABLESPACE是存储lobsegment和lobindex的表空间,这可能与表本身所在的表空间不同。也就是说,保存LOB数据的表空间可能不同于保存实际表数据的表空间。
为什么考虑为LOB数据使用另外一个表空间(而不用表数据所在的表空间)呢?原因与管理和性能有关。从管理的角度看,LOB数据类型表示一种规模很大的信息。如果表有数百万行,而每行有一个很大的LOB,那么LOB就会极为庞大。为LOB数据单独使用一个表空间有利于备份和恢复以及空间管理,单从这一点考虑,将表与LOB数据分离就很有意义。例如,你可能希望LOB数据使用另外一个统一的区大小,而不是普通表数据所用的区大小。
另一个原因则出于I/O性能的考虑。默认情况下,LOB不在缓冲区缓存中进行缓存。因此,默认情况下,对于每个LOB访问,不论是读还是写,都会带来一个物理I/O(从磁盘直接读,或者向磁盘直接写)。那么将这些对象分离到不同的磁盘上就很有意义。

ENABLE STORAGE IN ROW
此参数控制了LOB数据是否总与表分开存储(存储在lobsegment中)。如果设置了ENABLE STORAGE IN ROW,而不是DISABLE STORAGE IN ROW,小LOB(最多4,000字节)就会像VARCHAR2一样存储在表本身中。只有当LOB超过了4,000字节时,才会“移出”到lobsegment中。
LOB在4000byte以内,使用ENABLE STORAGE IN ROW比DISABLE STORAGE IN ROW快,总体系统消耗也较小。

参数调整例子:
ALTER TABLE tabname MODIFY LOB (lobname) (enable storage in row)
ALTER TABLE tabname MODIFY LOB (lobname) (disable storage in row)

CHUNK 8192
LOB字段存储块的大小,CHUNK是逻辑上连续的一组数据库块(block),也是LOB的最小分配单元,通常数据库的最小分配单元是数据库块,因此CHUNK大小必须是Oracle块大小的整数倍。
当存储LOB数据较大时,CHUNK大小设置大于8K有利于减小I/O的次数。例如,如果表中的LOB平均有7KB,而使用的CHUNK大小为32KB,对于每个LOB实例你都会“浪费”大约25KB的空间,另一方面,倘若使用8KB的CHUNK,就能使浪费减至最少。反之,如果有一个4MB的LOB,并使用8KB的CHUNK,你就至少需要512个CHUNK来存储这个消息。这也说明,至少需要512个lobindex条目指向这些CHUNK。这会影响获取性能,因为与读取更少但更大的CHUNK相比,要花更长的数据来读取和管理许多小CHUNK。因此我们应该找到一个CHUNK大小与lobindex条目数比较平衡的“中间点”。

参数调整例子:
ALTER TABLE tabname MODIFY LOB (lobname) ( CHUNK n )

PCTVERSION 10
这用于控制LOB的读一致性。lobsegment并不使用undo来记录其修改,而是直接在lobsegment中维护信息的版本。lobindex会像其他段一样生成undo,但是lobsegment不会。修改一个LOB时,Oracle会分配一个新的CHUNK,并且仍保留原来的CHUNK。如果回滚了事务,对LOB索引所做的修改会回滚,索引将再次指向原来的CHUNK。因此,undo维护会在LOB段本身中执行。修改数据时,原来的数据库保持不动,此外会创建新数据。
PCTVERSION控制着用于实现LOB数据版本化的已分配LOB空间的百分比(这些数据库块由某个时间点的LOB所用,并处在lobsegment的HWM以下)。对于许多使用情况来说,默认设置12%就足够了,因为在很多情况下,你只是要INSERT和获取LOB(通常不会执行LOB的更新;LOB往往会插入一次,而获取多次)。因此,不必为LOB版本化预留太多的空间(甚至可以没有)。
不过,如果应用确实经常修改LOB,倘若你频繁地读LOB,与此同时另外某个会话正在修改这些LOB,12%可能就太小,需适当增大该参数。

参数调整例子:
ALTER TABLE tabname MODIFY LOB (lobname) ( PCTVERSION n );

NOCACHE
这个子句控制了lobsegment数据是否存储在缓冲区缓存中。默认的NOCACHE指示,每个访问都是从磁盘直接读,类似地,每个写/修改都是对LOB的一个直接写。CACHE READS允许缓存从磁盘读的LOB数据,但是LOB数据的写操作必须直接写至磁盘。CACHE则允许读和写时都能缓存LOB数据。
如果是中小规模的LOB(例如,使用LOB来存储只有几KB的描述性字段),缓存就很有意义。如果不缓存,当用户更新描述字段时,还必须等待I/O将数据写到磁盘(将执行一个CHUNK大小的I/O,而且用户要等待这个I/O完成)。如果你在执行多个LOB的加载,那么加载每一行时都必须等待前一个I/O完成。所以启用执行LOB缓存很合理。
为此需根据LOB字段的大小与修改频繁度来决定CACHE参数的设置。

参数调整例子:
ALTER TABLE tabname MODIFY LOB (lobname) ( CACHE );
ALTER TABLE tabname MODIFY LOB (lobname) ( CACHE READS);
ALTER TABLE tabname MODIFY LOB (lobname) ( NOCACHE );

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/17997/viewspace-616935/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2008-04-16

  • 博文量
    65
  • 访问量
    232611