RDBMS是咱们常见的一些存储数据的仓库,不管是作前端仍是后端,都会接触到。前端
咱们常见的数据处理,都是经过sql来和数据库作交互的,所以形成了许多人对数据库认知比较模糊,底层的架构也不是很清晰,从本周开始,咱们介绍些数据库的基础知识,来了解数据库引擎是如何工做的,以及如何设计更好的索引的方法论,欢迎一块儿探讨。mysql
咱们以mysql的架构为例,进行说明。sql
最上层用于链接、线程处理;第二层中包含了大多数 的核心服务,包括了对 SQL 的解析、分析、优化和缓存等功能,存储过程、触发器和视图都是在这里实现的;而第三层就是 真正负责数据的存储和提取的存储引擎,例如:InnoDB、MyISAM等,文中对存储引擎的介绍都是对 InnoDB 实现的分析。数据库
在整个数据库体系结构中,咱们可使用不一样的存储引擎来存储数据,而绝大多数存储引擎都以二进制的形式存储数据。后端
在 InnoDB 存储引擎中,全部的数据都被逻辑地存放在表空间中,表空间(tablespace)是存储引擎中最高的存储逻辑单位,在表空间的下面又包括段(segment)、区(extent)、页(page):缓存
同一个数据库实例的全部表空间都有相同的页大小;默认状况下,表空间中的页大小都为 16KB,固然也能够经过改变 innodb_page_size 选项对默认大小进行修改,须要注意的是不一样的页大小最终也会致使区大小的不一样:服务器
从图中能够看出,在 InnoDB 存储引擎中,一个区的大小最小为 1MB,页的数量最少为 64 个。架构
在咱们经常使用的sql理解中,数据是以行的形式读取出来的,其实否则,经过上述的结构,咱们能够了解到,单次从磁盘读取单位是页,而不是行,也就是说,你即使只读取一行记录,从磁盘中也是会读取一页的,固然了单页读取代价也是蛮高的,通常都会进行预读,这些后续再说。优化
关系型数据库管理系统最重要的一个目标就是,确保表或者索引中的数据是随时能够用的。那么为了尽量的实现这个目标,会使用内存中的缓冲池来最小化磁盘活动。spa
每个缓冲池都足够大,大到能够存放许多页,多是成千上万的页。
缓冲池管理器将尽力确保常用的数据被保存于池中,以免一些没必要要的磁盘读。若是一个索引或者表页在缓冲池中被找到,那么将会处理很快。
若是在缓冲池中,没有找到数据,会从磁盘服务器的缓冲区里面去读取。
磁盘服务器的缓冲区,如同数据库的缓冲池读取同样,磁盘服务器试图将频繁使用的数据保留在内存中,以下降高昂的磁盘读取成本。这个读取成本大概会在1ms左右。
若是磁盘服务器的缓冲池中依然没有找到数据,此时就必需要从磁盘读取了,此时读取又分区随机读取和顺序读取。
咱们必须记住一个页包含了多条记录,咱们可能须要该页上的全部行,也多是其中一部分,或者是一行,但所花费的成本都是相同的,读取一个页,须要一次随机I/O,大约须要10ms的时间。
时间组成:
咱们能够看到,一次随机IO须要耗时的时间仍是好久的,10ms对计算机来讲是一个很长的时间节点了。
若是咱们须要将多个页读取到缓冲池中,并按顺序处理它们,此时读取的速度回变的很快,具体的原理,在B树索引中也有过介绍,此时读取每一个页面(4kb)所花费的时间大概为0.1ms左右,这个时间消耗对随机IO有很大的优点。
如下几种状况,会对数据进行顺序读取。
全表扫描
全索引扫描
索引片扫描
经过聚蔟索引扫描表行
顺序读取有两个重要的优点:
- 同时读取多个页意味着平均读取每一个页的时间将会减小。在当前磁盘服务器条件下,对于4kb大小的页而言,这一值可能会低于0.1ms(40MB/s)
- 因为数据库引擎知道须要读取哪些页,全部能够在页被真正请求以前就提早将其读取进来,咱们称为预读。
数据库中的 B+ 树索引能够分为汇集索引(clustered index)和辅助索引(secondary index),它们之间的最大区别就是,汇集索引中存放着一条行记录的所有信息,而辅助索引中只包含索引列和一个用于查找对应行记录或者主键记录的指针。
关于索引的B+树结构,网上有不少文章进行分析了,咱们就不在一一介绍。
引用:
https://draveness.me/mysql-innodb
-----------------------------------------------------------------------------
想看更多有趣原创的技术文章,扫描关注公众号。
关注我的成长和游戏研发,推进国内游戏社区的成长与进步。