平时用的多的是mysql,但是公司项目用的是oracle,面试的时候不免问到各种对比,这里做一个基于个人理解的总结
堆表和索引组织表
mysql的存储引擎是基于表的,存储引擎又可以称为表类型。而且mysql是基于插件式的存储引擎,其中innoDB是面向索引组织表的、mylsam是面向堆表的、memory是面向内存的…
而oracle没有存储引擎的说法,创建表时也可以为表指定表的类型,oracle的create table是默认使用堆表结构的,当然了,oracle还支持索引组织表、聚集表等,需要额外使用organization进行声明。
之前我一直先入为主,认为索引组织表是主要的表类型。其实堆表是使用最多的,mysql最早默认存储引擎mylsam也是基于堆表的。postgreSQL也是完全面向堆表的
堆组织表的最大特点就是无序,数据是以堆的方式管理的,增加数据的时候,会使用堆中找到第一个能够放下此数据的自由空间。从表中删除数据的时候,允许以后的新插入的数据或者修改完毕的数据复用这块空间。当进行全表搜索的时候,数据获取的顺序和“命中”顺序有关(物理层面),和插入顺序无关。
堆组织表的主键和唯一索引区别不大,和普通索引的区别也基本是在唯一约束上的区别。创建索引可以优化查询性能,避免全表扫描。
索引组织表一定会有一个主键,即使不声明也会隐式分配一个主键。虽然从数据库层面来看,数据行还是无序的,但是索引组织表创建后,数据文件和索引文件是集中存放的,因此至少会存在一个主键索引。当数据进行查询的时候,优化器会看到表中存在索引,于是数据返回的顺序是按照主键排好序的。
在数据库层面看来,数据就是无序存放的,表空间中数据都是堆放着的,但是优化器在生成执行计划的时候如果发现存在索引,就会走索引进行优化。索引是给优化器准备。
对于序的理解
关系型数据库大多是基于集合的,而基于集合就需要保证每条数据都需要有唯一标识。同时从数据库层面来看,数据行都是无序的。也就是说,数据库中的所有数据最原始存放在数据库中的状态就是无序的。集合数据库的索引的一个最大的作用就是将无序的数据以某种方式组织起来。
这应该也是为什么采用B+树这种使得“数据有序”的结构作为基础的索引,而哈希索引这种底层无序的数据结构一般用于非基础索引。
也就是说,集合数据库中的数据最原始的状态就是基于堆的、无序的,如果想要查询某条数据将无可避免的进行全表扫描。而主键本质上是一条具有唯一约束的索引,唯一:它声明了可以唯一标识一条记录的字段