《Oracle 数据结构知多少》  
感兴趣的朋友,浏览《Oracle 数据结构知多少(一)》 
http://space.itpub.net/26686207/viewspace-757937
本周又要继续开始“Oracle 数据结构系列之二”重点讲述表空间的存储属性,数据块的压缩,段空间存储属性等知识,欢迎广大亲们一起交流讨论,营造一个专家圈子,一起更上一层楼。长话短说,进入正题。我们在上一节已经把segment-extent-block概念一一讲明了,这里呢我们主要讲一讲它们在生产库上应用场景和如何设置。
二 数据库版本
LEO1@LEO1>select * from v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
PL/SQL Release11.2.0.1.0 - Production
CORE    11.2.0.1.0      Production
TNS for Linux:Version 11.2.0.1.0 - Production
NLSRTL Version11.2.0.1.0 - Production
三 实验
1.创建表,分区表,大对象字段,分别查询出它们是否为段对象,给出SQL演示的整个过程。
段对象:Oracle所有分配存储空间的对象都叫段对象。例如 表 索引 分区 大对象等都称之为段对象
段对象是接近于应用层的,它是业务层面的一个含义,表空间逻辑上是由段对象组成的。
段的种类
数据段
LEO1@LEO1>create table t1 (x int,y int);        创建个表
Table created.
LEO1@LEO1>create index idx_t1 on t1(x);       表上创建个索引
Index created.
LEO1@LEO1>insert into t1 values(1,1);         只有插入数据后oracle才会真正创建索引
1 row created.
LEO1@LEO1>commit;
Commit complete.
LEO1@LEO1>select * from t1;
         X          Y
----------------------------------
1                                       1
select segment_name,segment_type,tablespace_name,extents,blocks,bytes/1024/1024from dba_segments where segment_name in ('T1','IDX_T1');
SEGMENT_NAMESEGMENT_TYPE  TABLESPACE_N  EXTENTS  BLOCKS  BYTES/1024/1024
------------------------------------------ ------------------ ------------------------------- ------------------------------
T1             TABLE         LEO1          1        8      .0625
IDX_T1         INDEX          LEO1          1        8      .0625
上面的表和索引都占用空间(多少extent block  容量),因此都可称为段对象
临时段
是临时表和中间状态的数据存储放的位置,常用于sort hash merge,不用永久保存,只做临时存储,临时段组成了临时表空间,只有在内存不够时,oracle才会在临时表空间上创建临时段。
注意:临时段上的操作不产生redo,因为无需保护,是一种中间状态,这样可以提高效率
LEO1@LEO1>select file#,name,status,enabled,bytes,blocks,block_size from v$tempfile;
FILE#   NAME                          STATUS  ENABLED  BYTES     BLOCKS BLOCK_SIZE
--------------------------------------------------------------------------------------------------------------------------------
1   /u01/app/oracle/oradata/LEO1/temp01.dbf   ONLINE READ WRITE 128974848 15744      8192
经过查看临时段也分配存储空间了,块大小8k,15744个块,大小为128974848字节,因此说临时表 索引啊都可以称之为段对象,临时表的使用和演示后面进行,敬请期待!
回滚段
《Oracleundo我们需要掌握什么》 
http://space.itpub.net/26686207/viewspace-757488这篇文章对undo段做了非常详细介绍,朋友们可以参考。
这里我们只是演示一下undo段所占用的空间
LEO1@LEO1>select tablespace_name,file_name,bytes/1024/1024,autoextensible fromdba_data_files where tablespace_name='UNDOTBS1';
TABLESPACE_N   FILE_NAME                              BYTES/1024/1024   AUT
---------------------------------------------------------------------------------------------------------------------------------
UNDOTBS1      /u01/app/oracle/oradata/LEO1/undotbs01.dbf   165             YES
这就是undo表空间对应的undo数据文件,在数据库需要做回滚时就在undo表空间中创建undo段。
分区表的段对象
分区表中,一个分区对应一个段对象,如果有3个分区那么这张分区表就包含3个段对象,这时表已经不是段对象了,倒成了一个标签。
LEO1@LEO1>create tablespace par_data01 datafile size 10M autoextend off;
Tablespacecreated.
LEO1@LEO1>create tablespace par_data02 datafile size 10M autoextend off;
Tablespacecreated.
LEO1@LEO1>create tablespace par_data03 datafile size 10M autoextend off;
Tablespacecreated.
创建三个表空间分别存储三个分区
LEO1@LEO1>create table part_leo (name varchar2(20),age number,part_date date);
Table created.
LEO1@LEO1>insert into part_leo values ('leonarding1',100,to_date('2001-01-01','yyyy-mm-dd'));
insert intopart_leo values ('leonarding2',200,to_date('2002-02-02','yyyy-mm-dd'));
insert intopart_leo values ('Alan1',300,to_date('2003-03-03','yyyy-mm-dd'));
insert intopart_leo values ('Alan2',400,to_date('2004-04-04','yyyy-mm-dd'));
insert intopart_leo values ('tigerfish1',500,to_date('2005-05-05','yyyy-mm-dd'));
insert intopart_leo values ('tigerfish2',600,to_date('2006-06-06','yyyy-mm-dd'));
LEO1@LEO1>commit;
Commit complete.
LEO1@LEO1>select * from part_leo;
NAME                           AGE PART_DATE
--------------------------------- ---------
leonarding1                    100 01-JAN-01
leonarding2                    200 02-FEB-02
Alan1                          300 03-MAR-03
Alan2                          400 04-APR-04
tigerfish1                     500 05-MAY-05
tigerfish2                     600 06-JUN-06
创建一个表并插入6行记录,做分区表的原表
LEO1@LEO1>CREATE TABLE part_leo_super      
   PARTITION BY RANGE (part_date)
     ( PARTITION p1 VALUES LESS THAN(to_date('2002-12-01','yyyy-mm-dd'))
        TABLESPACE par_data01,      比2002-12-01小的记录放入p1分区
       PARTITION p2 VALUES LESS THAN(to_date('2004-12-01','yyyy-mm-dd'))
        TABLESPACE par_data02,      比2004-12-01小的记录放入p2分区
       PARTITION p3 VALUES LESS THAN(to_date('2006-12-01','yyyy-mm-dd'))
        TABLESPACE par_data03,      比2006-12-01小的记录放入p3分区
       PARTITION other VALUES LESS THAN(maxvalue)
        TABLESPACE par_data03)      余下的记录放入par_data03分区
   as select * from part_leo;  2   3    4    5    6   7    8    9  10   11  
Table created.
采用CTAS方式创建分区表,三个分区分别存放在三个表空间上
LEO1@LEO1>select * from part_leo_super partition (p1);         第一分区的数据
NAME                           AGE PART_DATE
--------------------------------- ---------
leonarding1                    100 01-JAN-01
leonarding2                    200 02-FEB-02
LEO1@LEO1>select * from part_leo_super partition (p2);         第二分区的数据
NAME                           AGE PART_DATE
--------------------------------- ---------
Alan1                          300 03-MAR-03
Alan2                          400 04-APR-04
LEO1@LEO1>select * from part_leo_super partition (p3);         第三分区的数据
NAME                           AGE PART_DATE
--------------------------------- ---------
tigerfish1                     500 05-MAY-05
tigerfish2                     600 06-JUN-06
LEO1@LEO1>select segment_name,partition_name,tablespace_name,extents,blocks,bytes/1024/1024from dba_segments where segment_name='PART_LEO_SUPER';
SEGMENT_NAME    PARTITION_NAME   TABLESPACE_N    EXTENTS    BLOCKS    BYTES/1024/1024
----------------------------------------------------------------------------------------------------------------------------------------
PART_LEO_SUPER  OTHER        PAR_DATA03    1          8        .0625
PART_LEO_SUPER  P1             PAR_DATA03    1         8        .0625
PART_LEO_SUPER  P2             PAR_DATA03    1          8       .0625
PART_LEO_SUPER  P3            PAR_DATA03   1          8        .0625
每个分区都有独立的存储空间,因此可以说每个分区都是一个段对象(PARTITION_NAME)PART_LEO_SUPER这个名在分区表中不算段名了可以看成一个总名称!
大对象字段的段对象
我们为什么要创建大对象字段,普通的varchar2字段:最大支持4000个字符!
如果我们想在字段中存放一篇小说,一个文章,一篇blog怎么办?大对象字段就是解决这个问题的。
注:大对象与小对象字段的长度不一致导致碎片的一个原因,一般把大对象单独放在一个表空间中减少碎片的产生。
创建存放CLOB字段的表空间clob_data
LEO1@LEO1>create tablespace clob_data datafile size 10M autoextend off;
Tablespacecreated.
创建含CLOB(character large object)字段表
LEO1@LEO1>create table clob_table
    (
    name varchar2(20),                  姓名
    employment varchar2(30),              职业
    school varchar2(30),                   毕业院校
    current_date date,                    当前时间
    discription clob                       描述(字符型大对象字段)
    )
   tablespace leo1                        存放于leo1表空间
   lob (discription)                        指定大对象字段
   store as
      (
       tablespace clob_data                大对象存放的表空间
      );
  2   3    4    5   6    7    8   9   10   11  12   13   14  
Table created.
我们通过下列数据字典找到刚刚创建的大对象
LEO1@LEO1>select table_name,column_name,segment_name,tablespace_name from dba_lobs wheretable_name='CLOB_TABLE';
TABLE_NAME   COLUMN_NAME SEGMENT_NAME               TABLESPACE_N
--------------------------------------------------------------------------------------------------------------------
CLOB_TABLE    DISCRIPTION     SYS_LOB0000074408C00005$$    CLOB_DATA
小结:由此看来大对象字段也占用表空间,凡是占用空间的对象都可称为段对象。
2.分别创建一个ASSM,MSSM管理的表空间。
MSSM—ManualSegment Space Management 手动段空间管理(手动设置对象的存储属性)
这种管理方式就是使用freelist管理数据块的分配和回收,是一种只针对数据块分配的管理方式,这种方式可以让DBA有更大的空间管理余地,更大自由发挥空间,在早期的Oracle上都是通过这种方式管理块分配的。
场景:对于一些数据块操作非常敏感的场合相对适用
参数:MSSM-由你设置freelists、freelistgroups、pctused、pctfree、initrans等参数来控制如何分配、使用段中的空间
缺点:1.需要设置更多的参数,例如上面所写的参数,操作复杂度更强
      2.参数设置值比较难评估,需要大量的测试过程
      3.需要了解数据库体系结构的DBA设置
注意:1.freelist空闲列表是放在段头里面的,如果有多个用户同时访问列表势必会引发段头争用,导致“buffer busy waits”等待事件发生,建议多设几个freelist,防止争用。
ASSM—AutomaticSegment Space Management 自动段空间管理(自动设置对象的存储属性)
这种管理方式就是使用“位图bitmap”管理数据块的分配和回收,1为占用块不可分配,0为空闲块可分配,由于计算机就是由二进制编码的,所以操作二进制代码是非常快捷的。现在Oracle 10g 11g 默认值都是ASSM段空间管理方式。
场景:希望数据块由Oracle自动分配管理的场合,不需要DBA介入太多
参数:ASSM-你只需控制一个参数pctfree,其他参数由Oracle自动管理,如果强行设置也将被忽略。
三层位图模式管理段空间:第一层BMB(bit map block)记录每个extent中数据块的存储信息,只管理当前的extent内块,放在extent头中,这是leaf节点
             第二层BMB管理第一层BMB记录,这是branch节点
             第三层BMB管理第二层BMB记录,放在段头中,这是root节点
ASSM段头包含了每个Extent存储信息
Extent区头包含BMB信息
优点:1.自动化管理段空间,无需手动设置大量参数,简化了操作
2.增大并发度,由于ASSM没有freelist概念,也就没有freelist列表争用情况,也就没有段头争用的情况,提高资源利用率。
缺点:1.全表扫描性能没有MSSM模式下好
      2.大数据加载,会导致性能下降,因为要自动维护位图表,需要一定的开销
      3.影响索引的集群因子(clustering factor)
(1) 设置db_create_file_dest参数
作用:指定Oracle创建某某文件的存放路径,设置后就可以在创建表空间时不指定文件路径了。
■ Datafiles
■ Tempfiles
■ Redo log files
■ Control files
■ Block change tracking files
LEO1@LEO1> showparameter db_create_file_dest
NAME                                 TYPE        VALUE
----------------------------------------------- ------------------------------
db_create_file_dest                      string
空,我们现在还没有初始化这个参数值
LEO1@LEO1>alter system set db_create_file_dest='/u01/app/oracle/oradata/LEO1/';
System altered.
LEO1@LEO1> showparameter db_create_file_dest  
NAME                                 TYPE        VALUE
----------------------------------------------- ------------------------------
db_create_file_dest                      string     /u01/app/oracle/oradata/LEO1/
现在我们已经设置好了参数
(2)创建MSSM和ASSM表空间
LEO1@LEO1>create tablespace leo_mssm segment space management manual;
Tablespacecreated.
LEO1@LEO1>create tablespace leo_assm segment space management auto;
Tablespacecreated.
我们创建了一个MSSM段管理表空间又创建一个ASSM段管理表空间,默认大小100M
LEO1@LEO1>select file#,name,bytes/1024/1024 from v$datafile;
FILE#   NAME                                                            BYTES/1024/1024
----------------------------------------------------------------------------------------------------------------------------------------------
9      /u01/app/oracle/oradata/LEO1/LEO1/datafile/o1_mf_leo_mssm_8p9jorpx_.dbf  100
10     /u01/app/oracle/oradata/LEO1/LEO1/datafile/o1_mf_leo_assm_8p9jplb8_.dbf   100
数据文件名是系统自定义的。
LEO1@LEO1>select tablespace_name,segment_space_management from dba_tablespaces wheretablespace_name in ('LEO_MSSM','LEO_ASSM');
TABLESPACE_N  SEGMEN
----------------------------------
LEO_ASSM      AUTO
LEO_MSSM     MANUAL
小结:我们根据实际需要来创建与业务匹配的表空间,宗旨技术为业务服务。