索引组织表是存储在B-树索引结构的一种变体中的表。在堆组织表中,行被插入到适合他们的位置。在索引组织表中,行被存储在表的主键索引中。在B-树中的每个索引条目也存储非键列值。因此,索引即是数据,数据也是索引。同堆组织表一样,应用程序使用SQL语句操作索引组织表。
给索引组织表打个比喻,假设人事经理有一箱纸盒。给每个盒子贴上1、2、3、4等标签,但这些盒子在书架上并不是顺序排放的。相反,每个盒子包含一个指针,指示序列中的下一个盒子的位置。
包含雇员记录的文件夹存储在每个盒子中。文件夹按雇员id排序。员工King的ID最低,为100,所以他的文件夹在第1盒的底部。雇员101的文件夹在100的之上,102的在101的之上,如此等等,直到盒子1已满。序列中的下一个文件夹在盒子2的底部。
在这个比喻中,将文件夹按雇员ID排序,使得能够有效地搜索文件夹,而无需维护一个单独的索引。假设用户请求雇员107、120、和122的记录。人事经理不需在一个步骤中搜索索引、然后又在另一步骤中检索文件夹,他可以按顺序搜索文件夹,并同时检索每个找到的文件夹。
通过主键或有效的前缀,索引组织表提供了对表行更快的访问。非键列存在于索引叶块中,避免了额外的数据块I/O。例如,雇员100的薪酬存储在索引行本身中。此外,因为行是以主键顺序存储的,通过主键或前缀进行范围访问只涉及最少的块I/O。另一个好处是避免一个单独的主键索引的空间开销。
当有关的数据片断必须存储在一起,或数据必须按特定的顺序物理地存储时,索引组织表很有用。这种类型的表通常用于信息检索、空间(请参阅"Oracle空间概述")、和OLAP应用程序
索引组织表特征
数据库系统通过操作B-树索引结构,来在索引组织表上执行所有操作。表3-4总结了索引组织表和堆组织表之间的差异。
表3-4堆组织表和索引组织表的比较

图3-3显示了一个索引组织表departments的结构。叶块包含的表行,按主键顺序排序。例如,在第一个叶块中的第一个值显示其部门ID20,部门名称为Marketing、经理ID为201、位置ID为1800。
图3-3索引组织表

索引组织表将所有数据都存储在相同的结构中,且不需要存储rowid。如图3-3,索引组织表中的叶块1可能包含如下按主键排序的条目:
20,Marketing,201,1800
30,Purchasing,114,1700
索引组织表中的叶块2可能包含如下所示的条目:
50,Shipping,121,1500
60,IT,103,1400
按主键顺序对索引组织表行的扫描,依照如下顺序读取块:
1.块1
2.块2
对比索引组织表和堆组织表中的数据访问,假定departments堆组织表段的块1包含的行,如下所示:
50,Shipping,121,1500
20,Marketing,201,1800
同一个表中块2包含的行,如下所示:
30,Purchasing,114,1700
60,IT,103,1400
此堆组织表的B-树索引中的一个叶块包含如下条目,其中的第一个列值是主键,第二个列值是rowid:
20,AAAPeXAAFAAAAAyAAD
30,AAAPeXAAFAAAAAyAAA
50,AAAPeXAAFAAAAAyAAC
60,AAAPeXAAFAAAAAyAAB
因此,在此示例中的块I/O数目是在索引组织表示例中的2倍。
索引组织表的行溢出区
在创建一个索引组织表时,您可以指定一个单独的段为行溢出区。索引组织表的B-树索引条目可能比较大,因为它们包含整个行,因此用一个单独的段来包含这些条目是很有用的。相比之下,常规B-树条目则通常很小,因为它们仅包含键和rowid。
如果指定了行溢出区,那么数据库可以将索引组织的表中的行分成以下两个部分:
•索引条目
本部分包含所有主键列的值、指向该行溢出部分的物理rowid、或(可选的)几个非键列的值。这部分存储在索引段中。
•溢出部分
此部分包含剩余的非键列的值。这部分存储在溢出存储区段中。
索引组织表的辅助索引
辅助索引是一个建立在索引组织表上的索引。在某种意义上,它是一个索引的索引。辅助索引是一个独立的模式对象,并与索引组织表分开存储。
如"Rowid数据类型"中所述,数据库使用叫做逻辑rowids的行标识符来访问索引组织表。逻辑的rowid是表主键的base64编码表示形式。逻辑rowid的长度取决于主键长度。
由于插入操作,索引叶块中的行可以在块内或块之间移动。索引组织表中的行像堆组织表那样迁移行(请参阅"链接行和迁移行")。因为索引组织表中的行并没有永久的物理地址,数据库使用基于主键的逻辑rowids。
例如,假设departments表是索引组织表。location_id列中存储每个部门的ID。表像如下所示这样存储行,最后一个值是是位置ID:

辅助索引对索引组织表提供快速、高效的访问,但使用的列既不是主键也不是主键前缀。例如,查询其ID大于1700的部门的名称,可以使用辅助索引以加快数据访问。
逻辑Rowids和物理猜想
辅助索引使用逻辑rowids来查找表行。逻辑的rowid包括一个物理猜测,是索引条目第一次被创建时的物理rowid。Oracle数据库可以使用物理猜测,直接探入索引组织表的叶块,以绕过主键搜索。当行的物理位置更改了,即使它包含的物理猜测已经过时,其逻辑rowid仍然保持有效。
对于堆组织表,按辅助索引访问涉及对辅助索引的扫描,和一个读取行所在数据块的额外I/O。对于索引组织表,按辅助索引访问取决于物理猜测的使用及其准确性:
•不用物理猜测,则访问包括两个索引扫描:先是一个对辅助索引的扫描,然后是一个对主键索引的扫描。
•使用物理猜测,则访问取决于其准确性:
o如果物理猜测准确,则访问包括一个辅助索引扫描,和一个读取行所在数据块的额外I/O。
o如果物理猜测不准确,则访问包括一个辅助索引扫描,和一个读取错误的数据块I/O(即猜测所指出的),再是一个按主键值对索引组织表的唯一索引扫描。
索引组织表上的位图索引
索引组织表上的辅助索引可以是位图索引。如"位图索引"所述,位图索引为每个索引键存储一个位图。
当索引组织表上存在位图索引时,所有位图索引都使用堆组织映射表。映射表将存储索引组织表的逻辑rowids。每个映射表行会为相应的索引组织表行存储一个逻辑rowid。
数据库使用搜索键来访问位图索引。如果数据库找到了该键,则该位图条目被转换为一个物理rowid。对堆组织表,数据库使用物理rowid来访问基表。对索引组织表,数据库使用物理rowid来访问映射表,这样会生成一个逻辑rowid,以被数据库用来访问索引组织表。图3-4演示了一个通过索引访问departments_iot表的查询。

注意:
索引组织表中的行移动,不会使建立在该索引组织表上的位图索引变得不可用。




