Oracle数据块概念及与行之间的关系测试

    数据块(Oracle Data Blocks),是Oracle最小的存储单位,Oracle数据存放在“块”中,一个块占用一定的磁盘空间。这里的“块”是Oracle的“数据块”,不是操作系统的“块”,操作系统的块通常为512k。

    Oracle每次请求数据的时候,都是以块为单位,也就是说,Oracle每次请求的数据是块的整数倍。如果Oracle请求的数据量不到一块,Oracle也会读取整个块,所以说,“块”是Oracle读写数据的最小单位或者最基本的单位。

    块的标准大小由初始化参数DB_BLOCK_SIZE指定。具有标准大小的块称为标准块(Standard Block)。块的大小和标准块的大小不同的块叫非标准块(Nonstandard Block)。同一数据库中,Oracle9i及以上版本支持同一数据库中同时使用标准块和非标准块,Oracle允许指定5种非标准块(Nonstandard Block)。操作系统每次执行I/O的时候,是以操作系统的块为单位;Oracle每次执行I/O的时候,都是以Oracle的块为单位,而Oracle数据块大小一般是操作系统块的整数倍。


数据块的格式(Data Block Format)

    块中存放表的数据和索引的数据,无论存放哪种类型的数据,块的格式都是相同的,块由数据块头(header/Common and Variable),表目录区(Table Directory),行目录区(Row Directory),可用空间区(Free Space)和行数据(Row Data)五部分组成,如下图所示:



图中两个箭头表示一个数据块中的可用空间区的容量是可变的。


数据块头(包括标准内容和可变内容)


数据块头(header)中包含了此数据块的概要信息,例如块地址(block address)及此数据块所属的段(segment)的类型(例如,表或索引)。


表目录区


如果一个数据表在此数据块中储存了数据行,那么数据表的信息将被记录在数据块的表目录区(table directory)中。


行目录区


此区域包含数据块中存储的数据行的信息(每个数据行片断(row piece) 在行数据区(row data area)中的地址)。[一个数据块中可能保存一个完整的

数据行,也可能只保存数据行的一部分 。]

当一个数据块(data block)的行目录区(row directory)空间被使用后,即使数据行被删除(delete),行目录区空间也不会被回收。

举例来说,当一个曾经包含50条记录的数据块被清空后,其块头(header)的行目录区仍然占用100字节(byte)的空间


管理开销


数据块头(data block header),表目录区(table directory),行目录区(rowdirectory)被统称为管理开销(overhead)。其中 有些开销的容量是固定的;

而有些开销的总容量是可变的。数据块中固定及可变管理开销的容量平均在84到107字节(byte)之间。


行数据


数据块(data block)中行数据区(row data)包含了表或索引的实际数据。一个数据行可以跨多个数据块。


可用空间区


在插入新数据行,或在更新数据行需要更多空间时(例如,原来某行最后一个字段为空(trailing null),现在要更新为非空值),将 使用可用空间区(free space)中的空间。如果一个数据块(data block)属于表或簇表的数据段(data segment),或属于索引的索引段(index segment),那么在其可用空间区中还可能会存储事务条目(transaction entry)。如果一个数据块中的数据行(row)正在由INSERT,UPDATE,DELETE,及 SELECT...FOR UPDATE 语句访问,此数据块中就需要保存事务条目。事务条目所需的存储空间依据操作系统而定。在常见的操作系统中事务条目大约需要占用23字节(byte)。


一个标准Oracle数据块大小是8k,即8192个字节,那么一个数据块能插入多少行呢?
如果按照每行1个字节的方式来插入数据块,是否可以插入8000行呢?下面来测试一下:


[oracle@ora10g ~]$ sqlplus /  as sysdba


SQL*Plus: Release 10.2.0.1.0 - Production on 星期二 9月 22 15:02:10 2015


Copyright (c) 1982, 2005, Oracle.  All rights reserved.


Connected to an idle instance.


SYS@ora10g> startup
ORACLE instance started.


Total System Global Area  524288000 bytes
Fixed Size    1220384 bytes
Variable Size  339738848 bytes
Database Buffers  180355072 bytes
Redo Buffers    2973696 bytes
Database mounted.
Database opened.
SYS@ora10g> conn zlm/zlm
Connected.
ZLM@ora10g> drop table t1 purge;


drop table t1 purge
           *
ERROR at line 1:
ORA-00942: table or view does not exist


ZLM@ora10g> create table t1 (id varchar2(1));


Table created.


ZLM@ora10g> begin
 for i  in 1..8000 loop
  insert into t1 values('a');
 end loop;
 commit;
 end;
 /


PL/SQL procedure successfully completed.


ZLM@ora10g> select f, b, count(*)
  from (select dbms_rowid.rowid_relative_fno(rowid) file,
               dbms_rowid.rowid_block_number(rowid) block
       from t1)
 group by file, block;


   FILE  BLOCK  COUNT(*)
---------- ---------- ----------
6   12    660
6   13    660
6   22    660
6   19    660
6   21    660
6   24    660
6   20    660
6   17    660
6   23    660
6   16    660
6   14    660
6   15    660
6   18     80


13 rows selected.


ZLM@ora10g> 



可以看到,即使每行只有1个字节,当插入一个字符a作为一行数据的时候,每个块可以存放660行数据(记录)


其实,每行的其他开销导致最小长度约占11个字节左右,所以一个8K的块的行理论上最多可用存储8096/11=736行,但这只是理论值,我测试出来的实际值为660行.



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值