oracle clob介绍

来源:互联网 发布:淘宝店铺客服分流 编辑:程序博客网 时间:2024/05/16 13:53

参考了DAVID的文档:http://blog.csdn.net/tianlesoftware/article/details/6905406

varchar2类型的对象最大只能存放4000字节的内容,要想存放更多的字符,可以选择用lob字段。lob分clob、blob。

clob是存储字符的,这种类型用于存储大量的文本信息。

blob这种类型用于存储二进制信息,如字处理文档,图像。它不会执行字符集转换。应用向BLOB 中写入什么位和字节,BLOB就会返回什么为和字节。

这里主要介绍clob的使用


介绍下clob的基础知识

1、创建一个带lob字段的表时,oracle会分配三个segment,一个用于存储表:table,一个用于存储lob字段:lobsegment,一个用于存储lob字段产生的lobindexlobindex 和lobsegment是为了支持我们的LOB 列。实际LOB 数据就存储在lobsegment 中(LOB 数据也有可能存储在表T中,这与参数ENABLE/DISABLE  STORAGE IN ROW有关)。lobindex 用于执行LOB 的定位。创建一个LOB 列时,一般来说,存储在表行中的一个指针(pointer),或LOB 定位器(LOB locator)。这个指针指向我们要查询的lob列的存储地点。

2、LOB 按“块”(chunk)来存储。LOB 列值存储在块(chunk)中,表中的列实际储存的是一个指针,这个指针指向列在lobsegment中的位置。块(chunk)是逻辑上连续的一组数据库块(block),这也是LOB 的最小分配单元,而通常数据库的最小分配单元是数据库块。CHUNK 大小必须是Oracle 块大小的整数倍,只有这样才是合法值。当插入一个lob列时,oracle就会给这个插入的列分配一个CHUNK。

3、LOB 数据类型表示一种规模很大的信息。如果表有数百万行,而每行有一个很大的LOB,那么LOB 就会极为庞大。为LOB 数据单独使用一个表空间有利于备份和恢复以及空间管理。一般LOB 数据使用单独的表空间。

4、默认情况下,LOB 不在缓冲区缓存中进行缓存(CACHE/NOCACHE参数)。默认情况下,对于每个LOB 访问,不论是读还是写,都会带来一个物理I/O(从磁盘直接读,或者向磁盘直接写)。LOB 可以存储在table segment中,即存储在表中。在这种情况下,LOB 数据会被缓存,但是这只适用于小于4,000 字节的LOB。

5、lobindex 和lobsegment 在一个表空间中。不能将lobindex 和lobsegment 放在不同的表空间中。在Oralce 的更早版本中,允许为lobindex 和lobsegment 分别放在单独的表空间中,但是从8i Release 3 以后,就不再允许为lobindex 和logsegment 指定不同的表空间。实际上,lobindex的所有存储特征都是从lobsegment 继承的。

6、对于一致性读,oracle对lob字段有独特的管理方式。目前,Oracle提供了两种维持机制来进行控制:基于时间的版本保留retention和基于空间的版本保留pctversion。

7、LOB index 是随Lobsegment 自动创建的,不能只删除和重建LOB index。

8、LOB当Lob数据设置为cache的时候,自动就是logging属性。如果设置为nologging,只是lobsegment部分的数据变化不会写redo log,不会影响到其他的in row和column列的数据redo记录工作。

现在对clob所特有的参数进行解释,懂得了参数也就懂了原理和应用了。

clob的语法,从dbms_metadata.get_ddl抓出来的

    CREATE TABLE "WU"."TEST"  (    "ID" NUMBER PRIMARY KEY,   "NAME" CLOB,  )  TABLESPACE "USERS"
    LOB ("NAME")

    STORE AS SECUREFILE (TABLESPACE "LOBTBS"
    DISABLE STORAGE IN ROW
    CHUNK 8192
    NOCACHE 

    LOGGING
    STORAGE( BUFFER_POOL DEFAULT)

    ) ;

抓出来的语法实际比这些多,我省略了STORAGE(INITIAL xx, NEXT  xx)和 PCTFREE xx  PCTUSED xx INITRANS xx这些参数。这些参数影响不大,也不是创建lob字段所特有的。

1、TABLESPACE--LOB(XX) STORE AS (TABLESPACE USERS)

指定存储lobsegment 和lobindex的 表空间,可以与表本身所在的表空间不同。也就是说,保存LOB 数据的表空间可以不同于保存实际表数据的表空间。而往往我们也是这么做的。注意点就是lobsegment 和lobindex的表空间是一样的。不能分开制定。

2、ENABLE/DISABLE  STORAGE IN ROW--LOB(xx ) STORE  AS (ENABLE/DISABLE STORAGE  IN  ROW)

LOB 数据是与表分开存储(即存储在lobsegment 中),或是可以存储在表段中,而不用全部放在lobsegment 中。如果设置了ENABLE STORAGE IN ROW,小LOB(最多4000 字节)就会像VARCHAR2 一样存储在表本身中。只有当LOB 超过了4,000 字节时,才会“存储”到lobsegment 中。如果开始制定的是ENABLE STORAGE IN ROW,已经往表里插入了很多小于4000字节的字段,那么可以再更改LOB的存储方式为DISABLE STORAGE IN ROW。这时候已经保存在表段中的小于4000字节的lob列会移动到Lobsegment中去。在你执行更改存储方式的语句是移动。默认是启用行内存储(ENABLE STORAGE  IN ROW)。

 一般来说,OUT ROW,即将数据存储在segment里,在这种情况下不会在buffer cache 中进行缓存,这样每次都会产生物理IO. 同时对out row 进行读写操作时,虽然有lobindex的存在,但 DML 操作需要同时维护lobindex和lobsegment。 采用OUT ROW 会增加逻辑IO和物理IO,所以默认启用IN ROW。 对lob 进行缓存,减小IO成本。

3、CHUNK--LOB(XX)  STORE AS ( CHUNK 8192)--这里参考DAVID的文档,因为他解释的很清楚

LOB 存储在块(chunk)中,LOB 索引会指向各个数据块。块(chunk)是逻辑上连续的一组数据库块(block),这也是LOB 的最小分配单元,而通常数据库的最小分配单元是数据库块。CHUNK 大小必须是Oracle 块大小的整数倍。选择CHUNK 大小时必须当心。首先,每个LOB实例(每个行外存储的LOB 值)会占用至少一个CHUNK。一个CHUNK 有一个LOB 值使用。如果一个表有100 行,而每行有一个包含7KB 数据的LOB,你就会分配100 个CHUNK,如果将CHUNK 大小设置为32KB,就会分配100 个32KB 的CHUNK。如果将CHUNK大小设置为8KB,则(可能)分配100 个8KB 的CHUNK。关键是,一个CHUNK 只能有一个LOB 使用(两个LOB 不会使用同一个CHUNK)。如果选择了一个CHUNK 大小,但不符合你期望的LOB 大小,最后就会浪费大量的空间。例如,如果表中的LOB 平均有7KB,而你使用的CHUNK 大小为32KB,对于每个LOB 实例你都会“浪费”大约25KB 的空间,另一方面,倘若使用8KB 的CHUNK,就能使浪费减至最少。

 还需要注意要让每个LOB 实例相应的CHUNK 数减至最少。前面已经看到了,有一个lobindex 用于指向各个块,块越多,索引就越大。如果有一个4MB 的LOB,并使用8KB 的CHUNK,你就至少需要512 个CHUNK来存储这个消息。这也说明,至少需要512 个lobindex 条目指向这些CHUNK。LOB的访问是通过INDEX来访问的,索引一次访问一个块(CHUNK或者普通的oracle block)这会影响获取性能。与读取更少但更大的CHUNK 相比,现在要花更长的数据来读取和管理许多小CHUNK。我们最终的目标是:使用一个能使“浪费”最少,同时又能高效存储数据的CHUNK大小。

4、PCTVERSION/RETENTION--LOB(XX)  STORE AS ( PCTVERSION/RETENTION)

oracle的一致性读是使用undo数据的。但对于Lob不是这样的。Oracle提供了两种维持机制来进行控制:基于时间的版本保留retention和基于空间的版本保留pctversion。

pctversion:LOB在lobsegment 中保留某个百分比的空间来实现LOB 的版本化(即一致性读),直接在lobsegment 本身中维护信息的版本。lobindex 会像其他段一样生成undo,但是lobsegment 不会。修改一个LOB 时,Oracle 会分配一个新的CHUNK,并且仍保留原来的CHUNK。如果回滚了事务,对LOB 索引所做的修改会回滚,索引将再次指向原来的CHUNK。因此,undo 维护会在LOB 段本身中执行。修改数据时,原来的数据库保持不动,此外会创建新数据。LOB 是读一致的,使用logindex 的读一致视图来撤销对LOB 的修改,从而提取获取LOB 定位器当时的LOB 数据。它不会使用logsegment 的undo 信息,因为根本不会为logsegment 本身生成undo 信息。

PCTVERSION 控制着用于实现LOB 数据版本化的空间占已分配LOB 空间的百分比(这些数据库块由某个时间点的LOB 所用,并处在lobsegment 的HWM 以下)。对于许多使用情况来说,默认设置10%就足够了,因为在很多情况下,你只是要INSERT 和获取LOB(通常不会执行LOB 的更新;LOB 往往会插入一次,而获取多次)。因此,不必为LOB 版本化预留太多的空间(甚至可以没有)。当pctversion=0的时候,表示旧版本数据是可以被其他事务产生的版本占用。如果设置为100,就表示旧版本数据永远都不会被覆写使用。大小的一个参数,该值越大,回滚的时间相对就长,但是占用的空间也就越大。

Retention:表示采用基于时间版本保留策略。尽量保证保留一个时间段内的数据lob版本不会清除掉,即多长时间内来保证一致读。在数据库版本的兼容性版本设置在9.2.0.0以上,并且undo_management参数值为true时,lob是默认直接使用retetion设置的。不能使用这个子句来指定保留时间;而要从数据库的UNDO_RETENTION 设置来继承它。这个子句与PCTVERSION 子句是互斥的,即RETENTION和 PCTVERSION 只能设置一个,不能两个都设置。

5、CACHE--LOB(XX)  STORE AS ( CACHE/NOCACHE/CACHE READS)

这个参数指定了lobsegment 数据是否存储在缓冲区缓存中。默认的NOCACHE 指示,每个访问都是从磁盘直接访问,类似地,每个写/修改都是对磁盘的直接写。CACHE READS 允许缓存从磁盘读的LOB 数据,但是LOB 数据的写操作必须直接写至磁盘。CACHE 则允许读和写时都能缓存LOB 数据。在许多情况下,默认设置可能对我们并不合适。如果你只有小规模或中等规模的L O B(例如,使用LOB来存储只有几KB 的描述性字段),对其缓存就很有意义。如果不缓存,当用户更新描述字段时,还必须等待I/O 将数据写指磁盘(将执行一个CHUNK大小的I/O,而且用户要等待这个I/O 完成)。如果你在执行多个LOB 的加载,那么加载每一行时都必须等待这个I/O 完成。所以启用执行LOB 缓存很合理。不过,对于一个大小为50MB的LOB,把它放在缓存中就没带道理了。

此时可以充分使用Keep 池或回收池。并非在默认缓存中将lobsegment 数据与所有“常规”数据一同缓存,可以使用保持池或回收池将其分开缓存。采用这种方式,既能缓存LOB 数据,而且不影响系统中现有数据的缓存。

CACHE意味着LOGGING。指定了CACHE又指定NOLOGGING时会报错。

6、STORAGE--LOB(XX)  STORE AS ( STORAGE (XX,BUFFER_POOL KEEP/RECYCLE/DEFAULT))

LOB段有一个完整的存储子句,可以用来控制物理存储特征。这个存储子句适用于lobsegment 和lobindex。

对LOB 段使用保持池或回收池可能是一个很有用的技术,这样就能缓存LOB 数据,而且不会“破坏”现有的默认缓冲区缓存。并不是将LOB 与常规表一同放在块缓冲区中,可以在SGA 中专门为这些LOB 对象预留一段专用的内存。BUFFER_POOL 子句可以达到这个目的。


下次更新对CLOB的操作

创建一个带Lob字段的表:

SQL> create table test (id number,name clob) lob(name) store as (tablespace users cache chunk 16K enable storage in row RETENTION STORAGE(buffer_pool keep));

Table created

SQL> alter table test move tablespace wu lob(name) store as (tablespace wu);

Table altered

SQL> alter table test move tablespace users;

Table altered

SQL> alter table test move lob(name) store as (tablespace users);

Table altered


不能对lob段的索引alter 。比如

SQL> select index_name,index_type,table_name from user_indexes;


INDEX_NAME                     INDEX_TYPE                  TABLE_NAME
------------------------------ --------------------------- ------------------------------
SYS_IL0000058670C00002$$       LOB                         TEST

SQL> alter index "SYS_IL0000058670C00002$$" rebuild;

alter index "SYS_IL0000058670C00002$$" rebuild

ORA-02327: cannot create index on expression with datatype LOB

LOB段存的新特性

在11g以前的版本里,lob段的存储格式为BasicFile。11g新出了一个特性:SecureFiles 来存储LOB数据。这种格式相比以前有一些优点,比如智能压缩,取消重复,透明加密(这个不咋用)。压缩功能支持显式压缩SecureFiles。取消重复可自动检测重复的SecureFile LOB 数据。有一个初始化参数控制这个新特性:DB_SECUREFILE 。可动态修改

(1)  ALWAYS:尝试将ASSM表空间上的所有LOB 创建为SecureFile LOB,但是仅可将自动段空间管理(ASSM) 表空间外的任何LOB 创建为BasicFile LOB

(2)  FORCE:强制将所有LOB 创建为SecureFileLOB

(3)  PERMITTED:允许创建SecureFiles(默认值)

(4)  NEVER:禁止创建SecureFiles

(5)  IGNORE:禁止创建SecureFiles,并忽略使用SecureFiles 选项强制创建BasicFiles 而导致的任何错误

对于SecureFiles,不再需要指定CHUNK(使用SecureFiles 时,块大小介于Oracle 数据块大小到64MB 之间。Oracle DB 尝试使数据集中在磁盘的相邻物理位置,从而将内部碎片降到最低。)、PCTVERSION、FREEPOOLS、FREELISTS 和FREELIST GROUPS。为了与现有脚本相兼容,将对这些子句进行分析但不解释它们。新增了compress压缩参数。undo只能用retention。

使用方法

create table test (id number,name clob) lob(name) store as secureFile sftest(可选是否命名)(tablespace users cache chunk 16K enable storage in row RETENTION STORAGE(buffer_pool keep));


原创粉丝点击