段与文件

175 阅读7分钟

        数据保存在数据库中,各种各样的配置数据以及其他信息作为文件保存在磁盘上。数据库内部,段是各类数据的逻辑容器。

        表是数据库存储的基本逻辑单元,与关系型(relational model)中的实体(entity)相对应。表通常由列与行的两维结构组成。尽管有效Oracle的对象关系结构延伸或打破了此定义。
        Oracle提供了大量不同类型的表,每一种都有其独特的逻辑或物理存储特性,如下所述。

  • 堆表 这是默认的表类型。如果在CREATE TABLE时不指定任何选项,你将得到一个堆表(heap table)。术语堆(heap)表示存储在表中的记录没有特定的顺序。堆表中的每一条记录都通过ROWID来唯一标识,可用ROWID来定位记录在磁盘上的位置。
  • 散列聚促表 这种表中的记录的物理位置由主键决定。这样不需要进行索引查找就可以通过主键快速地定位此记录。有序散列聚促(sorted hash cluster)是它的一个变体,其中的特定散列值对应的二级路是通过特定的排序顺序(sort sequence)检索的。
  • 索引组织表 这种表是按照类似于B*tree索引的方式组织的,其区别在于“叶子”块包含的是记录本身,而不是如同真实的B*tree那样只包含指向记录的指针。
  • 索引聚促 索引聚促在同一个段中保存多张表的内容,共享同一个键的记录保存在一起。可以认为它属于“预联结”的数据。
  • 对象表 对象表是基于Oracle对象类型创建的表。它们是通过对象的REF(类似于指针)而不是通过主键定位的,因此它的结构比普通标更加复杂。
  • 嵌套表 这是一种具备关系表特性的对象类型,可以将其“嵌入”到堆表的一个列中。表中的每条主记录,包含了嵌套表列的多条详细记录。
  • 外部表 它们是映射到存在数据库外部的文件上的表。如果文件需要被加载到数据库中,而又希望省略掉将其加载到中间表这一中间步骤,就可以使用外部表。
  • 临时表 主动表可以显式地创建,也可能被动地创建,在其中存放的数据只在当前会话或当前事务中可见。         如此多的表类型使人望而生畏,由此带来的性能调优方法的排列组合也相当多。不过数据库活动主要还是集中发送在传统的堆表上。

索引

        索引的存在主要是为了提高SQL语句与数据库的性能。因此对数据库性能优化的从业者来讲,透彻地理解索引的相关原理与实践非常必要。
        我们将在此提供一个索引选项的简要描述。

  • B*tree索引 这是Oracle默认的索引类型。B*tree索引由一个层级树组成,其中每层都包含指向下一层的指针。最终层级(叶子块)指向它们对应的数据记录。B*tree索引非常灵活且也是经过了时间的检验,对几乎所有的应用来说都是最常用的索引类型。
  • 位图索引 位图索引是给定列中所有取值组成的一个位图结构。这些紧凑结构可以被快速扫描,多个位图也可以进行有效的合并,这就使得它们在快速检索与索引合并方面比B*tree索引要高效得多。然而,位图索引会增加锁争用,也不支持进行范扫描。因此,位图索引经常被用在数据仓库数据库中,因为在这里大部分访问都是只读的。
  • 函数索引 这是一个基于表达式而不是列名创建的索引。这种索引可以优化在WHERE子句中出现对应表达式的查询,但是必须有确定的表达书组成,也就是那些同样的输入始终出现同样结果的表达式。
  • 虚拟索引 虚拟索引是没有物理索引的索引定义。在进行性能优化时,这些定义非常有用,因为有了它们,你就可以知道创建特定索引后执行计划将如何变化。

块、区间、段以及分区

        表与索引都由被称为区间(extend)的独立存储单元组成的。区间是由非常小的称为块(block)的存储单元组成的,块的大小一般在8KB到32KB之间。当表或者索引空间增长时,额外的区间就需要加进来以满足其需求。区间的大小可以在表定义中明确确定,但是当前Oracle的最佳实践是让其自动分配(使用自动段存储管理,即Automatic Segment Storage Management,简称ASSM)。
        对非分区的表与索引来讲,区间是单一段(segment)的一部分,该段表示表或索引的物理存储。分区表或索引则由多段组成,每个段表示一个分区(partition)。当表与索引中有LOB(嵌入的大对象)、嵌套表或索引组织表时,它们也可以由多个段组成。

表空间与数据文件

        段必须属于特定的表空间(tablespace),该表空间定义了段的存储特性(比如块大小)。表空间由多个数据文件(datafile)组成,数据文件可以表现为操作系统文件、裸磁盘分区或自动存储管理文件。段所归属的表空间决定了组成这个段的区间都包含在哪些数据文件中。段可以分布在多个数据文件上,但是一个区间只能呆在一个特定的数据文件中。

回滚段

        为了支持ROLLBACK语句,也就是回滚仍然没有被提交的事务,Oracle将被修改的数据块的“前镜像”副本保存在一个称为回滚或撤销段的结构中。这些段也用来实现一致读,以确保查询期间表上发生的变化不会反映在查询结果中。

重做日志与归档日志

        因为事务必须具备持久性,所以事务提交时必须将相应的事务信息写到磁盘。否则,如果事务信息在内存中时数据库突然崩溃,相应的事务就会丢失。为了最小化这些必要的IO,几乎所有的数据库系统在提交时都使用事务日志来记录事务信息。在Oracle中,这个日志称为重做日志(因为你可以利用此日志来重做事务)。
        Oracle会循环重用多个在线重做日志。当日志上的所有信息都已写入到数据库文件,并且在必要情况下日志已经归档以后,Oracle可以覆盖掉对应的在线日志文件。
        归档重做日志是在线重做日志的副本,当出现磁盘故障时可用它来做基于时间点的数据恢复。在恢复完在线备份后,可用归档日志来应用事务,知道数据库恢复到最新状态。

闪回日志

        使用重做日志“前滚”(rolling forward)可以对一个备份做完全恢复,但是这样耗时太久,特别是当使用的不是最近的备份时。Oracle的闪回日志提供了另一种选择。闪回日志保存回滚信息,与保存在回滚段中的信息类似。如果发生逻辑损坏,就可以用这个信息来“回滚”数据库。Oracle还支持其他类型的闪回技术:闪回查询支持再次执行之前已执行过的查询;闪回数据归档可以保存闪回信息,以满足长期的归档与审计目的。