数据库中的存储结构
在数据库中,不论读一行,还是读多行,都是将这些行所在的页进行加载。也就是说,数据库管理存储空间的基本单位是页(Page)。
行、页、区、段、表空间的关系如下图所示:
- 区(Extent)是比页大一级的存储结构,在 InnoDB 存储引擎中,一个区会分配 64 个连续的页。因为 InnoDB 中的页大小默认是 16KB,所以一个区的大小是 64*16KB=1MB。
- 段(Segment)由一个或多个区组成,区在文件系统是一个连续分配的空间(在 InnoDB 中是连续的 64 个页),不过在段中不要求区与区之间是相邻的。段是数据库中的分配单位,不同类型的数据库对象以不同的段形式存在。当我们创建数据表、索引的时候,就会相应创建对应的段。
- 表空间(Tablespace)是一个逻辑容器,表空间存储的对象是段,在一个表空间中可以有一个或多个段,但是一个段只能属于一个表空间。数据库由一个或多个表空间组成,表空间从管理上可以划分为系统表空间、用户表空间、撤销表空间、临时表空间等。
在 InnoDB 中存在两种表空间的类型:共享表空间和独立表空间。如果是共享表空间就意味着多张表共用一个表空间。如果是独立表空间,就意味着每张表有一个独立的表空间,也就是数据和索引信息都会保存在自己的表空间中。独立的表空间可以在不同的数据库之间进行迁移。
可以通过下面的命令来查看 InnoDB 的表空间类型:
show variables like 'innodb_file_per_table';
innodb_file_per_table=ON,这就意味着每张表都会单独保存为一个.ibd 文件。
数据页内的结构
页(Page)如果按类型划分的话,常见的有数据页(保存 B+ 树节点)、系统页、Undo 页和事务数据页等。数据页是我们最常使用的页。
查看页大小
show variables like '%innodb_page_size%';
页结构的示意图如下所示:
作用:
数据页之间采用链表的结构,让数据页之间不需要是物理上的连续,而是逻辑上的连续。
从数据页的角度看 B+ 树是如何进行查询的
每一个节点都是一个页,每一层上的节点之间通过双向链表链接。
在节点内部(也就是页结构的内部)记录之间是一个单向的链表,但是对记录进行查找,则可以通过页目录采用二分查找的方式来进行。
- B+ 树是如何进行记录检索的?
- 首先是从 B+ 树的根开始,逐层检索,直到找到叶子节点,也就是找到对应的数据页为止,将数据页加载到内存中。
- 页目录中的槽(slot)采用二分查找的方式先找到一个粗略的记录分组
- 然后再在分组中通过链表遍历的方式查找记录。
- 普通索引和唯一索引在查询效率上有什么不同?
唯一索引就是在普通索引上增加了约束性,也就是关键字唯一,找到了关键字就停止检索。
因此在普通索引的字段上进行查找也就是在内存中多几次“判断下一条记录”的操作,对于 CPU 来说,这些操作所消耗的时间是可以忽略不计的。
此文章为4月Day20学习笔记,内容来源于极客时间《SQL必知必会》