两大部分:存储(文件系统),程序实例。
程序实例分为8个模块:
1、存储管理模块:将数据的逻辑关系转换为物理存储关系。
2、缓存机制模块:优化执行效率。
3、SQL解析模块:解析SQL语句。
4、日志管理模块:记录操作。
5、权限划分模块:进行多用户管理。(管理员与用户)
6、容灾机制模块:灾难恢复。
7、索引管理模块:优化数据查询效率。
8、锁管理模块:使得数据库支持并发操作。
索引选择原则:
1.较频繁的作为查询条件的字段
2.重复太多的字段不适合单独创建索引,即使频繁作为查询条件
3.不会出现在where子句中的字段不应该创建索引
索引数据结构:
1.建立二叉查找树进行二分查找
(时间复杂度O(logn),删/增节点可能会变为一个线性表,查找的效率会很低 -->O(n))
2.建立B-Tree结构进行查找(读作B树)
3.建立B+Tree结构进行查找(mysql 索引主要结构)
4.建立Hash结构进行查找
磁盘IO的次数由索引树的高度决定
如果每个节点最多有m个孩子,又叫M阶B-tree的图示:(M=3就是为三阶)
定义
所有叶子节点都在同一层,且不包含其它关键字信息
ceil(m/2)=ceil(3/2)=2 向上取整
定义一条记录为一个二元组[key,data] ,key为记录的键值,对应表中的主键值,data为一行记录中除主键外的数据。对于不同的记录,key值互不相同
非终端节点的指针的个数 比关键字的个数多一个
拿磁盘块2来举例, p1 8 p2 12 p3
p1指向的关键字是 小于8的磁盘块5
p2指向的磁盘块 是 大于8 小于12的磁盘块6
p3指向的 是大于12的磁盘块7
模拟读取关键字信息为29需要读取几次磁盘 查找几次
①:先从根节点开始,把跟节点所在的磁盘块读取到内存中. 【发生了一次磁盘IO】
②:比较关键字29,在17和35之间,需要找到磁盘1中p2指向的磁盘块3 ,然后把磁盘3读取到内存中【发生了第二次磁盘IO】
③:对比关键字29,和磁盘3中保存的关键字 26,30 ,发现29在26,30之间。然后需要读取磁盘3中p2指向的磁盘块8 【发生第三次IO】
④:对比关键字29,和磁盘8保存的关键字28,29,然后查询出29号关键字。
B-Tree每个节点中不仅包含数据的key值,还有data值。而每一个页的存储空间是有限的,如果data数据较大时将会导致每个节点(即一个页)能存储的key的数量很小,当存储的数据量很大时同样会导致B-Tree的深度较大,增大查询时的磁盘I/O次数,进而影响查询效率。
在B+Tree中,所有数据记录节点都是按照键值大小顺序存放在同一层的叶子节点上,而非叶子节点上只存储key值信息,这样可以大大加大每个节点存储的key值数量,降低B+Tree的高度。
叶子节点形成有序链表
B+Tree查询 根节点–>非叶子节点(仅用来做索引)–>叶子节点(查询稳定)
B+Tree更适合做索引
理论上hash索引比B+Tree快.由其自身特性导致的缺点:
适用于字段值是固定的几个值,如男、女,颜色;便于高效统计。Oracle支持位图索引,数据结构了类似B+树。锁很严重,可能因为某行修改都会锁。适合并发较少,统计较多的情况
索引 ----- 二叉树、平衡二叉树、b-tree、b+tree详解
密集索引是所有值都有索引,稀疏是只有部分键才有
数据库中的B+Tree索引可以分为聚集索引(clustered index)和辅助索引(secondary index)。
上面的B+Tree示例图在数据库中的实现即为聚集索引,聚集索引的B+Tree中的叶子节点存放的是整张表的行记录数据。
InnoDB如果不是搜索主键,那么要在稀疏索引找到然后在去主键索引获取全部信息。MyISAM是都是通过指向完整的数据
InnoDB采用主键->第一个非空唯一->生成隐藏的优先级作为密集索引(唯一)
表结构存储在 *.frm中
MyISAM索引和数据是分开存储的 *.MYI存储索引 *.MYD存储数据
InnoDB索引和数据是存在一起的.ibd
系统从磁盘中读取数据是以磁盘块读取的,位于一个磁盘块中的数据会一次读取出来加载到内存中;
mysql的存储引擎中有 页(Page) 的概念,页是磁盘管理数据的最小单位,mysql的页的设置大小为16K。我们可以通过 show variables like 'innodb_page_size';
来看mysql服务器设置页的大小。
mysql从磁盘中读取数据是以页为单位,而往往一个磁盘块的大小是不够页的大小的,因此InnoDB每次申请磁盘空间时都会是若干地址连续磁盘块来达到页的大小16KB。
InnoDB在把磁盘数据读入到磁盘时会以页为基本单位,在查询数据时如果一个页中的每条数据都能有助于定位数据记录的位置,这将会减少磁盘I/O次数,提高查询效率
。