堆组织表,索引组织表和索引聚簇表

来源:互联网 发布:淘宝秒刷销量软件 编辑:程序博客网 时间:2024/05/17 22:40
1. 堆组织表:
   通常我们默认建的表就是堆组织表。
   语法:Create table test(  
    Id int,  
    Name varchar2(10)  
  );
   此类型的表中,数据会以堆的方式进行管理,增加数据时候,会使用段中找到的第一个能放下
   此数据的自由空间。当从表中删除数据时候,则允许以后的UPDATE和INSERT重用这部分空间,
   它是以一种有些随机的方式使用。
   
   很多初学者会想当然的以为数据的插入会按顺序进行,第一条肯定排在第一位,接着是第二条,一直到最后。
   可当SELECT查询的时候,返回的结果往往让人失望。排列的顺序让人大跌眼镜,下面来看一个例子。
   
   create table t(   
   a int,  
   b varchar2(4000) default rpad('*', 4000, '*'),  
   c varchar2(3000) default rpad('*', 3000,'*')  
 );  
   
 insert into t(a) values (1);  
 insert into t(a) values (2);  
 insert into t(a) values (3);  
 delete from t where a=2;  
 insert into t(a) values (4);  
   
 SQL> select a from t;  
   
          A  
 ----------  
          1  
          4  
          3 

  全表扫描时,会按命中的顺序来获取数据,而不是按插入的顺序。
  这是一个必要要了解的重要的数据库概念。一般来说,数据库表本质上是无序的数据组合。 
  
2. 索引组织表(index organized table, IOT):就是存储在一个索引结构中的表,数据按主键进行存储和排序。
   适用的场景:
    a.完全由主键组成的表。这样的表如果采用堆组织表,则表本身完全是多余的开销,
      因为所有的数据全部同样也保存在索引里,此时,堆表是没用的。
    b.代码查找表。如果你只会通过一个主键来访问一个表,这个表就非常适合实现为IOT.
 c.如果你想保证数据存储在某个位置上,或者希望数据以某种特定的顺序物理存储,IOT就是一种合适的结构。 IOT提供如下的好处:
  ·提高缓冲区缓存效率,因为给定查询在缓存中需要的块更少。
  ·减少缓冲区缓存访问,这会改善可扩缩性。
  ·获取数据的工作总量更少,因为获取数据更快。
  ·每个查询完成的物理I/O更少。
   如果经常在一个主键或唯一键上使用between查询,也是如此。如果数据有序地物理存储,就能提升这些查询的性能。
    语法:create table indexTable(
  ID varchar2 (10), 
  NAME varchar2 (20), 
  constraint pk_id primary key (ID)
  ) organization index;
3. 索引聚簇表:
   聚簇是指:如果一组表有一些共同的列,则将这样一组表存储在相同的数据库块中;聚簇还表示把相关的数据存储在同一个块上。
   利用聚簇,一个块可能包含多个表 的数据。概念上就是如果两个或多个表经常做链接操作,那么可以把需要的数据预先存储在一起。
   聚簇还可以用于单个表,可以按某个列将数据分组存储。  
   语法:
   索引聚簇表是基于一个索引聚簇(index cluster)创建的。
   里面记录的是各个聚簇键。聚簇键和我们用得做多的索引键不一样,索引键指向的是一行数据,
   聚簇键指向的是一个ORACLE BLOCK。我们可以先通过以下命令创建一个索引簇。
   create cluster emp_dept_cluster
  ( deptno number(2) )
  size 1024
  /

   size参数:
   向聚簇中放数据之前,需要先对聚簇建立索引。可以现在就在聚簇中创建表,
   但是由于我们想同时创建和填充表,而有数据之前必须有一个聚簇索引,所以我们先来 建立聚簇索引。
   create index emp_dept_cluster_idx
  on cluster emp_dept_cluster
  /
    
    建表:
    create table dept
  ( deptno number(2) primary key, 
      dname varchar2(14),
    loc varchar2(13)
  )
  cluster emp_dept_cluster(deptno)
  /

    create table emp
  (  empno    number primary key, 
 ename    varchar2(10), 
 job      varchar2(9), 
 mgr      number, 
 hiredate date, 
 sal      number, 
 comm     number,
   deptno number(2) constraint emp_fk references dept(deptno)
  ) cluster emp_dept_cluster(deptno)
    /

   什么时候不应该使用聚簇?
   1) 如果预料到聚簇中的表会大量修改:
    必须知道,索引聚簇会对DML的性能产生某种负面影响(特别是INSERT语句)。管理聚簇中的数据需要做更多的工作。
  2) 如果需要对聚簇中的表执行全表扫描:不只是必须对你的表中的数据执行全面扫描,
   还必须对(可能的)多个表中的数据进行全面扫描。由于需要扫描更多的数据, 所以全表扫描耗时更久。
  3) 如果你认为需要频繁地TRUNCATE和加载表:聚簇中的表不能截除。
 这是显然的,因为聚簇在一个块上存储了多个表,必须删除聚簇表中的行。

  因此,如果数据主要用于读(这并不表示“从来不写”;聚簇表完全可以修改),
 而且要通过索引来读(可以是聚簇键索引,也可以是聚簇表上的其他索引),
 另外 会频繁地把这些信息联结在一起,此时聚簇就很适合。