发表于: 2009.01.17 23:45
分类: ORACLE
出处: http://yangtingkun.itpub.net/post/468/477286
---------------------------------------------------------------
第一次看CONCEPT的时候,一直不是很明白,Oracle索引组织表中逻辑ROWID的物理猜是如何实现的,而这次看的时候很自然的就想明白其中的实现。
Oracle的普通表即堆表,存储数据时没有顺序可言,而Oracle的索引组织表是根据主键顺序来存储表中的数据的。
如果表中的数据都是通过主键来访问,那么没有任何,可是很多时候,需要在表上建立除主键之外的索引,而这就导致了一个问题。
对于普通表而言,Oracle保证数据插入到表中之后,数据的物理地址ROWID不会再发生改变。当然对表进行MOVE,或者ENABLE ROW MOVEMENT之后对分区表的分区键值进行修改等明确导致表数据位置发生变化的操作除外。也就是说,普通的增、删、改不会导致现有记录的物理地址发生变化。即使记录的长度发生了变化,导致当前数据块中无法容纳这条记录,Oracle也会在原位置上留下一个ROWID信息,通过这个ROWID信息可以找到这条记录的新的位置。这也就是行迁移、行链接的实现方式。虽然增加了额外的IO,但是确保了ROWID不发生变化。
索引正是利用了这种特性。索引中包括被索引的字段和这条记录的ROWID,Oracle在索引中找到对应的键值后,根据这个键值对应的ROWID,就可以找到表中的这条对应的记录。正是ROWID不发生变化的特性使得索引可以正常的工作。可以看到,前面提到的MOVE,以及一些导致ROWID发生变化的分区操作,在使得ROWID变化的同时,也会导致索引处于不可用状态。
那么现在存在一个问题,对于索引组织表而言,为了保证数据存储是根据主键顺序进行的,就必须根据数据的增、删、改随时调整表中数据的位置,这使得ROWID不发生改变这个前提无法实现。而对于索引组织表,第二个索引需要一个方法来找到表中数据的具体位置,因此也就有了逻辑ROWID。
对于索引组织表,虽然存储位置可能会经常发生变化,但是主键是必须存在的。如果不能通过物理位置来寻找,那么通过主键来查找也可以找到这条记录。不过Oracle的实现并不是这么简单。
逻辑ROWID除了包含表的主键信息外,还包括了这条记录在索引创建时的物理地址信息。关于逻辑ROWID相信结构描述,可以参考:http://yangtingkun.itpub.net/post/468/11363。
而这个地址信息,就是用来实现物理猜的。如果物理猜能够在目标数据块中找到这条记录,那么这个效率和物理ROWID的效率是一样的,只需要一次IO就找到了目标。如果通过物理猜找不到对应的记录,那么Oracle只能通过逻辑ROWID中包含的主键信息,通过主键扫描来定位这条记录,根据索引的层高,这个操作可能会多消耗几次IO操作。
学习Oracle其实就是一个不断积累的过程,如果基础打的比较扎实,再加上足够的积累,那么对数据库的知识和概念的理解都是水到渠成的。











