对象管理_表
本章任务
1.管理普通表
如上图所示,每个数据行都有一个行头部,在这里存放了该行数据所包含的列的数量,以及锁定标记等。
对于每条记录来说都有rowid列,该rowid是一个伪列。也就是说,该列的值并没有实际地保存在数据块里,但是可以查询并显示出来。
rowid格式为:OOOOOOFFFBBBBBRRR.
OOOOOO表示该数据行所在的对象号,FFF表示该数据行所在的相对文件号,BBBBB表示该数据行所在的数据块号,RRR表示该行在数据块中的行号。
rowid采用64进制来表示,也就是使用A-Z、a-z、0-9、/、+
A-Z ->0-25
a-z ->26-51
0-9 ->52-61
/ ->62
+ ->63
测试rowid格式:OOOOOOFFFBBBBBRRR
AAAMfN 0+0+0+12*power(64,2)+31*power(64,1)+13*power(64,0)
AAE 0+0+4*power(64,0)
AAAAAO 0+0+0+0+0+14*power(64,0)
AAA 0+0+0 =0
2.扩展表
有时我们需要主动地扩展一个表所占有的空间,或者需要将一个表分不到多个数据文件上去,从而将表的I/O分散到多个磁盘上去。我们可以执行下面的命令
alter table emp allocate extent (size 1024M datafile 'F:\oracle\product\10.2.0\oradata\orcl\USERS01.DBF');
3.重整表
将一个表从目前所在的表空间转移到另外一个表空间里去
或者需要消除表的数据块级别的碎片。
数据块级别的碎片?
所谓数据块级别的碎片指的是每个数据块里含有的数据行太少了,比如100条数据记录分布在100个数据块里,这时我们称这种表为稀疏表。
稀疏表产生的原因在于 :在该表上存在很多的insert和delete.在表的segment header里记录了一个值,叫高水位标记(High Water Mark,简称HWM).HWM表示当前segment里使用的最后一个数据块的位置。当发生insert时,由于不断扩展数据块,因此会不断增加HWM的值.
使用HWM的好处?
当用户发出select count(*) 这样的查询语句而引起全表扫描时,服务器进程在扫描segment数据块的过程中,只扫描到HWM为止,HWM后面的数据块都是还没有使用过的数据块,因此一定不含有当前segment的数据,所以也就不去扫描了;但是如果发生delete操作,则不会降低HWM的值 (也就是说,即便把表里的数据全部删除,HWM的位置还是不变,也就导致进行全表扫描时,比如select count(*)时,任然要扫描到HWM为止,如下图所示)
从上面的图可以看到,该表的数据块里的数据排列不够紧密。oracle10g以后可以使用shrink对表进行收缩。
4.收缩表
进行收缩操作有两个前提条件:
(一)表所在的表空间必须使用ASSM;
(二)因为收缩表引起了数据行在不同数据块之间的转移,因此在被收缩的表上必须启用row movement选项,发出如下语句:
SQL> alter table EMP enable row movement;
Table altered
下面为shirt过程
SQL> select table_name,blocks,num_rows from user_tables where table_name = 'EMP';
TABLE_NAME BLOCKS NUM_ROWS
------------------------------ ---------- ----------
EMP 48312 7990033
SQL> select max(empno) from emp;
MAX(EMPNO)
----------
8000000
SQL> delete from emp where empno>7000000;
1000000 rows deleted
SQL> commit;
Commit complete
SQL> alter table EMP shrink space compact;
Table altered
SQL> alter table EMP shrink space;
Table altered
SQL> alter table EMP shrink space cascade;
Table altered
SQL> analyze table EMP compute statistics;
Table analyzed
SQL> select blocks, extents from user_segments where segment_name = 'EMP';
BLOCKS EXTENTS
---------- ----------
42528 113
SQL>
5.截断表
如果需要删除表里所有的数据,我们可以使用delete命令.delete是DML事务,需要对表的记录加锁,产生重做记录,并消耗undo表空间。因此,delete命令需要消耗较多的资源,执行较长的时间.对于大表来说尤其如此.如果准备删除表里所有的记录,则Oracle提供了一个更加有效的命令:截断(truncate)
截断命令是一个DDL命令,该命令只更新数据字典,将数据字典里将该表所占用的空间记录全部删除,然后,将表所占用的数据块全部释放;最后将表的HWM下降到最低。不过由于截断是一个DDL命令,因此一旦执行就不能回滚.其命令为:
SQL> create table test(
2 id int primary key,
3 name varchar2(20)
4 );
Table created
SQL> truncate table test;
Table truncated
本章目标
1. 掌握对象管理_表