聚簇表

来源:互联网 发布:凯英网络 编辑:程序博客网 时间:2024/06/14 05:08

  截至目前,我们已经对堆表和索引组织表的相关内容予以充分说明。我们知道,在处理海量数据时,由于堆表需要执行大量的随机读,这就在很大程度上增加了读取代价;尽管索引组织表在特定的读取要求下不再需要执行随机读,但当存在多样化的读取类型时也同样需要付出非常大的读取代价,这使得索引组织表也无法适用于海量数据的处理。

  对于海量数据处理而言最有用使用价值的就是聚簇

   “聚簇”这个概念不仅被使用在关系型数据库中,而且在其他类型的数据库或操作系统中也经常被使用。这里所提及的聚簇与其他类型的聚簇是完全不同的概念

 

 

      聚簇的概念会随着DBMS的不同而有所不同,但使用聚簇所追求的目标几乎都是相同的。这里主要针对oracle的聚簇进行详细说明。聚簇就像表和索引一样是拥有自己独立存储空间的一种对象

表是索引的上级概念一样聚簇是表的上级概念。虽然各自都是相互独立的对象,但是在概念上却有一定的从属性。换言之,可以在使用聚簇所创建的对象中创建表。由于在没有表的聚簇中不能插入任何数据,所以没有表的聚簇是毫无意义的。为了帮助各位读者进一步了解聚簇的概念,下面列举一些比喻来对其进行说明。

聚簇表其实就是把相同聚簇键放在相同或相邻的数据块中,这样从而提高了聚簇因子的效率,从而提高了查询速度。

 

某个地区(table space)盖了很多工厂(table),这些工厂所占用的土地都是提前规划好的区域(segment),各个工厂需要把自己所加工过的半成品(row)作为原材料运输到其他工厂去进行加工,当然在运输的过程中道路(relationship)是不可缺少的前提条件,这些道路错综复杂、四通八达。对特定的原材料经过一系列的加工(process)最终生产出成品(application).

 

如果经常需要向比较远的工厂供货(join),则由于增加了运输单价(clustering factor,增加了费用(costresource)开支,这就严重影响了生产效率(performance)。在此情况下,为了缩减成本开支,提高生产效率,将经常需要运输产品的两个工厂设在相互临近的地方(在相同的聚簇中创建表),并通过履带(cluster)向两个互相连接(Join)的工厂传输产品。这样的做法就可以在很大程度上缩减运输成本的开支。为了这样的目的而把表进行聚簇的方法称为“复合表聚簇”

 

聚簇是指:如果一组表有一些共同的列,则将这样一组表存储在相同的数据库块中;聚簇还表示把相关的数据存储在同一个块上。利用聚簇,一个块可能包含多个表的数据。概念上就是如果两个或多个表经常做链接操作,那么可以把需要的数据预先存储在一起。聚簇还可以用于单个表,可以按某个列将数据分组存储。

更加简单的说,比如说,EMP表和DEPT表,这两个表存储在不同的segment中,甚至有可能存储在不同的TABLESPACE中,因此,他们的数据一定不会在同一个BLOCK里。而我们有会经常对这两个表做关联查询,比如说:select * from emp,dept where emp.deptno = dept.deptno .仔细想想,查询主要是对BLOCK的操作,查询的BLOCK越多,系统IO就消耗越大。如果我把这两个表的数据聚集在少量的BLOCK里,查询效率一定会提高不少。

比如我现在将值deptno=10的所有员工抽取出来,并且把对应的部门信息也存储在这个BLOCK里(如果存不下了,可以为原来的块串联另外的块)。这就是索引聚簇表的工作原理。

注:讲到这里,聚簇是针对两个表关联进行一种最优的方式。如果把两个表访问的数据行存放在同数据块中,就能提高查询效率。在很大程度上,优化就是针对数据块来进行操作的(除并行外)。

  

 

 

单表聚簇:

 

     单表聚簇是指在指定的聚簇中只创建一个表的聚簇结构。由于拥有相同聚簇键值的行被集中存储在相同的位置上,所以在读取大范围数据时灵活运用该结构能够在很大程度上提高数据的读取效率。关于它的具体特征和使用准则将在后面予以详细说明。

 

     有一个比较特殊的地方需要各位读者注意,即虽然在单位聚簇中的每一个行的前面都列举出了聚簇值,但在实际物理存储中相同的聚簇键值只被存储一次。不仅在数据块头部也存储着聚簇键ID和聚簇键值。复合表聚簇也同样具有这样的特征,即位于不同表中的相同聚簇键值只被存储一次。

     利用这种结构可以在很大程度上提高数据的读取效率,但这种存储结构同样具有无法避免的缺陷。当聚簇键值被修改时将会发生怎样样的事情呢?位于指定位置上的聚簇键值被修改,则意味着它不能继续停留在原来的单位聚簇中,只能移动到与其修改后的值所对应的单位聚簇中。由于聚簇键位置的移动与ROWID变化具有相似的概念,所以它将对聚簇产生致命性的影响。

 

   我们知道,在堆表中当一个行被存储在一个已有数据块时,可以利用行迁移的方法来确保其ROWID不发生任何变化。即让ROWID仍然停留在原来的位置,只把行中的数据移动到新的位置上。这种方法不仅简单,而且也确保了ROWID不会发生任何变化,所以堪称最理想的方法

为了进一步理解聚簇的概念,我们把聚簇看做是表的一个更高阶段的抽象。从这个角度来思考聚簇,复杂的问题就变得比较简单了。即把一个单位聚簇看做是一般表的一行,把单位聚簇中的每一行看做是一般表的一个列。

 

聚簇表之所以能够在如此大的程度上提高数据的读取效率,并不是因为它具有某种特殊的数据处理机制,而是因为在此结构中只要读取一个索引行就能够连续读取多个数据行。聚簇索引与一般索引相比除了这一差异之外再无其他任何差异。

 

 

 

 

    

复合聚簇:

 

   复合表聚簇是指在一个单位聚簇中存储两个或两个以上的表聚簇结构。由于具有相同聚簇键值的不同表中的行被存储在相互邻近的位置上,所以在执行表连接时能够在很大程度上提高执行速度。

 

  尽管两个表被存储在同一个单位聚簇中,但这并没有破坏它们之间的独立性。表被创建在任意位置上之间的独立性不会受到任何影响,我们把这个属性称之为局部透明性。从逻辑上看,表所处的特殊位置其实也只不过是任意位置中的某一个位置而已。因此,即使我们把表创建在任意位置上也同样还会破坏它们之间的独立性。

 

   聚簇中各个独立的表不仅可以被单独读取,而且也可以创建自己独立的索引。我们知道,之所以把两个或两个以上的表以聚簇的形式来进行存储,主要是为了提高这些表的连接效率

 

   如果聚簇表的聚簇键值被修改,则会由于聚簇键值的修改而导致数据块链接现象的发生,从而在一定程度上降低聚簇的效率。然而,这与文件系统根本就不允许对记录键值进行修改相比,并不能认为聚簇的修改代价比文件系统的修改代价大。

 

 

聚簇表的代价:

 

单表聚簇解决了关系型数据库中最难解决的问题-大范围数据处理复合聚簇则在很大程度上提高了特定表连接的效率。因此,聚簇的这些特征在提高数据读取效率方面发挥着巨大的作用。然而,我们知道“世界上没有免费的午餐”,有所得必然会有所失,虽然我们使用聚簇实现了提高数据读取效率的目的,但我们也必须为此付出相应的代价。

 

 例如某个棒球队由于缺乏优秀选手而每次都无法赢得棒球队而言,当务之急是物色一些优秀的选手来弥补缺陷,但需要考虑的就是是否能够支付得起优秀选手的高额工资。如果能够利用一名非常优秀的选手替代相对较差的选手,则相对整个球队的费用开支而言,其实并没有太大增加。

因此,问题的焦点就可以归纳为两点:第一,能在多大程度上解决紧要问题;第二,为了解决该紧要问题需要付出多大代价。

 

  聚簇只是在数据查询时能够提高数据的读取效率,但在数据插入、修改、删除中却需要付出额外的代的价。因此,如何能把效率和代价较好地协调在一起是使用好聚簇的关键问题。在我们说明聚簇准则之前,首先应当对聚簇的代价有一个正确理解,因为它对正确选择聚簇有很大的帮助。

0 0
原创粉丝点击