在英文的P469页,有一段描述:
如下:
There really is no such thing as a nonunique entry in a B*Tree index. In a nonunique index, Oracle simply stores the rowid by appending it to the key as an extra column with a length byte to make the key unique. For example, an index such as CREATE INDEX I ON T(X,Y)
is conceptually CREATE UNIQUE INDEX I ON T(X,Y,ROWID). In a unique index, as defined by you, Oracle does not add the rowid to the index key. In a nonunique index, you will find that the data is sorted first by index key values (in the order of the index key) and then by rowid
ascending. In a unique index, the data is sorted only by the index key values.
感谢NinGoo写的例子,记录如下:
/>/>
http://www.itpub.net/showthread.php?s=&threadid=718966&perpage=10&pagenumber=1
create table tt(id int, name varchar2(20));
create unique index ix_t on tt(id);
insert into tt values(1,'a');
insert into tt values(2,'a');
select file_id,block_id from dba_extents where segment_name='IX_T' and owner=USER;
FILE_ID BLOCK_ID
---------- ----------
32 240905
alter system dump datafile 32 block 240905;
检查发现索引数据应该在240905+4
0:Metadata 1:Metadata 2:Metadata 3:Metadata
4:25-50% free 5:unformatted 6:unformatted 7:unformatted
alter system dump datafile 32 block 240909;
检查trace文件
唯一索引:
row#0[8021] flag: ------, lock: 2, len=11, data:(6): 08 03 ac e5 00 00
col 0; len 2; (2): c1 02
row#1[8010] flag: ------, lock: 2, len=11, data:(6): 08 03 ac a9 00 00
col 0; len 2; (2): c1 03
----- end of leaf block dump -----
End dump data blocks tsn: 32 file#: 32 minblk 240909 maxblk 240909
删除索引,在建议非唯一索引,重复以上步骤:
非唯一索引:
row#0[8020] flag: ------, lock: 0, len=12
col 0; len 2; (2): c1 02
col 1; len 6; (6): 08 03 ac e5 00 00
row#1[8008] flag: ------, lock: 0, len=12
col 0; len 2; (2): c1 03
col 1; len 6; (6): 08 03 ac a9 00 00
----- end of leaf block dump -----
End dump data blocks tsn: 32 file#: 32 minblk 240909 maxblk 240909
select dump(rowid,16) from tt ;
DUMP(ROWID,16)
-----------------------------------------------------------
Typ=69 Len=10: 0,1,2a,34,8,3,ac,a9,0,0
Typ=69 Len=10: 0,1,2a,34,8,3,ac,e5,0,0
select * from tt ;
ID NAME
---- ---------
2 a
1 a
可以发现唯一索引中rowid在行头,非唯一索引rowid保存在最后一列中。而且可以发现非唯一索引的长度要大于唯一索引。