目录

一、建表语句

二、关键字详解

1. ENABLE 和 DISABLE

2. 创建主键约束

3. USING INDEX

4. PCTFREE

5. PCTUSED

6. INITRANS 和 MAXTRANS

1)INITRANS

 2)MAXTRANS

7. COMPUTE STATISTICS

8.  STORAGE

1)表空间管理机制

2)STORAGE 内部参数

3)FREELISTS 和 FREELIST GROUPS

4)BUFFER_POOL

4.1. BUFFER_POOL 分类

4.2. BUFFER_POOL 区别

5)FLASH_CACHE

5.1. FLASH_CACHE工作原理

5.2. FLASH_CACHE 的优点

5.3. FLASH_CACHE 控制参数

5.3.1. db_flash_cache_file:db 闪存文件

5.3.2. db_flash_cache_size :db 闪存大小

5.4. FLASH_CACHE 取值

6) SEGMENT CREATION IMMEDIATE

9. NOCOMPRESS 和 COMPRESS

10. LOGGING 和 NOLOGGING

11. LOB

12. STORE AS [BASICFILE/SECUREFILE]

1)大字段类型分类

2)BASICFILE 与 SECUREFILE 对比

13. ENABLE STORAGE IN ROW

14. CHUNK

15.  RETENTION/PCTVERSION

16. CACHE/CACHE READS/NOCACHE

17. BFILE

18. PCTFREE对lob的影响

三、总结


一、建表语句

我们创建一个 STUDENT 表,下面是创建完成后系统给我们补全的 DDL ,本文我们就依托于这个 DDL 进行说明。

  CREATE TABLE "DAKE"."STUDENT" 
   (	"ID" NUMBER NOT NULL ENABLE, 
	"NAME" VARCHAR2(30) NOT NULL ENABLE, 
	"GENDER" CHAR(2) NOT NULL ENABLE, 
	"AGE" NUMBER(2,0) NOT NULL ENABLE, 
	"CLASS_ID" NUMBER NOT NULL ENABLE, 
	"ADDRESS" VARCHAR2(100), 
	"COMMONT1" NUMBER, 
	"COMMONT2" NUMBER(3,0), 
	"COMMONT3" NUMBER(10,0), 
	"COMMONT4" NUMBER(20,0), 
	"COMMONT5" NVARCHAR2(10), 
	"COMMONT6" CLOB, 
	"COMMONT7" DATE, 
	"COMMONT8" TIMESTAMP (6), 
	"COMMONT9" INTERVAL DAY (3) TO SECOND (6), 
	 CONSTRAINT "STUDENT_PK" PRIMARY KEY ("ID")
  USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "USERS"  ENABLE
   ) SEGMENT CREATION IMMEDIATE 
  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 FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "USERS" 
 LOB ("COMMONT6") STORE AS BASICFILE (
  TABLESPACE "USERS" ENABLE STORAGE IN ROW CHUNK 8192 RETENTION 
  NOCACHE LOGGING 
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT))

二、关键字详解

1. ENABLE 和 DISABLE

在这里是对非空字段进行校验,即该字段不可为空;如果是 DISABLE ,虽然我们定义了非空,但是改字段的取值一样可以为空,实际上等同于非空约束不起作用。

我们创建一张表,TEST_04,建表语句如下:

CREATE TABLE TEST_04 ( 
	ID NUMBER(22) NOT NULL,
	NAME VARCHAR2(30) NOT NULL DISABLE,
	MONEY NUMBER,
	PRIMARY KEY (ID)
);

我们看到了 NAME 这一列是非空约束的,但是我们加上了 DISABLE,我们插入数据看一下:

 我们看到 NAME 这一列竟然可以为空,说明关键字 DISABLE 确实如我们所说,是使约束失效,不起作用。

如果不加这个关键字,模式是 ENABLE 的。

这里我们只是针对 DDL 做出了一个简单的验证,ENABLE 在其他地方也是类似的效果,这里就不赘述了。总之一句话,ENABLE 会验证指定的约束,DISABLE不验证。

2. 创建主键约束

CONSTRAINT "STUDENT_PK" PRIMARY KEY ("ID")
  USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "USERS"  ENABLE

其中:

CONSTRAINT "STUDENT_PK" PRIMARY KEY ("ID")

是定义一个主键约束,名称为 STUDENT_PK,主键字段为 ID。

一般情况下,CONSTRAINT "STUDENT_PK" 都不带的,即不指定名称,系统会自动生成一个基于该表的主键名称。我们以上面的 TEST_04 这张表为例,我们没有指定名称,但是我们打开索引查看:

 如果我们看 STUDENT 表:

 我们接着看剩余部分的语句:

USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "USERS"  ENABLE

3. USING INDEX

指定存在的索引。如果不指定,则根据约束自动建立一个index ,并且和这个约束的名字一样。

4. PCTFREE

为一个块保留的空间百分比,表示数据块在什么情况下可以被insert,默认是10,表示当数据块的可用空间低于10%后,就不可以被insert了,只能被用于update;即:当使用一个block时,在达到pctfree之前,该block是一直可以被插入的,这个时候处在上升期。

 向一个数据库写入数据时,对数据表中的块block来说,数据会依次填满数据块,在Oracle中,向数据库写数据的时候,需要先找到一个空闲块,之后向空闲块中写入数据。

Oracle是怎样判断一个块是空闲块?

​ 答案就是 PCTFREE 参数。该参数是一个百分比值,它的默认为10%。如果一个数据块的空闲空间(可用空间)低于 PCTFREE 设定值,就认为这个数据块已经写满。会将这个块从空闲块的列表(FREELIST)上删除。
 

5. PCTUSED

是指当块里的数据低于多少百分比时,又可以重新被insert,一般默认是40,即40%,即:当数据低于40%时,又可以写入新的数据,这个时候处在下降期。

优化方向
如果希望存储空间发挥最大使用效益,可以把PCTUSED设大一点,相反的,如果想要提高IO效能,应该把PCTUSED设置小一点。

6. INITRANS 和 MAXTRANS

INITRANS 和 MAXTRANS,这两个值是与数据块的事物控制相关的,控制事物表的大小,2和255也是默认值。

1)INITRANS

初始化事务槽的个数,默认值:2

 2)MAXTRANS

最大事务槽的个数,默认值:255

7. COMPUTE STATISTICS

计算统计数据

8.  STORAGE

存储参数

1)表空间管理机制

先阐明一个概念:数据表空间 Tablespace 空间管理的机制问题。

​ storage关键字里面涉及到参数取值通常来自我们使用表空间的设置。数据表逻辑上是一种段对象segment object(Data Segment)。Data Segment的空间管理是通过Tablespace表空间进行管理的。

​ 在管理空闲空间和分配空间的问题上,有字典管理方式(Dictionary Management Tablespace DMT)和本地管理方式(Locally Management Tablespace LMT)。(声明:本部分参考陈吉平老师的《Oracle——高可用环境》)。

在Oracle8i以前,对空闲空间是采用数据字典DML的方式进行管理。两个底层数据字典UET( 已 经 使 用 过 的 空 间 ) 和 F E T (已经使用过的空间)和FET(已经使用过的空间)和FET(未使用的空间)。当分配空间的时候,Oracle使用一系列递归的SQL来获取空闲空间。这种结构存在一些潜藏的问题。

是并行操作引起的性能瓶颈。在寻找空间空间和分配空间的时候,Oracle对两个数据字典表进行递归SQL调用和更新。在DML操作频繁、空间分配管理的环境下,数据字典进行串行化操作,容易形成性能瓶颈。

配合其他参数进行空间分配,容易形成过多的空间碎片。特别是在分配大小不一致的情况下。
每个Segment所使用的所有extents信息都保存在数据字典中,如果数据表很大,字典数据表中记录数目也就相对较多。那么,进行批量的删除或者数据表drop,会引起长时间的数据表更新操作。长时间的串行化更新操作进一步就会影响系统整体的空间管理分配能力。

鉴于这些问题,Oracle在8i之后,推出了本地管理表空间(LMT)机制,逐渐取代DMT方法。简单的说,就是将空闲空间管理职责,由统一的数据字典管理下放到文件级别,让文件自己管理空闲空间、分配空间。

在LMT机制里,Oracle将存储信息保存在文件的文件头部。在文件头上,存在一个位图形式的存储信息段,其中记录了该文件空闲空间管理信息。这样,在表空间进行对象空间分配的时候,只需要进行文件级别的资源协调,不需要访问专门的数据字典。这样也就避免了空闲资源带来的争用。

2)STORAGE 内部参数

  • INITIAL:区段(extent),一次扩展64k
  • NEXT:分配下一个空间片段的大小
  • MINEXTENTS:最小区段数,数据对象在创建开始分配分区的个数
  • MAXEXTENTS:最大区段
  • PCTINCREASE:PCT    INCREASE的合并后的单词,实际上是:Percentage increase,意思是提升百分比
  • FREELISTS:空闲链表
  • FREELIST GROUPS:空闲链表组
  • BUFFER_POOL:缓冲池,决定了该数据段对象在SGA缓冲区中的管理策略
  • DEFAULT:默认值,介于keep和recycle两类之间的一种对象缓存方式。
  • FLASH_CACHE:默认刷新缓存
  • TABLESPACE "USERS" :指定表空间-USERS
  • ENABLE:约束的校验

3)FREELISTS 和 FREELIST GROUPS

FREELISTS和FREELIST-GROUPS参数是段的存储参数。

​ 数据库在INSERT,UPDATE操作时都需要请求空闲的数据块,由于不可能每次操作时都去每个数据块查询一下看看有没有空闲的块(如果这样那效率太低了)。为了解决这个问题,ORACLE的在每个段的段头有一个空闲数据块指针链表的结构,这个就称为FREELISTS,FREELISTS列表代表链表的长度。表面上看像解决了问题,但在高并发对一个表的插入或更新时,一个空闲链表往往会出现等待的现象,所以为了提高性能,又增加了多个空闲链表的处理,也就是FREELIST-GROUPS,也就说段有多少个空闲链表是FREELIST-GROUPS参数决定。

​ 在ORACLE9.2以前,对于一些高并发的表需要检查FREELISTS和FREELIST-GROUPS参数是否满足应用的要求。从ORACLE9.2新增加了ASSM(表空间段自动管理)的新特性,有了ASSM,链接列表FREELISTS被位图结构所取代,所以也根本不需要指定什么FREELISTS和FREELIST-GROUPS参数了,一个段里哪些数据块是空闲的,那些是可以再使用的,在这个位图里全部可以取到,并且全部是由ORACLE自动管理。


通过测试与实践,采用自动段管理的表,在并发处理性能上表现非常好,所以基本上现在的表都采用段自动管理了,因此FREELISTS和FREELIST-GROUPS参数也就成为过去。

Freelists与Freelist Group都是涉及到段对象空间分配的机制。分配给数据段的空闲空间包括两个部分,高水位线HWM以上空闲块和HWM以下空闲块。

其中,HWM以下的空闲空间是通过Freelists进行管理。简单的说,Freelists就是一个列表,列表上连接着所有管理的空闲数据块。当进行insert或者update操作的时候,数据表段segment 需要额外的空闲数据块,就需要段segment进行空闲块的管理。


在这个过程中,每个段头上都有专门的freelists,进行空闲块的管理。freelists参数就表示附加在这个段对象上处理freelist的个数,也就是一个freelists group上所容纳的freelists的个数。


在案例参数中,取定freelists=1,表示该数据表中每个freelists group上包括一个freelists。该参数的最小值为1,最大值的选取与当前数据库使用数据块大小db_block_size密切相关。如果设置不合适,会在运行阶段报错。


使用freelist的时候,当系统需要空闲块保存数据是,会向freelist进行空间请求,容易成为性能的瓶颈所在。所以从9i开始,Oracle引入了位图表进行freelist的管理。

指定创建数据对象上使用的Freelist Group的数量。我们说,默认情况下,是使用一个freelist进行数据空闲块管理。一些数据表如果分配比较频繁,单个freelist可能不能满足实际的需要,这时候可以考虑使用多个freelist group来缓解空间块管理压力。

说明: 对表空间空间的管理,Oracle存在手工段管理方式下Segment Management Manual。如果设置为自动段空间管理ASSM下,freelists和freelist group两个参数是不起效果的。

4)BUFFER_POOL

Oracle是不会直接对数据文件中的数据进行操作的。对数据的读写操作,都是需要对文件以数据块的形式加载在内存SGA共享区中,之后对数据块进行操作。如果是修改或者新增加操作,则由DBWn后台进行写回数据文件。

数据块在SGA区中驻留的场所就是Buffer Pool。Oracle在访问一条数据的时候,首先会在Buffer Pool中寻找,看看该块是不是已经缓存在Buffer Pool中了。如果没有,就从数据文件中获取这个数据块。长期DBA们关注的数据块命中率,也就是在Buffer Pool中发生的。

一般内存是小于数据库容量的。为了加快速度,最理想的情况是将所有的数据加载在内存中。但是这种方法还存在一些距离。所以,总会有数据块被从Buffer Pool中替换掉。目前Oracle采用LRU算法进行数据块淘汰,也就是最常用、访问最频繁的数据块会更长时间保存在缓冲区内,很少访问的数据块可能很快的被剔出缓冲区。这样做的目的也就是保证经常访问数据访问速度。

在这样的基础上,Oracle对Buffer Pool进行了进一步的划分。划分为keep、default和recycle三个子,这样的划分目的是在业务范畴上对数据进行进一步的分治。

4.1. BUFFER_POOL 分类

1. KEEP 池:就是保持最长的时间。keep池中的对象,都是定义为经常使用的对象,保持最大限度的驻留时间,不会轻易被剔出Buffer Cache。

2. RECYCLE 池:是为了不经常访问的数据对象块准备的。通常被加载之后,不希望长时间的保存。

3. DEFAULT:是buffer pool的默认选项,是介于keep和recycle两类之间的一种对象缓存方式。

4.2. BUFFER_POOL 区别

1. 三种类型池对象虽然目的定义不同,但是使用的管理算法仍然是LRU算法。区别只是在从业务上对数据对象进行划分,而这个定义是掌握在系统设计和DBA手中;

2. 当我们对SGA空间进行动态管理的时候,三个缓存池空间是通过Oracle动态进行调整的。所以,我们现在已经不需要分别定义空间的大小,而只需要定义三类对象是什么就可以了。

3. 回到buffer_pool参数,Buffer_pool定义了该段对象进行缓存的策略。取值有default、keep和recycle。

修改表的数据存储的缓冲池:变更default为recycle

alter table t_buffer_pool storage(buffer_pool recycle);

建表时,显式指定存储缓冲池:

 create table t_buffer_pool(a int) storage(buffer_pool keep);

5)FLASH_CACHE

从Oracle 11gR2开始,Oracle终于如大家所预料的那样,开始支持SSD(solid-state disk),该特性允许使用SSD硬盘作为Buffer Cache的二级缓存,以在磁盘和内存之间增加一级缓冲,提升数据访问性能。这个功能其实是EXADATA引入,这也是EXADATA提高IO性能的又一利器。不过即使不是EXADATA,在11.2中也可以设置该功能,前提要求操作系统必须是oracle enterprise linux(简称OEL)或者solaris,也就是说只支持Oracle公司自己的操作系统。Flash Cache 的功能只会提高磁盘读的性能,因为Dirty blocks还是会直接写到磁盘而不会在SSD中。

5.1. FLASH_CACHE工作原理

  1. 首先当有读的请求发生时,磁盘数据会被读到buffer
  2. 有写的工作完成时,会将Dirty blocks直接写入磁盘
  3. 将SGA中通过LRU移出的数据写到flash cache中,下次有读的请求时会通过flash cache写入内存

5.2. FLASH_CACHE 的优点

  1. 使用固态磁盘(SSD)技术对数据库缓冲缓存进行透明扩展
  2. SSD充当2级缓存(SGA为1级)
  3. 比磁盘快(读取速度快100倍)
  4. 比内存便宜(每GB 50美元)
  5. 大容量(每个闪存磁盘数百GB)
  6. 更少的驱动器和更好的性能,大型作业完成更快

5.3. FLASH_CACHE 控制参数

11gR2中,对这一特性的支持是通过新引入的2个参数来控制的:

db_flash_cache_file 和 db_flash_cache_size。

5.3.1. db_flash_cache_file:db 闪存文件

操作系统文件系统或Oracle自动存储管理磁盘组中,指定包含闪存缓存的文件的路径和文件名。如果文件不存在,数据库会在启动时创建它。文件必须驻留在闪存设备上。如果在磁盘驱动器上配置闪存缓存(主轴),性能可能会受到影响。以下是db_flash_cache_文件的有效值示例:

/dev/fioa1

5.3.2. db_flash_cache_size :db 闪存大小

指定闪存缓存的大小。必须小于或等于闪存设备的物理内存大小。表示为nG,表示千兆字节(GB)的数量。例如,要指定16 GB的闪存缓存,将db_flash_cache_size设置为16G。

注意:

如果db_flash_cache_size>0表示enable flush cache特性;

如果db_flash_cache_size=0表示disable flush cache特性。

Flash cached blocks Headers是被保存在SGA中,所以配置了flash cache特性,需要适当的增加sga的size。

Flush cache size 设置多大合适?

根据Oracle官方doc的建议,一般设置Flush cache为buffer cache的2-10倍左右,少于2倍的设置,将不会带来什么好处。

5.4. FLASH_CACHE 取值

FLASH_CACHE 有三个取值:KEEP | NONE| DEFAULT 

  1. KEEP和buffer_pool参数对应的keep含义一样;
  2. DEFAULT和buffer_pool参数对应的含义一样(按照类似LRU算法将长时间不用的数据从flash disk中清理出去);
  3. NONE表示不起用。

使用方法:

alter system set altdb_flash_cache_file = '/dev/raw/sda' scope=spfile;
alter system set db_flash_cache_size = 32G scope=spfile;

将db_flash_cache_size设为0 可以disable flash cache. 再设回来可以enable. 但不允许动态修改db_flash_cache_size的值.

对于RAC的环境, 需要在每个instance上面都设置以上两个参数 并且不能使用同一个file.

6) SEGMENT CREATION IMMEDIATE

立即创建段

 与 SEGMENT CREATION IMMEDIATE 相对应的是 SEGMENT CREATION DEFERRED——延迟创建段。

SEGMENT CREATION DEFERRED是 deferred_segment_creation 参数,在11.2.0.4g才有的参数, 默认是true。表示,创建一个表,在刚刚创建没有插入数据时,Oracle是否会创建对应的‘段’结构,是否分配空间,为true时,不分配空间,但在sys用户下不支持:

  1. 在sys用户下,创建一个没有数据的表时,同时自动分配空间
  2. 在普通用户下,创建一个没有数据的表时,不会分配空间

查看sql语句,是否已经分配空间:

select dbms_metadata.get_ddl('TABLE','TEST_01') from dual;

Oracle 11g EXP导出,再IMP导入时,发现导入后,出现少表,有一些数据为空的表结构没有被导入,原因是于导出时,这些空表没有被导出。也就是说:

 EXP导出时,没有 segment 的对象不会导出。

 产生“导入时少表”的原因,在于Oracle 11g 的参数  “deferred_segment_creation”。

解决方案:

1. 设置 deferred_segment_creation 的值为false

alter system set  deferred_segment_creation=false;

此方法只对以后的表有效,无论空表还是非空表都会分配segment,之前的表还是没分配空间。

2. 创建表的时候声明立即创建 Segment

 create table table_name segment creation immediate;

3.  修改 segment

对于已经创建但是还没有 Segment 的表来说,可以执行 SQL 使其创建出分配空间:

alter table table_name allocate extent

  当然也可以插入一条数据,使其创建分配空间。

下面我们接着分析下面的语句:

  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 FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
  TABLESPACE "USERS" 
 LOB ("COMMONT6") STORE AS BASICFILE (
  TABLESPACE "USERS" ENABLE STORAGE IN ROW CHUNK 8192 RETENTION 
  NOCACHE LOGGING 
  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT))

已经经过的我们不再赘述了。

9. NOCOMPRESS 和 COMPRESS

COMPRESS:压缩参数

NOCOMPRESS:不压缩,一般默认为 NOCOMPRESS

​ Compress参数含义:在存储表数据的时候是否启用压缩选项。压缩使用的级别是数据块block级别。Oracle对数据块的压缩采用相邻相同值合并的压缩算法。

Compress参数有两个系列参数:

  1. ​ OMPRESS FOR DIRECT_LOAD OPERATIONS:作用于Compress相同,适合于数据仓库OLAP系统。只在直接插入过程中在表或者分区上启用压缩技术;
  2. ​ COMPRESS FOR ALL OPERATIONS:适合于OLTP系统,针对所有的操作均启用了压缩选项。要求的版本较高。

压缩表数据该如何选择?

​表改动很小的或者几乎不改动的情况下使用compress,节省空间,提高查询的性能,
​经常改变的表不要使用压缩(nocompress),不然会使表的更新和插入操作变慢。

10. LOGGING 和 NOLOGGING

LOGGING :写入日志
NOLOGGING 表示不写入日志

 Nologging对表的某些特定操作不写入redo log, 如 insert /+ APPEND/直接插入,create table as select ……
这样做可以減少日志的生成量,加快记录的插入。但平时表的insert,update,delete 還是會写入redo log的。

11. LOB

LOB:指定存储LOBINDEX和LOBSEGMENT的表空间。
基于管理和性能的考虑,需要为LOB数据另外指定一个表空间。
LOB数据庞大,另外分配一个表空间有利于备份,恢复,空间管理。
默认情况下,LOB数据不在缓冲区缓存中进行缓存,每次访问都会带来一个物理I/O,这种情况下,把LOB数据单独储存到一个磁盘上就非常有意义。

LOB ("COMMONT6") STORE AS BASICFILE 的意思是针对大字段对象  COMMONT6 采用 BASICFILE 机制 进行存储

12. STORE AS [BASICFILE/SECUREFILE]

指定BASICFILE/SECUREFILE是11g之后增加的特性。默认为BASICFILE,这也是11g之前的唯一选择。

1)大字段类型分类

针对大字段类型,也就是打对象LOB(Large Object),Oracle有四种:

  • CLOB:字符 LOB,用于存储大量文本信息,比如XML或者纯文本,存储的内容可能会在读写时发生字符集转换
  • NCLOB:另一种LOB,可以指定保存的字符集,而不是数据库默认的字符集
  • BLOB:二进制LOB。存储二进制信息,比如文档、图像等几乎任何其他数据。不会对数据字符集进行转换,保存什么,读出来还是什么。
  • BFILE:二进制文件LOB。存储一个指向操作系统文件的指针,这个文件并不属于数据库维护。BFILE对文件内容只有读权限。

 简而言之,CLOB 和 NCLOB 保存文本信息,BLOB 保存二进制信息。

从 Oracle 11g 开始,引入了 secureFiles 新的LOB架构。11g 之前叫 BasicFiles。在 Oracle 11g 中如果不特别制定,默认创建 BasicFiles LOB,但是在 Oracle 12c 之后,LOB 列在 ASSM 管理的表空间,默认会创建 SecureFiles。

2)BASICFILE 与 SECUREFILE 对比

SecureFiles LOBs相比于BasicFiles:

LOBs具有加密(encryption)、去重(deduplicaiton)、压缩(compression)等新功能,pctversion,chunksize等参数也仅仅为了向后兼容而保留,因此SecureFiles LOBs的自适应能力更强,在管理上更为简化,成为了clob、blob等大对象使用的首选,上面的这些功能描述可以参考官方文档来获得。

注意:Oracle 官方文档已经说明,BasicFiles在或许版本中将不再使用。

SecureFiles 的好处:

  1. 比以往的 LOB 性能提高很多;
  2. 易用性(无需设置CHUNK、PCTVERSION、FREELISTS、FREELIST GROUPS、FREEPOOLS参数);
  3. SecureFiles 支持加密、压缩和去重等新功能。

将basicfile转换为securefile lob

alter table tlob move lob("b_lob") store as securefile (tablespace xxx);

 注意:

这里 move lob 段会进行锁表。如果 lob 很大会占用大量临时空间,将会导致长时间锁表。因此,最好在设计之初就将表设计为 securefile lob。

 强烈建议:使用 SecureFiles 而不是 BasicFiles。

13. ENABLE STORAGE IN ROW

控制是否将LOB数据和表分开存储。如果使用ENABLE STORAGE IN ROW,这也是默认行为,对于小的LOB(最多4000字节),就会像VARCHAR2一样直接存储在表中,这会带来性能上的提高。

14. CHUNK

LOB存储在CHUNK中;指向LOB数据的索引会指向各个CHUNK。


CHUNK是逻辑上连续的一组数据库块(block),这也是LOB的最小分配单元,而通常数据库的最小分配单元是数据库块。


CHUNK大小必须是数据库块大小的整数倍。


CHUNK大小必须合适。如果过大,会造成空间浪费;如果过小,会造成CHUNK数很多,这就会造成LOBINDEX很大,降低性能。

15.  RETENTION/PCTVERSION

LOB实现读一致性(http://blog.csdn.net/fw0124/article/details/6899246)的方式和一般的表数据有所不同。


LOBINDEX会像其他段一样生成UNDO,但是LOBSEGMENT并不使用UNDO来记录其修改,而是直接在LOBSEGMENT本身中维护数据的版本。


修改一个LOB时,Oracle会分配一个新的CHUNK,并且仍保留原来的CHUNK。如果回滚了事务,对LOB索引所做的修改会回滚,索引将再次指向原来的CHUNK。


Oracle使用LOBINDEX的读一致视图来撤销对LOB的修改,从而获得读一致性。

RETENTION子句告诉Oracle按照UNDO_RETENTION参数来决定将修改过的LOB历史数据保存在LOBSEGMENT中多久的时间。


PCTVERSION子句控制着用于保存修改过的LOB历史数据的存储空间占已分配LOB空间的百分比。

16. CACHE/CACHE READS/NOCACHE

cache 选项告诉 oracle 对于 lob 数据是否存放到缓存中。如果存放到缓存中,则在读写的时候为db file sequential reads。如果不设置cache,则使用直接路径读写。默认为不打开cache。

默认为 NOCACHE,LOB数据不在缓冲区缓存中进行缓存,每个访问都是对磁盘直接读写。

CACHE READS允许缓存从磁盘读的LOB数据,但是LOB数据的写操作直接写至磁盘。

CACHE则允许读和写时都能缓存LOB数据。

对于频繁读写,并且较小的LOB,比较适合使用缓存。

17. BFILE

BFILE类型只是操作系统上一个文件的指针。它用于为这些操作系统文件提供只读访问。
可以使用dbms_lob包,把BFILE当成一个LOB来处理。

不过需要注意的是,如果要从BFILE中加载文字数据,需要注意字符集问题。为此可以使用DBMS_LOB.LOADCLOBFROMFILE过程,它的bfile_csid参数用来指定BFILE的character set id。

18. PCTFREE对lob的影响

pctfree这个参数定义了一个块保留空间的百分比,保留空间是为了将来可能发生的更新操作,因为更新可能增大被更新行占用的空间,如果此时该块没有可利用空间,那么只有发生row migrate了,从而会降低I/O性能。换句话说,就是当一个块的利用率达到1-pctfree的时候,oracle就将该块从freelist中移除,不再向该块插入数据。所以说pctfree是控制什么时候将块从freelist中移除的。
因此对于永远或者几乎不进行update的lob表,可以将pctreee设置为0

至此,我们针对 Oracle 的建表语句分析完毕。

三、总结

 CREATE TABLE "DAKE"."STUDENT" (	
	"ID" NUMBER NOT NULL ENABLE, -- 针对非空约束进行校验,该字段不能为空
	"NAME" VARCHAR2(30) NOT NULL ENABLE, -- 同上
	"GENDER" CHAR(2) NOT NULL ENABLE, 
	"AGE" NUMBER(2,0) NOT NULL ENABLE, 
	"CLASS_ID" NUMBER NOT NULL ENABLE, 
	"ADDRESS" VARCHAR2(100), 
	"COMMONT1" NUMBER, 
	"COMMONT2" NUMBER(3,0), 
	"COMMONT3" NUMBER(10,0), 
	"COMMONT4" NUMBER(20,0), 
	"COMMONT5" NVARCHAR2(10), 
	"COMMONT6" CLOB, 
	"COMMONT7" DATE, 
	"COMMONT8" TIMESTAMP (6), 
	"COMMONT9" INTERVAL DAY (3) TO SECOND (6), 
	CONSTRAINT "STUDENT_PK" PRIMARY KEY ("ID") -- 指定主键约束
-- 使用索引,空闲百分比为10,低于10%就不在新增数据,只进行更新操作;最小事务数为2,最大为255,计算统计数据存储参数为:
-- 初始化区段(extent)大小65536,一次扩展64k,并分配下一个空间片段大小为1048576,最小区段为1,最大区段为2147483645
-- 增长百分比0,空闲链表1,空闲链表组1,缓冲池采用默认的缓存方式缓存数据,FLASH_CACHE 和 CELL_FLASH_CACHE 两个缓存对象也采用默认方式进行缓存
-- 指定表空间为 USERS,并针对以上约束进行校验,然后立即创建段,创建段结构并分配空间。
	USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS 
	STORAGE(
	INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
	PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
	TABLESPACE "USERS"  ENABLE
) SEGMENT CREATION IMMEDIATE 
-- 空闲百分比是10,数据块数据低于40%时开始新增数据;初始化事务大小1,最大事务大小255;不压缩方式记录日志,存储情况为:
-- 初始化区段大小为......
	PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255 NOCOMPRESS LOGGING
	STORAGE(
		INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
-- 增长百分比为0,空闲链表1,空闲链表组1,缓冲池采用默认的缓存方式存储
		PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT
  )
  TABLESPACE "USERS" 
-- 针对大字段对象  COMMONT6 采用 BASICFILE 机制 进行存储:
-- 表空间为 USERS 并进行约束校验,对于小的LOB(最多4000字节),就会像VARCHAR2一样直接存储在表中;
-- 指定 CHUNK 数据库大小为8192,Oracle按照UNDO_RETENTION参数来决定将修改过的LOB历史数据保存在LOBSEGMENT中多久的时间;
-- LOB数据不在缓冲区缓存中进行缓存,每个访问都是对磁盘直接读写,并记录日志,存储情况为......
	LOB ("COMMONT6") STORE AS BASICFILE (
		TABLESPACE "USERS" ENABLE STORAGE IN ROW CHUNK 8192 RETENTION 
		NOCACHE LOGGING 
		STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
		PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
	) 

参考文章

数据库数据导出建表SQL解析

《Oracle编程艺术》学习笔记(37)-数据类型-LOB

Oracle11gR2 Smart Flash Cache测试说明

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐