MySQL 技术内幕——数据库架构

如何设计一个数据库?

要设计一个关系型数据库,首先要划分为两部分,存储模块和程序实例模块,程序实例实现了对存储模块的管理。

MySQL 技术内幕——数据库架构_第1张图片

其中索引管理和锁管理是重点。

1、为什么要使用索引?

最基本的数据查询方式便是全表扫描,全表扫描是非常慢的,需要避免。索引便是一种更高效的查询机制。

2、什么样的信息能成为索引?

主键、唯一键以及普通键。

3、索引的数据结构?

索引的数据结构分为树结构和 Hash 结构。

索引最简单的树结构便是二叉查找树,还有平衡二叉树、红黑树、B 树、B+ 树。MySQL 存储引擎 InnoDB 的 B 树索引便是通过 B+ 树来实现的。

下面详细看下这些数据结构,以体验其优势和劣势:

(1) 二叉查找树

特点:每个节点最多有两个子树,称为左子树和右子树;对于每个节点的值 x,其左子树值均小于 x,右子树的值均大于 x。

查找方式:二分查找。时间复杂度 O(logn)。

缺点:有可能变成线性的二叉树,查询时间复杂度会变为 O(n),大大降低了查询效率。

(2) 平衡二叉树

特点:在二叉查找树的基础上,任意一个节点左子树和右子树的高度均不超过 1。

查找方式:二分查找,时间复杂度 O(logn)。

缺点:平衡二叉树是利用树的旋转特性,来保证树是平衡二叉树,时间复杂度会维持在 O(logn),但是如果树的深度特别深,就会增加大量的 IO 操作,其检索性能会比全表扫描还要差很多。

那么为了即降低时间复杂度,又降低 IO 的次数,需要让树变的矮一些,每个节点能存储的数据多一些,即引出了 B 树。

(3) B 树

B 树又称为平衡多路查找树,如果每个节点最有 m 个孩子,那么这样的树便是 m 阶 B 树,下面是一个三阶 B 树:

MySQL 技术内幕——数据库架构_第2张图片

特点:

  • 根节点至少包括两个孩子;
  • 树中每个节点最多含有 m 个孩子(m>=2);
  • 除根节点和叶子节点外,其他节点至少有 ceil(m/2) 个孩子,ceil 函数表示取上限,例如 ceil(3/2) = 2;
  • 所有叶子节点都位于同一层,即叶子节点的高度都是一样的。

查找的时间复杂度 O(logn)。

(4) B+ 树

B+ 树是比 B 树更优秀的数据结构。下面是一个三阶 B+ 树:

MySQL 技术内幕——数据库架构_第3张图片

B+ 树是 B 树的变体,其定义基本与 B 树相同,除了:

  • 非叶子节点的子树指针与关键字个数相同;
  • 非叶子节点的子树指针P[i],指向关键字值 [K[i], K[i+1]) 的子树;
  • 非叶子节点仅用来做索引,数据都保存在叶子节点中;
  • 所有叶子节点均有一个链指针指向下一个叶子节点,并按大小顺序链接,作用:方便直接在叶子节点做范围统计。

B+ 树所有的检索都是从根部开始,检索到叶子节点才能结束,非叶子节点仅用来做索引,不存储数据,这样非叶子节点就能存储更多的关键字了,使得 B+ 树比 B 树更矮,IO 性能会更好。

查找的时间复杂度 O(logn)。

经过上面的分析,发现 B+ 树更适合用来存储索引,原因如下:

  • B+ 树的磁盘 IO 代价更低;
  • B+ 树查询效率更加稳定;
  • B+ 树更有利于对数据库的扫描;

除了 B 树索引,有些存储引擎还支持 Hash 索引,例如 InnoDB。

Hash 索引

Hash 索引使用了 Hash 表来存储索引,检索只需要计算一次 Hash 值便可以定位 “桶” 的位置,然后把 “桶” 里面的数据全部加载进内存,由于 “桶” 里面的数据是一个链表,顺着链表便可以定位到索引的位置。

Hash 索引的查询效率理论上要比 B 树索引高。既然 Hash 索引性能好,那么为什么还要使用 B 树索引呢?

这是因为 Hash 索引是有缺点的:

  • 仅仅能满足 “=” “IN”,不能使用范围查询;
  • 无法被用来避免数据的排序操作;
  • 不能利用部分索引键查询;
  • 不能避免表扫描,Hash 索引是将索引键通过 Hash 运算之后,将 Hash 值和所对应行指针信息存放在链表节点中的,由于不同索引键存在相同 Hash 值,所以即使取出数据,也无法直接完成查询,还需要访问链表节点中的实际数据进行相应的比较;
  • 遇到大量 Hash 值相等的情况后,性能并不一定就会比 B 树索引高。

除了 B 树索引,Hash 索引,还有一些数据库支持 BitMap 索引,即位图索引,目前已知的是 Oracle 数据库支持,当表中的数据只有几种值时,例如性别字段,BitMap 索引就是最佳的选择了。BitMap 索引不适合高并发的联机事务处理系统,而适合于并发较少,且统计运算较多的系统。

4、密集索引和稀疏索引的区别?

定义
密集索引 密集索引文件中的每个搜索码值都对应一个索引值。即叶子节点不仅仅保存键位信息、该行数据的地址,还保存了位于同一行记录里的其他列的信息,由于密集索引决定了表的物理排列顺序,一个表只能有一个物理排列顺序,所以一个表只能创建一个密集索引。
稀疏索引 稀疏索引文件只为搜索码的某些值建立索引项。即叶子节点仅保存了键位信息、该行数据的地址。

InnoDB 主键索引、唯一索引、普通索引均属于稀疏索引。

InnoDB 有且仅有一个密集索引,这个密集索引的选取规则:

  • 若一个主键被定义,该主键则作为密集索引;
  • 若没有主键被定义,该表的第一个唯一非空索引则作为密集索引;
  • 若不满足以上条件,InnoDB 内部会生成一个隐藏主键(密集索引);
  • 在 InnoDB 中,非主键索引即是稀疏索引,存储了相关键位信息和该行数据的地址,包含两次查找,而密集索引只需要一次查找。

你可能感兴趣的:(MySQL)