oracle的逻辑结构
oracle的逻辑结构是一种层次结构。主要由:表空间、段、区和数据块等概念组成。逻辑结构是面向用户的,用户使用oracle开发应用程序使用的就是逻辑结构。数据库存储层次结构及其构成关系,结构对象也从数据块到表空间形成了不同层次的粒度关系。
1.数据块(data blocks)
数据块是oracle{banned}{banned}最佳佳小的存储单位,oracle数据存放在“块”中。一个块占用一定的磁盘空间。特别注意的是,这里的“块”是oracle的“数据块”,不是操作系统的“块”。
oracle每次请求数据的时候,都是以块为单位。也就是说,oracle每次请求的数据是块的整数倍。如果oracle请求的数据量不到一块,oracle也会读取整个块。所以说,“块”是oracle读写数据的{banned}{banned}最佳佳小单位或者{banned}{banned}最佳佳基本的单位。
块的标准大小由初始化参数db_block_size指定。具有标准大小的块称为标准块(standard block)。块的大小和标准块的大小不同的块叫非标准块(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/common and variable):存放块的基本信息,如:块的物理地址,块所属的段的类型(是数据段还是索引段)。
表目录(table directory):存放表的信息,即:如果一些表的数据被存放在这个块中,那么,这些表的相关信息将被存放在“表目录”中。
行目录(row directory):如果块中有行数据存在,则,这些行的信息将被记录在行目录中。这些信息包括行的地址等。
行数据(row data):是真正存放表数据和索引数据的地方。这部分空间是已被数据行占用的空间。
空余空间(free space):空余空间是一个块中未使用的区域,这片区域用于新行的插入和已经存在的行的更新。
头部信息区(overhead):我们把块头(header/common and variable),表目录(table directory),行目录(row directory)这三部分合称为头部信息区(overhead)。头部信息区不存放数据,它存放的整个块的信息。头部信息区的大小是可变的。一般来说,头部信息区的大小介于84字节(bytes)到107字节(bytes)之间。
数据块中自由空间的使用
当往数据库中插入(insert)数据的时候,块中的自由空间会减少;当对块中已经存在的行进行修改(update)的时候(使记录长度增加),块中的自由空间也会减少。
delete语句和update语句会使块中的自由空间增加。当使用delete语句删除块中的记录或者使用update语句把列的值更改成一个更小值的时候,oracle会释放出一部分自由空间。释放出的自由空间并不一定是连续的。通常情况下,oracle不会对块中不连续的自由空间进行合并。因为合并数据块中不连续的自由空间会影响数据库的性能。只有当用户进行数据插入(insert)或者更新(update)操作,却找不到连续的自由空间的时候,oracle才会合并数据块中不连续的自由空间。
对于块中的自由空间,oracle提供两种管理方式:自动管理,手动管理
行链接和行迁移(row chaining and migrating)
行链接(row chaining):如果我们往数据库中插入(insert)一行数据,这行数据很大,以至于一个数据块存不下一整行,oracle就会把一行数据分作几段存在几个数据块中,这个过程叫行链接(row chaining)。如下图所示:
如果一行数据是普通行,这行数据能够存放在一个数据块中;如果一行数据是链接行,这行数据存放在多个数据块中。
行迁移(row migrating):数据块中存在一条记录,用户执行update更新这条记录,这个update操作使这条记录变长,这时候,oracle在这个数据块中进行查找,但是找不到能够容纳下这条记录的空间,无奈之下,oracle只能把整行数据移到一个新的数据块。原来的数据块中保留一个“指针”,这个“指针”指向新的数据块。被移动的这条记录的rowid保持不变。行迁移的原理如下图所示:
无论是行链接还是行迁移,都会影响数据库的性能。oracle在读取这样的记录的时候,oracle会扫描多个数据块,执行更多的i/o。
块中自由空间的自动管理
oracle使用位图(bitmap)来管理和跟踪数据块,这种块的空间管理方式叫“自动管理”。自动管理有下面的好处:
◆易于使用
◆更好地利用空间
◆可以对空间进行实时调整
块中自由空间的手动管理
用户可以通过pctfree, pctused来调整块中空间的使用,这种管理方式叫手动管理。相对于自动管理,手动管理方式比较麻烦,不容易掌握,容易造成块中空间的浪费。
pctused也是用于设置一个百分比,当块中已使用的空间的比例小于这个百分比的时候,这个块才被标识为有效状态。只有有效的块才被允许插入数据。
pctfree参数用于指定块中必须保留的{banned}{banned}最佳佳小空闲空间百分例,默认值为10。之所以要预留这样的空间,是因为update时,需要这些空间。如果update时,没有空余空间,oracle就会分配一个新的块,这会产生行迁移(row migrating)。
例如,假定在create table语句中指定了pctfree为20,则说明在该表的数据段内每个数据块的20%被作为可利用的空闲空间,用于更新已在数据块内存在的数据行其余80%是用于插入新的数据行,直到达到80%为止。显然,pctfree值越小,则为现存行更新所预留的空间越少。因此,如果pctfree设置得太高,则在全表扫描期间增加i/o,浪费磁盘空间;如果pctfree设置得太低,则会导致行迁移。
pctused参数设置了数据块是否是空闲的界限。当数据块的使用空间低于pctused的值时,此数据块标志为空闲,该空闲空间仅用于插入新的行。如果数据块已经达到了由pctfree所确定的上边界时,oracle就认为此数据块已经无法再插入新的行。例如,假定在create table语句中指定pctused为40,则当小于或等于39时,该数据块才是可用的。所以,可将数据块填得更满,这样可节省空间,但却增加了处理开销,因为数据块的空闲空间总是要被更新的行占据,所以对数据块需要频繁地进行重新组织。比较低的pctused增加了数据库的空闲空间,但减少了更新操作的处理开销。所以,如果pctused设置过高,则会降低磁盘的利用率导致行迁移;若pctused设置过低,则浪费磁盘空间,增加全表扫描时的i/o输出。pctused是与pctfree相对的参数。
那么,如何选择pctfree和pctused的值呢?有个公式可供参考。显然,pctfree和pctused的之和不能超过100。若两者之和低于100,则空间的利用与系统的i/o之间的{banned}{banned}最佳佳佳平衡点是:pctfree与pctused之和等于100%减去一行的大小占块空间大小的百分比。例如,如果块大小为2048字节,则它需要100个字节的开销,而行大小是390字节(为可用块的20%)。为了充分利用空间,pctfree与pctused之和{banned}{banned}最佳佳好为80%。
那么,怎样确定数据块大小呢?有两个因素需要考虑:
一是数据库环境类型。例如,是dss环境还是oltp环境?在数据仓库环境(olap或dss)下,用户需要进行许多运行时间很长的查询,所以应当使用大的数据块。在oltp系统中,用户处理大量的小型事务,采用较小数据块能够获得更好的效果。
二是sga的大小。数据库缓冲区的大小由数据块大小和初始化文件的db_block_buffers参数决定。{banned}{banned}最佳佳好设为操作系统i/o的整数倍。
2.数据区(extent)
是一组连续的数据块。当一个表、回滚段或临时段创建或需要附加空间时,系统总是为之分配一个新的数据区。一个数据区不能跨越多个文件,因为它包含连续的数据块。使用区的目的是用来保存特定数据类型的数据,也是表中数据增长的基本单位。在oracle数据库中,分配空间就是以数据区为单位的。一个oracle对象包含至少一个数据区。设置一个表或索引的存储参数包含设置它的数据区大小。
3.段(segment)
是由多个数据区构成的,它是为特定的数据库对象(如表段、索引段、回滚段、临时段)分配的一系列数据区。段内包含的数据区可以不连续,并且可以跨越多个文件。使用段的目的是用来保存特定对象。
一个oracle数据库有4种类型的段:
数据段:数据段也称为表段,它包含数据并且与表和簇相关。当创建一个表时,系统自动创建一个以该表的名字命名的数据段。
索引段:包含了用于提高系统性能的索引。一旦建立索引,系统自动创建一个以该索引的名字命名的索引段。
回滚段:包含了回滚信息,并在数据库恢复期间使用,以便为数据库提供读入一致性和回滚未提交的事务,即用来回滚事务的数据空间。当一个事务开始处理时,系统为之分配回滚段,回滚段可以动态创建和撤销。系统有个默认的回滚段,其管理方式既可以是自动的,也可以是手工的。
临时段:它是oracle在运行过程中自行创建的段。当一个sql语句需要临时工作区时,由oracle建立临时段。一旦语句执行完毕,临时段的区间便退回给系统。
4.表空间(tablespace)
是数据库的逻辑划分。任何数据库对象在存储时都必须存储在某个表空间中。表空间对应于若干个磁盘文件,即表空间是由一个或多个磁盘文件构成的。表空间相当于操作系统中的文件夹,也是数据库逻辑结构与物理文件之间的一个映射。每个数据库至少有一个表空间(system tablespace),表空间的大小等于所有从属于它的数据文件大小的总和。
(1)系统表空间(system tablespace)
是每个oracle数据库都必须具备的。其功能是在系统表空间中存放诸如表空间名称、表空间所含数据文件等数据库管理所需的信息。系统表空间的名称是不可更改的。系统表空间必须在任何时候都可以用,也是数据库运行的必要条件。因此,系统表空间是不能脱机的。
系统表空间包括数据字典、存储过程、触发器和系统回滚段。为避免系统表空间产生存储碎片以及争用系统资源的问题,应创建一个独立的表空间用来单独存储用户数据。
(2)sysaux表空间
是随着数据库的创建而创建的,它充当system的辅助表空间,主要存储除数据字典以外的其他对象。sysaux也是许多oracle 数据库的默认表空间,它减少了由数据库和dba管理的表空间数量,降低了system表空间的负荷。
(3)临时表空间
相对于其他表空间而言,临时表空间(temp tablespace)主要用于存储oracle数据库运行期间所产生的临时数据。数据库可以建立多个临时表空间。当数据库关闭后,临时表空间中所有数据将全部被清除。除临时表空间外,其他表空间都属于永久性表空间。
(4)撤销表空间
用于保存oracle数据库撤销信息,即保存用户回滚段的表空间称之为回滚表空间(或简称为rbs撤销表空间(undo tablespace))。在oracle8i中是rollback tablespace,从oracle9i开始改为undo tablespace。在oracle 10g中初始创建的只有6个表空间sysaux、system、temp、undotbs1、example和users。其中temp是临时表空间,undotbs1是undo撤销表空间。
(5)users表空间
用户表空间,用于存放永久性用户对象的数据和私有信息。每个数据块都应该有一个用户表空间,以便在创建用户是将其分配给用户。