Oracle数据库管理:从入门到精通——第7章 存储结构和它们之间的关系
第7章 存储结构和它们之间的关系
7.1 各种类型的段
段是在数据库中占有磁盘空间的对象。这些段使用数据库的数据文件中的磁盘空间。
- 表(table)
表是oracle数据库中最重要的段,在备份和恢复策略中所要考虑的也主要是表,因为数据主要存在表中。表是数据库中最常用的存储数据的机制,在表段中所存储的数据是无序的,数据库管理员几乎无法控制某一行数据所存放在一个表中的具体位置。oracle规定一个表中所有数据必须存放在一个表空间中。 - 分区表(table partition)
当一个表的规模很大或并行操作非常频繁时,可以把这个表划分为若干个分区(partition)。此时表已经称为了逻辑的概念,而每一个分区为一个存储数据的段,每个分区的存储参数都可以单独定义。分区表的优点是一个分区损毁了不影响其他分区的操作,另外可以通过把每个分区放在不同的磁盘上以提高并行操作的能力,从而提高改进系统效率的目的。 - 索引(index)
引入索引段的目的是加快基于某一特殊键(索引关键字)的查询速度,这样的查询可以很快地查找到在某一个表中所需数据行的准确位置。如果一个表有5个索引,那么就会有5个相应的索引段。基于某一特定的索引的所有索引记录都存储在一个索引段中。 - 簇(cluster)
在一些商业系统中,注入订单系统或发票系统,在设计这样的系统时为了减少数据的冗余,在规范化过程中把本来属于一张订单或一张发票的数据存放在了不同的表中。但是用户,如经理还是习惯于使用传统的订单或发票,因此为了把这些相关的表组合成传统的订单或发票就要进行多表的连接。如果这些表很大而且连接又是经常的操作,就可能严重的影响数据库系统的效率,于是oracle系统引入一种称为簇(cluster)的段。可以将订单或发票定义成簇,并定义订单号或发票号为簇号。oracle会将相同簇号(cluster number)的数据行(即使属于不同的表)也存放在同一个数据块中(也可能是相邻的数据块中)。这样在进行这些表的连接操作时,oracle就可以很快就把相同簇号的数据行连接在一起。
簇已经不再是传统意义上的关系表了,但是簇能不用就不用,因为这样可以减少管理和维护的复旦,也可以使跨IT平台的移植变得更加容易。
-
索引分区(index partition)
当在一个大型或超大型表上创建索引时,这个索引可能很大,所以也可以像分区表那样,将改索引划分为若干个分区,每个索引分区为一单独的段。这样一个索引可以分布在不同的表空间上。但是每个索引分区(段)只能存放在一个表空间中。引入索引分区的主要目的也是减少输入或输出竞争。 -
索引表(index-organized table)
如果用户的查询主要基于索引关键字,那么在索引树的叶子结点中的数据行的地址部分可以存放真正的数据,这种存储结构就称为索引表。索引表可以大大地加快基于索引关键字的查询,但是这种存储结构不适合DML操作非常频繁的表。 -
临时段(temporary segment)
当SQL语句中使用了诸如ORDER BY、GROUP BY或DISTINCT等子句时,oracle服务器就要试着在内存中进行排序。如果内存中排不下就要把中间的结果写道磁盘上,该磁盘区就是临时段。 -
还原段(undo segment)
还原段也称为回滚段(rllback segment),用来存放事务(transaction)对数据库所作的改变,在对任何数据块或索引块改变之前,所有的原始值都将存放到还原段中。这样做不但运行用户可以还原所做的变化,而且还可以在一个进程中对某一行数据进行DML操作的同时,允许其他进程对该行数据进行读操作(读的是存放到还原段的原来的数据)。 -
大对象段(LOB segment)
大对象(LOB)数据类型是用来存储例如大的正文文档、图像或音像信息的。在一个表中可以有一列或多列LOB数据类型。如果LOB类型的列很大,oracle服务器就会将该列的值单独存放在另一个段中,该段就称为大对象段,在表中只包含了一个指向相应大对象(LOB)数据的指针(地址)。 -
嵌套表(nested table)
嵌套表是一种特殊表,该表中的某一列又是由一个用户定义的表组成,即表中嵌套表。被称为嵌套表的内表将被存放在另外一个段中。嵌套表也不是传统意义上的关系表,建议能不用就不用,可以减少管理和维护的负担。 -
自举段(bootstrap segemnt)
自举段是在数据库被创建时由sql.bsq脚本建立的,也被称为高速缓存段。该段在实例打开数据库时帮助初始化数据字典高速缓存区,不能对自举段进行任何的查询或修改,数据库管理员也无须对该段进行任何维护。
7.2 存储子句的优先级
存储子句可以在段一级说明以控制区段(extent)在段中是如何分配的。其分配原则如下:
任何在段一级说明的存储参数将覆盖在表空间一级所对应的选项设置,但是表空间一级的参数MINNUM EXTENT或UNIFORM SIZE除外
当存储参数在段一级没有显式定义时,它们默认为表空间一级所定义的参数值
当存储参数在表空间一级没有显示定义时,oracle数据库系统的默认参数值将被使用
如果在表空间一级已经定义MININUM EXTENT的大小,将应用于该表空间中将来所有段的区段(extent)的分配
某些存储参数不能在表空间一级定义,这些存储参数只能在段一级说明
如果对存储参数进行了修改,新的存储参数只适用于还没有分配的区段(extent)

7.3 区段
区段(extent)是在表空间中某个段所使用的一块(磁盘)空间,是一组连续的oracle数据块,从理论上来说oracle根本没有必要引入区段,因为直接使用oracle数据块来进行磁盘空间的分配完全行得通。oracle引入区段的目的是为了提高系统的效率,因为利用区段来进行磁盘空间的分配可以大大地减少磁盘分配的次数,另外一个重要的原因是,oracle的磁盘分配算法是一个递归算法,而递归算法效率本身都比较低,减少磁盘分配的次数也就等于减少了该递归算法使用的次数。
oracle分配区段的场景:当一个段被创建时(created);当一个段被扩展(extented)时;当一个段被改变(altered)时。
oracle回收区段的场景:当一个段被删除(dropped)时,当一个段被改变时,当一个段被截断(truncated)时
当一个表空间被创建时,在该表空间的数据文件就包含了一个表头,这个头就是该数据文件的第一个或前几个数据块。随着段的创建,oracle使用表空间中的空闲区段(free extent)为这些段分配磁盘空间。由某个段所使用的连续磁盘空间被称作使用区段(used extent)。当一些段释放了磁盘空间时,这些释放的区段就被添加到所在表空间中可以使用的空闲区段池中。

7.4 数据库块
oracle的最小的存储单元——数据库块(database block),也称为oracle数据块。oracle数据块是由oracle数据库系统输入或输出的最小单位,它是由一个或多个操作系统块组成。其大小在表空间创建时设置,而DB_BLOCK_SIZE为默认oracle数据块的大小。现在应该数据块可使用应该标准的块(尺寸)来创建,同时可以使用最多4种不同的非标准块(尺寸),非标准数据块的大小为2的次方,其值在2~32KB之间。支持多种数据块尺寸的功能可以通过将需要进行操作的对象存放在数据块大小适当的表空间中以最大限度低改进输入或输出效率。
7.5 数据块的大小
标准数据块的大小被用户系统(system)和临时(temporary)表空间,除非有特别的说明,标准数据块的大小也被用作一个表空间的数据块的默认值。数据库中标准数据块的大小是在数据库创建时使用DB_BLOCK_SIZE初始化参数设置的。若要改变这一设置就要重建数据库。DB_BLOCK_SIZE说明了高速默认缓存的大小,该高速缓存的数据块的大小为标准数据块的大小,有DB_BLOCK_SIZE所定义。
使用高速缓存初始化参数来定义系统全局区(SGA)中高速缓存的大小。如果要在一个数据库中使用多个数据块,就必须定义DB_CACHE_SIZE和至少应该DB_nK_CACHE_SIZE参数。可以使用动态参数配置额外的非标准块的高速缓存。
如:DB_2K_CACHE_SIZE用于2KB数据块。该参数定义了所对应数据块的高速缓存的大小。DB_nK_CACHE_SIZE的默认值为0。如果在数据库中有任何数据块大小为nKB的联机表空间存在,就不可以将DB_nK_CACHE_SIZE置为0.如果nK是标准块的大小,则DB_nK_CACHE_SIZE被禁止。每个高速缓存的的最小尺寸为应该granule。
如果没有必要不用创建非标准数据块尺寸的表空间,因为使用非标准数据块尺寸的表空间会增大内存的开销,同时管理运维也会更加复杂。
7.6 数据块的内容和参数
数据块由3部分组成,分别是块头部分、数据区和空闲区。其中上面是数据块的头部分,下面是数据部分,而中间为空闲区。头部从上往下增长,而数据部分则从下往上增长,当两部分接触时数据块就满了。

数据区:装的是数据行,位于数据块的底部,当插入数据行时该部分从下往上增长。
数据块头:存有段类型(如表或索引)、数据块的地址、表目录、行目录和事物槽(transactionslot),事务槽是在事务修改数据块中的数据行时使用的,每个事务槽大约2个字节。头部从上往下增长。
空闲区:位于数据块的中部。数据块中的空闲区最初时是连续的,但是删除和修改操作可能使数据块中的空闲区碎片化,在需要时oracle服务器会进行合并空闲区的操作。
为了更有效的管理和控制数据块的各个部分,引入下图4个参数,这4个数据块空间控制参数既可以用来控制数据段中的空间使用,也可以控制索引段中的空间使用。它们被分为控制并行操作的参数和控制数据空间使用的参数两大类。

数据并行操作的参数:这类参数包括INITRANS和MAXTRANS。数据行和块头结构如下图,在数据块中每一数据行的头部有一个锁位,该锁位只记录了该行在事务中所使用的事务槽号,而事务槽就是在数据块头中,有关事务的控制信息都放在事务槽中。在下图中3、8数据行的有关事务的信息分别放在了块头的第1和第2号事务槽中。服务器是通过每一行的锁位中的事务槽号在数据块头中找到所对应的事务槽,并利用该槽中的信息来完成该数据行的事务控制。
事务槽是用来存储与当前改变数据块的事务有关的信息。每个事务只使用一个事务槽,即使这个事务正在修改多行数据或多行索引记录。
INITRANS:定义了创建数据块或索引块时事务槽的初始值。它被用来保证最低水平的并行操作。对于数据段,它的默认值为1,而对于索引段,它的默认值为2.如果该参数被设为8,那么服务器就能在任何时候都保证在一个数据块中可以有最多8个并行的事务。
MAXTRANS:定义了创建数据块或索引块时事务槽的最大值。如果并行的事务很多,所需的事务槽的个数可能超过INITRANS所设定的初始值。服务器会在块头中分配更多的事务槽,其数量的上限就是MAXTRANS所定的值。MAXTRANS默认值为255.
控制数据空间使用的参数:这类参数包括PCTFREE和PCTUSED两个参数。
oracle一共提供了2种管理数据块的方法,分别是手动管理和自动的段空间管理。


并行操作与数据块的空间利用率是相互矛盾的。如果将INITRANS和MAXTRANS设置得过大,这样不仅并行操作改进了,而且系统的效率也有所提高,但是由于数据块头的加大而使在数据块所存储的数据减少。
7.7 手工数据块的管理
手工数据块的管理是唯一的数据块管理方法。oracle允许使用PCTFREE、PCTUSED和FREELISTS。参数来手工配置数据块以便更有效地管理和控制数据块中磁盘空间的使用(这里的数据块既包括数据段中的块,也包括索引段中的块)。引入这些参数的目的是为了最大限度地利用数据块的磁盘空间,最后将数据块装满数据行。这样做虽然提高了磁盘空间的使用率,也引出一个效率问题。假设为了提高磁盘空间的利用率,在一开始就将一数据块装满数据。如果接下来有一个对该数据块中的数据行进行的修改操作,而且将修改操作将加大某一列或某几列的长度,此时数据块已经没有可供扩展的足够空间,数据块将这些数据存放在另一数据块中而在原来所在的数据行上放上一个指针指向真正的数据,也称为数据的迁移。这样本来一行的数据就被放在了两个数据块中,从而增加了查询数据的磁盘I/O量,降低了系统的效率。下图为一个数据迁移之前和迁移之后的示意图。

为了避免数据的迁移,oracle在插入数据时并不将数据块装满,而是为将来可能的修改操作预留一定数量的磁盘空间。这是一个典型的用空间换时间的方法。下图在给出PCTFREE和PCTUSED两个参数的定义前,通过下图例子解释2个参数的具体用法。
图中由于PCTFREE定义为15%,PCTUSED定义为30%,因此oracle的操作如下:
(1)在进行插入操作时,oracle服务器要保留数据块空间的15%空闲空间,用于将来可能的修改操作所造成的扩展。
(2)当空闲空间小于或等于15%时,oracle将该数据块从空闲队列中去掉,即该块不能进行插入操作了。
(3)如果进行了删除操作或修改操作造成了数据行的缩小,即释放了磁盘空间,虽然空闲空间大于15%(所使用的空间小于85%),但所使用的空间大于30%,该块还是不允许进行插入操作。
(4)只有当所使用的空间小于30%(低于PCTUSED)时,该块才能被重新放入空闲队列中,即允许进行插入操作。

PCTFREE:该参数定义在每个数据块中预留空间的百分比。这部分空间只是在数据块中的数据进行修改操作(update)而造成空间的增长时使用的。该参数的默认值是为10%。
FREELISTS:该参数用来在一个段中定义空闲队列(free list)的个数。空闲队列是一个数据块的列表,这些数据块将被用作插入操作的候选数据块。在默认情况下,创建一个段时只有一个空闲队列。根据需要可以通过设置FREELISTS参数在一个段创建多个空闲队列。
PCTUSED:该参数定义每个数据块中已经使用的空间的百分比。只有当一个数据块中所使用的空间低于这一参数所设定的值,oracle服务器才将这一数据块放入空闲队列,该参数的默认值为40%。
7.8 自动的段空间管理
自动的段空间管理是一种在数据库段内部管理空闲空间的方法。该方法使用位图而不是使用空闲队列来追踪段内的空闲和使用空间。特点是
管理上的便利:因为PCTUSED和FREELISTS等参数都是自动管理的
较好的空间利用:在这种方法中,所有的对象,特别是行的尺寸变化很大的对象的空间利用率会更有效
并行插入(insert)操作的性能也有较大的改进
自动段空间管理是使用位图来管理磁盘空间的。在一个自动管理的表空间中所有的位图管理段包含了一个位图,该位图描述了段中每一块与可获得空间相关的状态。这个位图存放在一组单独的数据块中,这组数据块被称作位图块(BMBs)。当插入新的一行时,分为检索位图以找到一个具有足够空间的块。随着一个块可获得空间的变化,新的状态要反映在位图中。

oracle数据块、区段、段(特别是表段)和表空间之间的关系

当使用DDL创建一个表时,oracle系统就创建了一个存储其数据的段。一个表空间一般包含多个相关的段。虽然逻辑上一个表是由包含了多列的数据行所组成的,但是一个数据行最终是以一组row piece的方式存储在数据块中。之所以称为row piece,是因为在某些特定情况下,如数据行很大,一个数据块装不下,或update操作造成了数据迁移,一行数据可能被存放在不止一个数据块中。
浙公网安备 33010602011771号