先按照tom的方法先搭建实验环境
1:建索引聚簇
2:再索引聚簇上建立索引
3:在索引聚簇上建立表
4:插入数据
-
SQL> create cluster emp_dept_cluster
-
2 (deptno number(2))
-
3 size 1024
-
4 /
-
-
Cluster created.
-
-
SQL> create index emp_dept_cluster_idx
-
2 on cluster emp_dept_cluster
-
3 /
-
-
Index created.
-
-
SQL> create table dept
-
2 (deptno number(2) primary key,
-
3 dname varchar2(14),
-
4 loc varchar2(13)
-
5 )
-
6 cluster emp_dept_cluster(deptno)
-
7 /
-
-
Table created.
-
-
SQL> create table emp
-
2 (empno number primary key,
-
3 ename varchar2(10),
-
4 job varchar2(9),
-
5 mgr number,
-
6 hiredate date,
-
7 sal number,
-
8 comm number,
-
9 deptno number(2) references dept(deptno)
-
10 )
-
11 cluster emp_dept_cluster(deptno)
-
12 /
-
-
SQL> insert into dept
-
2 select * from scott.dept;
-
-
4 rows created.
-
-
SQL> commit;
-
-
SQL> insert into emp
-
2 select * from scott.emp;
-
-
14 rows created.
-
-
SQL> commit;
现在实验环境已经建成,开始实验
1:查询数据是存放在那个数据块上面
-
SQL> select dbms_rowid.rowid_relative_fno(rowid),dbms_rowid.rowid_block_number(rowid) from dept;
-
-
DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)
-
------------------------------------ ------------------------------------
-
-
6 29484
-
6 29484
-
6 29484
-
6 29484
-
-
-
SQL> select dbms_rowid.rowid_relative_fno(rowid),dbms_rowid.rowid_block_number(rowid) from emp;
-
-
DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)
-
------------------------------------ ------------------------------------
-
-
6 29484
-
6 29484
-
6 29484
-
6 29484
-
6 29484
-
6 29484
-
6 29484
-
6 29484
-
6 29484
-
6 29484
-
6 29484
-
-
DBMS_ROWID.ROWID_RELATIVE_FNO(ROWID) DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)
-
------------------------------------ ------------------------------------
-
-
6 29484
-
6 29484
-
6 29484
-
-
14 rows selected.
从上面可以看到emp 和 dept 表中的都是存放在 file 6 block 29484 这个数据块上面
2:转储该数据块
SQL> alter system dump datafile 6 block 29484;
System altered.
以下是转储的部分信息:
-
data_block_dump,data header at 0xa68664
-
===============
-
tsiz: 0x1f98
-
hsiz: 0x46
-
pbl: 0x00a68664
-
76543210
-
flag=--------
-
ntab=3
-
nrow=22
-
frre=-1
-
fsbo=0x46
-
fseo=0x1cdb
-
avsp=0x1c95
-
tosp=0x1c95
-
0xe:pti[0] nrow=4 offs=0
-
0x12:pti[1] nrow=4 offs=4
-
0x16:pti[2] nrow=14 offs=8
-
0x1a:pri[0] offs=0x1f82
-
0x1c:pri[1] offs=0x1f54
-
0x1e:pri[2] offs=0x1f2a
-
0x20:pri[3] offs=0x1f02
-
0x22:pri[4] offs=0x1f6a
-
0x24:pri[5] offs=0x1f40
-
0x26:pri[6] offs=0x1f18
-
0x28:pri[7] offs=0x1eec
-
0x2a:pri[8] offs=0x1ec9
-
0x2c:pri[9] offs=0x1ea0
-
0x2e:pri[10] offs=0x1e77
-
0x30:pri[11] offs=0x1e51
-
0x32:pri[12] offs=0x1e26
-
0x34:pri[13] offs=0x1e00
-
0x36:pri[14] offs=0x1dda
-
0x38:pri[15] offs=0x1db5
-
0x3a:pri[16] offs=0x1d92
-
0x3c:pri[17] offs=0x1d69
-
0x3e:pri[18] offs=0x1d46
-
0x40:pri[19] offs=0x1d23
-
0x42:pri[20] offs=0x1cff
-
0x44:pri[21] offs=0x1cdb
从上面的信息里可以看到这里又3张表,22条数据,表0有2条数据,表1有4条数据,表2有14条数据
继续观察转储文件
block_row_dump:
tab 0, row 0, @0x1f82
tl: 22 fb: K-H-FL-- lb: 0x0 cc: 1
curc: 4 comc: 4 pk: 0x0180732c.0 nk: 0x0180732c.0
col 0: [ 2] c1 0b
tab 0, row 1, @0x1f54
tl: 22 fb: K-H-FL-- lb: 0x0 cc: 1
curc: 6 comc: 6 pk: 0x0180732c.1 nk: 0x0180732c.1
col 0: [ 2] c1 15
tab 0, row 2, @0x1f2a
tl: 22 fb: K-H-FL-- lb: 0x0 cc: 1
curc: 7 comc: 7 pk: 0x0180732c.2 nk: 0x0180732c.2
col 0: [ 2] c1 1f
tab 0, row 3, @0x1f02
tl: 22 fb: K-H-FL-- lb: 0x0 cc: 1
curc: 1 comc: 1 pk: 0x0180732c.3 nk: 0x0180732c.3
col 0: [ 2] c1 29
这是表0数据,其实表0就是我们最开始建立的索引聚簇(以deptno为聚簇键)
查询dept 表的deptno字段
-
SQL> select deptno from dept;
-
-
DEPTNO
-
----------
-
-
10
-
20
-
30
-
40
把10,20,30,40 都 转换为16进制
-
SQL> select dump(&num,16) from dual;
-
Enter value for num: 10
-
old 1: select dump(&num,16) from dual
-
new 1: select dump(10,16) from dual
-
-
DUMP(10,16)
-
-----------------
-
-
Typ=2 Len=2: c1,b
-
-
SQL> /;
-
Enter value for num: 20
-
old 1: select dump(&num,16) from dual
-
new 1: select dump(20,16) from dual
-
-
DUMP(20,16)
-
------------------
-
-
Typ=2 Len=2: c1,15
-
-
SQL> /;
-
Enter value for num: 30
-
old 1: select dump(&num,16) from dual
-
new 1: select dump(30,16) from dual
-
-
DUMP(30,16)
-
------------------
-
-
Typ=2 Len=2: c1,1f
-
-
SQL> /;
-
Enter value for num: 40
-
old 1: select dump(&num,16) from dual
-
new 1: select dump(40,16) from dual
-
-
DUMP(40,16)
-
------------------
-
-
Typ=2 Len=2: c1,29
和转储文件中表0的字段值都相符合. 那这个索引聚簇中,表和聚簇键是通过什么相关联的呢,在表0中我看到了 pk: 0x0180732c.0 nk: 0x0180732c.0 pk: 0x0180732c.1 nk: 0x0180732c.1 pk: 0x0180732c.2 nk: 0x0180732c.2 pk: 0x0180732c.3 nk: 0x0180732c.3
为了能看的更直观一些我把表0一些重要信息囊括了一下:
Deptno pk nk
10 0x0180732c.0 0x0180732c.0
20 0x0180732c.1 0x0180732c.1
30 0x0180732c.2 0x0180732c.2
40 0x0180732c.3 0x0180732c.3
其实下面的表1和表2就是通过pk中的最后那个值来相关联起来的,以下是表1的转储信息,我做了一些处理,就是还原了原来的信息:
-
tab 1, row 0, @0x1f6a
-
tl: 24 fb: -CH-FL-- lb: 0x0 cc: 2 cki: 0 ----------------cki:0 和 0x0180732c.0 相关联
-
col 0: [10] 41 43 43 4f 55 4e 54 49 4e 47 ---------------- ACCOUNTING
-
col 1: [ 8] 4e 45 57 20 59 4f 52 4b ---------------- NEW YORK
-
tab 1, row 1, @0x1f40
-
tl: 20 fb: -CH-FL-- lb: 0x0 cc: 2 cki: 1 -------------------cki:1 和 0x0180732c.1 相关联
-
col 0: [ 8] 52 45 53 45 41 52 43 48 ------------------ RESEARCH
-
col 1: [ 6] 44 41 4c 4c 41 53 --------------------- DALLAS
-
tab 1, row 2, @0x1f18
-
tl: 18 fb: -CH-FL-- lb: 0x0 cc: 2 cki: 2 -----------------------cki:2 和 0x0180732c.2相关联
-
col 0: [ 5] 53 41 4c 45 53 ------------------- SALES
-
col 1: [ 7] 43 48 49 43 41 47 4f ------------------ CHICAGO
-
tab 1, row 3, @0x1eec
-
tl: 22 fb: -CH-FL-- lb: 0x0 cc: 2 cki: 3 -------------------------- cki:3 和 0x0180732c.3相关联
-
col 0: [10] 4f 50 45 52 41 54 49 4f 4e 53 ------------ OPERATIONS
-
col 1: [ 6] 42 4f 53 54 4f 4e ----
表2其实也是一样的道理,这里就不写了!
还有这里的pk和nk 为什么一样呢,在什么时候会不一样呢
我刚才在创建的索引聚簇的时候 有个size=1024 这个字句,我猜想这个pk,nk 估计就是当 在1024个字节放不下信息的时候,pk,nk起到指向要串连到其他的块的地址!
我们增加dept =10 的记录!
创建一个插入的存储过程
-
create or replace procedure insert_emp
-
as
-
begin
-
for i in 4000 .. 6000
-
loop
-
/*execute immediate '*/
-
insert into superman.emp values ( i,'aaaa','aaaaa',8000,sysdate,800,1000,10);
-
end loop;
-
end;
-
SQL> exec insert_emp;
-
-
PL/SQL procedure successfully completed
-
-
SQL> commit;
-
-
Commit complete
-
-
SQL> alter sytem switch logfile;
-
-
System altered
下面查看块的分布情况
-
SQL> select dbms_rowid.rowid_block_number(rowid) from superman.emp where deptno=10 GROUP BY dbms_rowid.rowid_block_number(rowid);
-
-
DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)
-
------------------------------------
-
-
29516
-
29483
-
29519
-
29484
-
29512
-
29487
-
29513
-
29485
-
29518
-
29517
-
29486
-
-
DBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)
-
------------------------------------
-
-
29514
-
-
12 rows selected.
现在我们再次转储29484这个块
-
SQL> alter system dump datafile 6 block &blockid;
-
Enter value for blockid: 29484
-
old 1: alter system dump datafile 6 block &blockid
-
new 1: alter system dump datafile 6 block 29484
-
-
System altered.
block_row_dump:
tab 0, row 0, @0x1f82
tl: 22 fb: K-H-FL-- lb: 0x1 cc: 1
curc: 165 comc: 165 pk: 0x0180734d.0 nk: 0x01807349.0
col 0: [ 2] c1 0b
0x0180734d 为 file 6 block 29517
0x01807349 为 file 6 block 29513
这里我们可以得出 pk是指向它的上一块地址,nk是指向他的下一块地址!