1. mysql的整体架构
由连接器 -> 分析器 -> 查询缓存 -> 优化器 -> 执行器 -> 执行引擎组成。
连接器:负责校验用户身份。
分析器:语法分析
查询缓存:命中缓存直接返回结果,但是每次对表进行修改,缓存会清空,建议在某些静态表使用查询缓存来提高效率。
优化器:当表中存在索引的时候,优化sql语句使用索引提高效率。
执行器:执行sql语句。
2.mysql如何恢复数据
• mysql内部存在一个redoLog日志文件,每当出现修改语句的时候,执行器先把修改语句写到redoLog当中,并更新内存再返回结果,然后在系统空闲的时候把数据写入硬盘当中。redoLog相当于一个环形双端队列,当redoLog写满了就清除环形头部的部分数据;这样就不用每次对硬盘进行修改提高性能,需要注意的是redoLog是InnoDB特有的。
• 除了redoLog之外,还存在一个binLog用于系统归档,所有写入操作都记录在binLog当中,不会清除。不同点是redoLog是执行引擎特有的,binLog是mysql的Server层的。数据发生修改时,首先写入redoLog中当,更新内存为准备阶段,再写入binLog当中,提交事务。二次提交保证两份例子逻辑上的一致性。
• 因此,我们就可以通过最近的一次数据库备份,然后再备份点开始把binLog同步到需要恢复数据的那个时间点。
3.事务隔离级别有哪些?mysql的默认隔离级别是什么?
• 读未提交,读取到未提交的数据。
• 读已提交,读取已提交的数据。
• 可重复读,一个事务开启后读取到的数据,总是一样的,不管中间是否发生了数据修改。
• 串行化,读加锁写也加锁,所有操作串行化执行,最高级别。
mysql的默认隔离级别是读提交 READ-COMMITTED。
4.mysql事务如何实现的?
mysql在每次数据修改时,会记录一个回滚视图,比如有个事务把 t1 -> t2 , 修改后会记录一个 t2 -> t1 的视图,不同的事务级别有不同的视图,因为同一记录在数据库存在多个不同的版本,这就是MVCC,事务是通过mysql的MVCC多版本控制实现的事务,需要注意的是回滚日志也是非常占用硬盘资源的。
不同事务隔离级别,拿到的视图也是不一样的。
5. 索引是基于什么数据结构?
索引是为了提高查询效率而出现的一种概率,类似于数据库的一种目录。实现方式为B+树,但是为啥不用Hash , 二叉树, 数组呢?Hash数据结构,查询区间数据,需要遍历一次所有数据,时间复杂度是O(n);数组,在增加删除操作的时候需要挪动部分数组数据的下标,也不合适;二叉树基于二分搜索查询,修改数据后再平衡二叉树,查询和修改操作都是Log(n)。但是树高比较大, 树高越大从磁盘读取数据的次数就越多,也不合适。
B+树是一种N叉树数据结构的树,所有数据都存放在叶子节点上,非叶子节点只是起到一个索引的作用,查询修改时间复杂度log(n)
6.InnoDB索引存在那几种模型,区别?
索引分为主键索引和非主键索引(二级索引),两者之间的区别是:
• 当根据主键索引去查询时,通过ID主键即可查询出数据行。
• 当根据二级索引去查询时, 通过二级索引树查询到叶子节点上的主键值,然后再回表使用主键树,查询数据行。
7.索引如何维护?为何主键要设置为自增?
索引维护需要保证B+树的有序性,每次添加较大的ID行数据的时候,需要在B+树后插入一条新的数据,但是假如添加的数据行ID较小,则需要调整B+树前面的分支结构,假如前面的数据页已经满了,则需要分裂页,挪动后续所有的叶子节点位置,这样子肯定会影响性能。同理删除数据也一样,可能会造成分裂页的情况。
• 因此我们在数据库设计的时候,一般把主键设为自增,这样每次新增数据的时候都是在后续节点上进行添加节点;
• 同时表的删除操作,使用逻辑删除,deleted标志为删除,防止删除操作的时候发生页分裂,提高数据库系统性能。
• 前面讲过非主键索引的叶子节点上保存的是主键ID, 使用自增类型的主键保存在叶子节点上也可以节省索引的空间。
8.如何利用索引提升查询性能?
覆盖索引:非主键索引查询到是主键Id,再通过主键Id查询这个过程称为回表。 通过减少回表次数,提高性能。
最左前缀原则:当需要多条件查询,排序时,把有索引的字段写在醉左边,先通过索引快速定位到合适位置,然后向后遍历;同理,我们在建立联合索引的时候,通过最左原则,可以少维护一个索引字段。
索引下推:在使用联合索引的时候,先通过第一个字段的索引找到合适位置之后,sql引擎会自动判断第二个字段的值是否符合条件,如果符合条件的话,取出主键ID进行回表查询,优点:节省了一次回表次数,提高系统性能。
觉得不错的话,点个赞是对我最大的支持。如果有不对的地方,也欢迎留言。