数据库对象最终都是以某种结构存放在数据文件中。达梦数据库的逻辑结构从大到小可以分为表空间、段、簇、页,数据库的操作过程也是对这些不同层级的逻辑结构进行维护和管理的过程。
达梦数据库由表空间组成,表空间由一个或多个数据文件组成。达梦数据库创建完成后,默认会创建四个表空间:SYSTEM表空间、ROLL表空间、MAIN表空间和TEMP表空间。
(1)SYSTEM表空间存放数据库的字典信息,相当于Oracle数据库的system、sysaux表空间。对于SYS、SYSSSO、SYSAUDITOR系统用户,默认的用户表空间是SYSTEM。
(2)ROLL表空间存放数据库事务的回滚数据,相当于Oracle数据库的undo表空间。设置参数有ROLLSEG、ROLLSEG_POOLS、ROLL_ON_ERR等,通常使用默认值即可。系统自动管理,无须用户干预。
(3)MAIN表空间相当于Oracle数据库的users表空间,也是SYSDBA的默认表空间。如果创建用户时未指定默认表空间,则MAIN就作为用户的默认表空间。
(4)TEMP表空间存放用户操作时产生的临时数据,相当于Oracle数据库的temp表空间。用户可以通过参数TEMP_PATH、TEMP_SIZE、TEMP_SPACE_LIMIT分别对TMEP表空间文件的路径、初始化大小、最大空间使用等进行调整。日常运行由系统自动管理,无须用户干预。
达梦数据库提供了系统视图V$TABLESPACE供查询表空间信息。
数据库对象在存储空间上的逻辑对象被称为段,相当于Oracle数据库的segment。
达梦数据库的段分三种。
(1)数据段:数据库中数据对象的逻辑结构。
(2)临时段:临时表空间(temp)创建的段。
(3)回滚段:回滚表空间(roll)创建的段。
达梦数据库提供了系统视图DBA_SEGMENTS(DBA视角)、USER_SEGMENTS(普通用户视角)供用户查询段信息。
段由一个或多个连续的存储空间区域组成,这些连续的存储空间称为簇,相当于Oracle数据库的extent(区)。
簇的存储空间是连续的,因此簇不能跨文件,由同一个数据文件中16个或32个或64个连续的数据页组成。在达梦数据库中,簇的大小由用户在创建数据库时指定,默认数量为16个。一旦创建好数据库,此后该数据库的簇的大小就不能改变。假设页的大小为8KB,簇的大小即为8KB×16=128KB。
当创建一个表、索引时,达梦数据库为表、索引的数据段分配至少一个簇,数据库会自动分配对应数量的空闲数据页。如果初始分配的簇中所有数据页都已经用完,或者新插入、更新数据需要更多的空间,达梦数据库将自动分配新的簇。
用户在删除表、索引对象中的记录时,达梦数据库通过修改数据文件中的位图来释放簇,释放后的空闲簇可以供其他对象使用。当用户删除了表中所有记录时,达梦数据库仍然会为该表保留1、2个簇供后续使用。若用户使用DROP语句来删除表、索引对象,则此表、索引对应的段以及段中包含的簇全部收回,并供存储于此表空间的其他对象使用。
对于临时表空间,达梦数据库会自动释放在执行SQL语句过程中产生的临时段,并将属于此临时段的簇空间归还给临时表空间。
对于回滚表空间,达梦数据库将定期检查回滚段,并确定是否需要从回滚段中释放一个或多个簇。
簇由连续的多个页组成。达梦数据库的页相当于Oracle数据库的block(块)。页是数据库的最小存储单元,也是数据库读写数据文件的最小单位。
达梦数据库在创建数据库时,可以将页大小设置为4KB、8KB(默认值)、16KB、32KB等。数据库建好后,页大小不能修改。页的逻辑结构如图2-9所示。
其中,“页头控制信息”包含关于页类型、页地址等信息。页的中部存放数据。为了更好地利用数据页,在数据页的尾部专门留出一部分空间用于存放行偏移数组,行偏移数组用于标识页上的空间占用情况,以便管理数据页自身的空间。
图2-9
数据库在更新(update)变长类型数据字段时,会发生数据记录的长度改变的情况,因此数据页有时会出现空闲空间不足,导致无法存放长度增加的数据记录。Oracle数据库的block有一个参数PCTFREE,默认值为10。该参数的意思是,当block的存储空间使用率达到90%时,该block不再插入新的数据记录,保留10%的空闲存储空间供更新操作使用。当数据块的可用空间无法容纳长度增长后的数据行时,Oracle数据库会将此行数据迁移到新的数据块中,在被迁移数据行原来所在位置保存一个数据记录在新数据块的指针。
达梦数据库也有一个数据页存储参数FILLFACTOR,它指定一个数据页初始化后,插入数据时最大可以使用空间的百分比(默认值为100)。
Oracle数据库在创建表、索引时可以设置PCTFREE参数值,创建完成后也可以随时修改。而达梦数据库的FILLFACTOR参数只能在创建表、索引时设置,一旦创建完成就不能修改。
当数据页使用空间百分比高于FILLFACTOR参数时,新的数据记录无法插入该页,只能插入到下一页。如果新的数据记录按聚集索引顺序插入该页,则会导致页拆分,即该页的记录拆分为两页存放。如果这种现象频繁发生,则会导致数据库性能下降。
设置FILLFACTOR参数时需要在空间和性能之间进行权衡。为了充分利用空间,用户可以设置一个很高的FILLFACTOR参数值,或者直接使用默认值100。这样做的好处是提高了存储空间利用率,同时数据存储密度增加,对于读取数据的操作也十分有利,可以有效地减少磁盘I/O。但是这也会导致在后续更新数据时,频繁引起页分裂,从而产生大量的磁盘I/O操作。为了提高更新数据的性能,可以设置一个相对较低的FILLFACTOR参数值,使后续执行更新操作时,可以尽量避免数据页的分裂。不过,这是以牺牲空间利用率来换取性能的提高。