-----2010-03-19
昨天的实验。证明了cluster中的表都是在同一个段上的,但是从实验中也看到了数据不在同一个块上的情况。虽然得出了这个结论,但是昨天回家看书了之后,发现原来我的实验没有真正按照聚簇表的聚集方式去存放数据。按照如下方法:
begin
for i in (select rownum rn, dbms_random.string('X', 10) a, mod(dbms_random.value(1,10),2) b, '' d
from dual connect by rownum <= 10) loop
insert into student values(i.rn, i.a, i.b, i.d);
insert into stu_grade
select i.rn, dbms_random.string('X', 10), dbms_random.value(1,100), ''
from dual;
end loop;
end;
我们便可以模拟出在同一个块上的情况了:
SQL> select dbms_rowid.rowid_block_number(rowid) blkno,
2 dbms_rowid.rowid_row_number(rowid) rowno,
3 s.*
4 from student s;
BLKNO ROWNO ID NAME
---------- ---------- --------------------------------------- -------------------------------
42020 0 1 X9FCEQT0SX
42024 0 2 1QWUGV92YL
42028 0 3 K60A3B901E
42032 0 4 5SAEMB7IRG
42036 0 5 RQ2TOSCU5S
42040 0 6 XKJONRUF72
42044 0 7 C5J6OE1I2C
42048 0 8 NZO3G6ETBC
42052 0 9 OGY5HRFLIS
42056 0 10 AWQ7QBE79G
10 rows selected
SQL> select dbms_rowid.rowid_block_number(rowid) blkno,
2 dbms_rowid.rowid_row_number(rowid) rowno,
3 g.*
4 from stu_grade g;
BLKNO ROWNO STU_ID STU_NAME
---------- ---------- --------------------------------------- -------------------------------
42020 0 1 MNZU2K6R7R
42024 0 2 AB1X3ZJBBN
42028 0 3 E6FEVDN9JY
42032 0 4 OA0QNIMDO3
42036 0 5 BUU69NPUAU
42040 0 6 11U7QUPPTF
42044 0 7 A1PGQC7EVY
42048 0 8 8DO1K7X3ZZ
42052 0 9 IIQKD8GT5D
42056 0 10 1BKJH1LT53
10 rows selected
从以上的结果中,很清楚的能够看到两个表的数据所存放的都对应的在同一个块上。因此昨天的实验前面的结论是不全面的,只要能够按照聚簇表要求的存放方式存放,便能够将数据放到一个块上。
另:以上实验修改了昨天的聚簇表字段,昨天是id和name,今天为了实验方便,改成了id字段。
--###########################################
聚簇表可以将多个表捆绑在一起,它是一种数据结构,在这个结构中,
聚簇将一个或多表都放到同一个块或段中。
使得聚簇中的表在通过聚簇剑关联查询时能够减少对块的频繁获取。
下面是实验:
--首先创建聚簇
create cluster my_cluster(
id int, name varchar2(100)
);
--创建聚簇表
create table student(
id int,
name varchar2(100),
sex int,
addr varchar2(100)
)cluster my_cluster(id, name);
create table stu_grade(
stu_id int,
stu_name varchar2(100),
grade varchar2(100),
class_name varchar2(100)
)cluster my_cluster(stu_id, stu_name);
--创建聚簇索引
create index my_clu_idx on cluster my_cluster tablespace fund_index nologging;
这里需要提到的是,创建聚簇表后如果没有创建该聚簇索引,则无法插入数据,执行时会报如下错误:
ORA-02032: 聚簇表无法在簇索引建立之前使用
创建该索引后,该问题解决。
insert into student
select rownum, dbms_random.string('X', 10), mod(dbms_random.value(1,10),2), ''
from dual connect by rownum <= 10;
insert into stu_grade
select trunc(dbms_random.value(1,10)), dbms_random.string('X', 10), dbms_random.value(1,100), ''
from dual connect by rownum <= 10;
虽然说聚簇表的数据是放在同一个块或段上的,但是我查看了下两个表的所有行所在的块,没有发现有聚合的块:
select dbms_rowid.rowid_block_number(rowid) blkno, s.*
from student s;
select dbms_rowid.rowid_block_number(rowid) blkno, g.*
from stu_grade g;
但是在进行段查询的时候,发现单独查看两个表的段信息是查不到的:
select * from dba_segments s
where s.segment_name in('STU_GRADE', 'STUDENT');
可以证明他们的数据是放在同一个段上的,即my_cluster上。
查看段的信息,观察段所包含的区和块的范围:
SQL> select dbms_rowid.rowid_block_number(rowid) blkno
2 from student s;
BLKNO
----------
161
165
169
173
177
181
185
189
193
197
10 rows selected
SQL> select dbms_rowid.rowid_block_number(rowid) blkno
2 from stu_grade g;
BLKNO
----------
142
146
150
154
158
162
166
170
174
178
10 rows selected
SQL>
SQL> select d.BLOCK_ID, d.BLOCK_ID + d.BLOCKS end_block
2 from dba_extents d where d.segment_name = 'MY_CLUSTER'
SQL> /
BLOCK_ID END_BLOCK
---------- ----------
137 265
可发现,聚簇中的两个成员表所有的block均落在这个范围中。
--删除聚簇表及级联的表和约束
drop cluster my_cluster including tables cascade constraints ;