Oracle逻辑存储结构,主要描述oracle 数据库内部数据的组织和管理方式,即在数据库管理系统的层面中如何组织和管理数据,与操作系统没有关系。逻辑存储结构时候物理存储机构的抽象体现,是不可见的,可以通过查询数据库数据字典了解逻辑结构信息。
Oracle数据库的存储逻辑结构主要由表空间(Tasblespace)、段(Segment)、区(Extent)、数据块(Data Block)4个部分组成。其中块是最基本的存储单元,块组成区、区组成段、段组成表空间,最终由段组成数据库。
Oracle数据库逻辑结构图如下:
1 表空间
一个数据库被分成一个个的逻辑单元,那么这些逻辑单元就叫做"表空间"。表空间有一个或多个数据文件组成,一个数据库从逻辑上又由一个或多个表空间组成,它用于存放数据库对象,如:表、索引等。而表空间的大小则等于组成这个表空间的所有数据文件大小之和。
每个数据库都对应的默认表空间,包括一个系统表空间(SYSTEM)、辅助表空间(SYSAUX)、一个用户表空间(USERS)以及用于应用程序、索引和另外的数据结构的其他空间组成。
SYSTEM Tablespace:用于存储Oracle内部数据字典
SYSAUX Tablespace:用于存储辅助内部对象
USERS Tablespace:用于存储用户对象
2 段
数据库中的表在表空间中都由一块单独的磁盘空间区域,称之为段。每一段依次在表空间中有一块初始的磁盘空间区域,成为初始盘区。当段使用完对应的空间时,磁盘空间的另一个单独区域——下一盘区将被启用。如果这一块区域也被使用完,那么还有另一盘区被启用。这个过程会跟随每一个表持续执行,直到整个表空间填充满为止。
数据库中的表由一个或多个的段组成,而普通表由一个段组成,分区表则由多个段组成
一个段有一系列的区组成,段是存放数据的逻辑存储单元,段的分类包括:数据段、索引段、临时段和回滚段
#查询Oracle数据库段类型
SQL> select distinct segment_type from dba_segments;
SEGMENT_TYPE
------------------
LOBINDEX
INDEX PARTITION
NESTED TABLE
TABLE PARTITION
ROLLBACK
LOB PARTITION
LOBSEGMENT
TABLE
INDEX
CLUSTER
TYPE2 UNDO
2.1 数据段
Data Segment。 数据段用于存放数据。可以存储普通表、聚簇表、分区表。
- 普通表(Table):这是最常见的段类型,普通表,没有分区,则每个表有一个类型为Table的段;
- 聚簇表(Cluster Table):每个Cluster有一个Cluster段,一个Cluster中可以存储一个或多个表;
- 分区表(Patition Table):分区表中的一个分区
2.2 索引段
Index Segment ,这是除了Table Segment之外最常见的段类型,表的普通索引,没有分区,则每个索引有一个类型为Index的段,用户可以使用Create Index语句为索引或索引的分区创建索引段。
- 非分区索引(nonpartitioned index)使用一个索引段(index segment)来容纳其数据;
- 分区索引(partitioned index),每个分区使用一个索引段来容纳其数据。
2.3 临时段
Temporary Segment,临时段用于存放临时数据。在进行数据查询时会使用到临时段。临时段由Oracle数据库自动创建和维护。例如,Oracle在进行数据排序时就需要使用临时段,当排序操作可以在内存中执行,或Oracle设法利用索引就执行时,就不必创建临时段。如果Oracle使用到数据库临时段时,则表示数据库性能在降低的征兆,数据库管理员则应想法时相关的数据操作尽量在内存中进行。需要使用临时段的操作:
- Create Iindex
- Select ... Order by
- Select Distinct ...
- Select ... group by
- Select . . . union
- Select ... Insersect
- Select ... Minus
2.4 回滚段
RollBack Segment,回滚段用于保存回滚条目,用户可以撤销对数据的修改,ROLLBACK (Oracle 8i及以前的回滚段 )和TYPE2 UNDO(9i及以后的“撤销段”)
3 区
区是数据库的一个逻辑存储单元,它由连续的数据块组成,区是一个连续的存储空间,当段中的空间耗尽时,数据库将分配一个新的区个这个段。块组成区,区组成段。
3.1区的分配
当数据库创建一个表时,Oracle会自动给该表的数据段分配一个初始区,即使该表中没有存储数据,也会分配。随着数据的插入,分配的初始区空间被填满时,Oracle会再分配一个区给这个数据段,后续新分配的区(非初始化区)叫做递增区,若一个递增区用完,Oracle再次进行分配新的。
3.2区的分配机制
Oracle利用表空间级的存储参数来进行空间的分配,关于存储参数的相关概念见下集分解。
3.3区的空间释放
通常,分配给一个段的区所占用的空间不会被释放,除非将这些段相关的的对象给删除。也可以通过以下方式回收分配的区空间
- Truncate Drop Storage:该命令会回收分配给一个段的区
- Alter Table ..... Deallocate UnUsed :该命令会回收已分配给一个段,但还未使用的区
3.4区的管理方式:
- 字典管理:Dictionary Managed Tablespace ,通过数据字典管理区
- 本地管理:Locally Managed Tablespace ,通过位图管理区。(推荐使用的区的管理方式)
4 数据块
块是Oracle的最小存储单位,数据存放到块中,一个块占用相应的存储空间。
Oracle在每次请求数据时,都是以块为单位,所以块是Oracle读写数据的最小单位或者最基本的单位。Oracle每一次数据请求都是块的整数倍,若请求数据量不足一块时,也会读取整个块。块的标准大小是由初始化参数DB_BLOCK_SIZE设置。
4.1 数据块的特征:
- 数据块 'block' 是 Oracle '最小的存储单元',也是 '最小的 I/O 单元'
- 有五种大小:2KB、4KB、8KB(默认)、16KB、32KB ,必须是倍数增加
- 不可更改,除非重新创建数据库
4.2 数据块的常用命令
- 数据块大小:show parameter db_block_size ; 8192 = 8 * 1024
- 缓存大小 : show parameter db_cache_size;
- 一次从物理文件中读取数据块的数量 show parameter db_file_multiblock_read_count;
- 找到转储的文件(命令行):show parameter dump;
SQL> show parameter db_block_size ;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_block_size integer 8192
SQL> show parameter db_cache_size;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_cache_size big integer 0
SQL> show parameter db_file_multiblock_read_count;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_file_multiblock_read_count integer 128
SQL> show parameter dump;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
background_core_dump string partial
background_dump_dest string f:\app\diag\rdbms\lsxddb\lsxddb\trace
core_dump_dest string f:\app\diag\rdbms\lsxddb\lsxddb\cdump
max_dump_file_size string unlimited
shadow_core_dump string none
user_dump_dest string f:\app\diag\rdbms\lsxddb\lsxddb\trace
SQL>
4.3 数据块的格式
块中存放的数据和索引,无论是那种类型的数据,块的格式都是相同的,块的组成包括:块头、表目录、行目录、空余空间和行数据五部分组成,如下图
- 头部信息区(Overhead):通常块头、表目录、行目录这三部分合称为头部信息区,它不存放数据,存放的是整个块的信息。头部信息区的大小是可变的,一般来说其大小介于84字节到107字节之间。
- 块头(Header):存放块的基本信息,如块的物理地址、块所属的段的类型(属于数据段还是索引段)
- 表目录(Table Directoy):存放表的信息,若一些表是数据被存放在这个块中,那边该表的相关信息将被存放在"表目录"中
- 行目录(Row Directory):若块中有行数据存在,则这些行的信息被记录在行目录中,包括行的地址等
- 行数据(Row Data):真正存放表数据和索引数据的地方,这部分空间是已被数据行占用的空间
- 空余空间(Free Space):也称为自由空间,是一个块中为使用的区域,这些区域用于新行的插入和已经存在的行的更新
4.4 自由空间的使用
当往数据中Insert数据时块中的自由空间会减少;当对块中已经存在的行进行update进行数据修改(数据长度增加)时块的自由空间也会减少。 当使用delete语句删除块中的记录或者使用update语句把列的现有值更改成一个更小值的时候,Oracle会释放出一部分自由空间,但释放的自由空间不一定是连续的。由于合并数据块中不连续的自由空间会影响数据库的性能,所以在通常情况下,Oracle不会对不连续的自由空间进行合并。只有当insert或update取找不到连续的自由空间的时候,Oracle才会自动合并数据块中不联系的自由空间。
4.5 行衔接和行迁移:
当insert或update值超出了自由空间的大小则会发生行迁移或者行衔接。
- 行衔接(Row Chaining):若在往数据库中插入一行数据,数据很大(或行太长)以至于一个数据块无法存下整行数据,Oracle就会把一行数据分作几段存在几个数据块中,这个过程就叫做行衔接。在这种情况下,oracle会先把自由空间使用与该块链接的一块或多块数据块来容纳该行的数据。行衔接经常在插入比较大的行时才会发生,如包含long, long row, lob等类型的数据。在这些情况下行链接是不可避免的。导致了在一次读取过程中要读取多个数据块,引起I/O性能下降。
- 行迁移(Row Migrating):当update后的行长度大于修改前的行长度,并且该数据块中的自由空间已经比较小而不能完全容纳该行的数据时,就会发生行迁移。在这种情况下,Oracle会将整行的数据迁移到一个新的数据块上,而将该行原先的空间只放一个指针,指向该行的新的位置,注意,即使发生了行迁移,发生了行迁移的行的rowid 还是不会变化,这也是行迁移会引起数据库I/O性能降低的原因。
4.6 自由空间的自动管理
使用位图来管理和跟踪数据块,这种块的空间管理方式称之为"自动管理",其好处有
- 易于使用
- 可以更好地利于空间
- 可以对空间进行实时调整
4.7 自由空间的手动管理
数据库用户可以通过Pctfree、Pctused来调整块中空间的使用,这种管理方式称之为"手动管理",手动管理的缺点:不容易掌握、容易造成块中空间的浪费
- Pctfree:参数用于指定块中必须保留的最小空闲空间百分例。之所以要预留这样的空间,是因为update时,需要这些空间。如果update时,没有空余空间,Oracle就会分配一个新的块,这会产生行迁移(Row Migrating)。Select table_name,pct_free fromuser_tables
- Pctused:也是用于设置一个百分比,当块中已使用的空间的比例小于这个百分比的时候,这个块才被标识为有效状态。只有有效的块才被允许插入数据。