Mysql数据库的进阶快速Read,面试前看一看,巩固自我,悦纳自我。

Mysql数据库

大部分内容载自JavaGuide,以及Java全栈

 Java 全栈知识体系 (pdai.tech)

Java 面试指南 | JavaGuide(Java面试 + 学习指南)

存储引擎

        说到数据库,绕不开的一个问题就是存储引擎,能够专门点出来提一下的一个是InnoDB,一个是MyISAM,这两个都是非常优秀的存储引擎,每一个都有自己的特点,但现在MySQL主要使用的引擎还是InnoDB引擎,InnoDB是一个事务型的存储引擎,它支持事务,并且使用了聚簇索引来储存索引与数据,支持行级锁,并支持外键,当然还有一些额外的优化,比如自适应哈希索引等。

索引

        索引的优缺点,有点就是可以快速找到自己所需要的数据,减少了查找的数据量,并且创建唯一索引保证数据的唯一性。缺点就是创建索引维护索引都是需要耗费时间,并且修改包含索引的数据的时候需要消耗一些额外的时间,并且还需要额外的物理空间来对索引进行保存。并且在数据量较低的情况下并不一定的需要索引,效率也不会提高很多。

        InnoDB使用B+树为储存索引的数据结构,主要是因为其他数据结构比如红黑树,层数太高,每一层储存数据太少,检索的次数过多,Hash索引,主要是因为Hash他的匹配度只能够达到精确匹配,如果是模糊匹配以及范围匹配,对Hash索引就不太友好,并且比较难以适用于排序以及分组的情况。

        索引还包括各种各样的索引,比如主键索引(值唯一的索引),普通索引(加速查询的索引),唯一索引(唯一的普通索引),覆盖索引(普通索引包含了需要查询的所有东西),联合索引(几个值联合列出的索引),隐藏索引等等。

聚簇索引的优点:查询速度快,排序查找和范围查找非常快,对比非聚簇索引少了一次IO操作

缺点:依赖有序地数据,如果修改索引数据,修改的代价相对较大

MySQL 表的文件

索引是有最左匹配原则的,联合索引的时候,进行查询需要对比索引的顺序来进行查询。

各数据结构的缺点:

Hash:不好进行范围查找,对于排序分组一类的比较拉胯

二叉树:二叉树性能太低,最低的效率达到了O(n)

平衡树:每一此IO只能读取一个节点,效率太慢了

红黑树:层数深度太高了,查找一个可能IO次数会很多

B树:一个叶子结点有一个数据,B树叶子结点过于独立,检索IO次数不一定

事务

        Mysql事务,何为事务,本质上事务是逻辑上的一组操作,要么都执行,要么都不执行,关系型的事务都有四个特性ACID 原子性,一致性,隔离性,持久性,以AID为手段来进行C的实现,这便是数据库事物的特性。原子性指的是命令要么全部完成要么全部失败,一致性指的是执行事务的时候数据保持不变,隔离性指的是一个事物不会被另外一个事物所干扰,持久性指的是一个事务完成之后将会持久改变。

隔离级别与锁

        Mysql他有这四个隔离级别,读未提交,读已提交,可重复度,串行化,他的安全性和效率成反比,随着隔离级别的提高都解决了一些关于安全性的问题,比如读已提交解决了脏读,可重复度解决了不可重复度,以及一定的解决了幻读的问题,隔离级别基本都是基于锁还有MVCC机制来进行实现的,Mysql默认的隔离级别是可重复度,解决了脏读和不可重复度以及一点的解决了幻读的问题。

        在锁这一方面,InnoDB与MyISAM有一些区别,InnoDB支持行级锁,锁的粒度更低,并发的程度也就更高,而MyISAM仅支持表级锁,力度太高,并发效率低下,但实现简单,行级锁会产生死锁的问题,死锁产生的原因1.互斥,2.占有且等待,3.不可剥夺,4.一直等待,Mysql解决死锁问题的方法也很简单,设置事务的超时时间或则检测发生了死锁问题的事务,然后将价值较小的那一方进行回滚。InnoDB里面是有多种行级锁的记录锁(锁数据),间隙锁(锁范围),临键锁(记录锁与间隙锁的集合)。如果是RR级别,行级锁默认是临键锁,但如果锁的是唯一索引那么便会进行优化,变为记录锁,当然还有共享锁与排他锁,S锁与S锁兼容,其他锁接不兼容。还有意向锁,意向锁是为了表锁判断是否可以对某张表进行上锁。

        再说快照读与当前读,快照读就是读取一个快照版本里面的数据,当前读就是读取最新的一个数据。

三大日志

        Mysql包含三个日志,binlog(归档日志)和事务日志 redo log(重做日志)和 undo log(回滚日志)。

        redo log是引擎级别的日志,redo log日志主要是为了防止Mysql突然挂机了或死机了,重启时进行效验的日志,保持数据的完整性和持久性。Mysql是数据以页为单位,查找数据时,磁盘的数据会先放入Buffer Pool,后续的查询如果Buffer Pool有则直接拿出,如果没有在从磁盘中IO拿出,减少IO次数,然后将所执行的语句,‘在某个数据页上做了什么修改’ 写进redo log buffer里面,然后再刷盘到日志里面。刷盘的时机有很多种,比如提交事务就刷盘,log buffer空间不足就刷盘,后台线程每隔一秒刷新然后刷盘,并且可以控制刷盘策略,其中默认的刷盘策略是当事务提交成功就会进行刷盘,这是为了数据安全的考虑下。当然还有一个后台线程每隔一秒默默刷盘。

        binlog是逻辑日志,属于Mysql Sever层的,记录的是 类似于 “给 ID=2 这一行的 c 字段加 1” 这种的日志,binlog的主要作用就是数据备份,主备、主主、主从,binlog按顺序记录所有涉及更新的逻辑操作,binlog有三种保存机制,第一种statement,记录完整的Sql语句的原文,第二种row,记录一些额外数据,第三种mixed,记录结合前两种,判断是否会可能引起数据不一致,如果是,就用row就用statement格式。写入的时候将会一条条写入binlog cache里面,等事务提交之后再讲binlog cache的数据记入binlog文件当中,当然如果超出了binlog cache的内存大小,也会暂存到硬盘当中。

        redo log和binlog他们如果一个记录了,一个没记录就会有bug产生,当数据恢复的时候究竟是选择相信redo log还是binlog,所以就有了两阶段的提交,第一阶段提交redo log会有一个字段prepare,第二阶段binlog记录完之后redo log字段就会变为commit,当redo log发现字段为prepare而且binlog没有记录的情况下就会回滚该事物。

        undo log是回滚日志我们知道如果想要保证事务的原子性,就需要在异常发生时,对已经执行的操作进行回滚,在 MySQL 中,恢复机制是通过 回滚日志(undo log)。并且,回滚日志会先于数据持久化到磁盘上。这样就保证了即使遇到数据库突然宕机等情况,当用户再次启动数据库的时候,数据库还能够通过查询回滚日志来回滚将之前未完成的事务。另外,MVCC 的实现依赖于:隐藏字段、Read View、undo log。

MVCC的实现

        MVCC是一个在多个并发事务之中,保持各个事务的隔离性和一致性的手段。在读操作的时候,会读取MVCC中不晚于读操作时候的相关数据,也就是快照读。写操作的时候,会加一个数据快照,在数据快照中进行修改了再将修改后的数据写入数据,当然在RR的情况下,在写操作并未提交的同时如果有其他的事务进来,尽管提交了,在快照版本中并不会被其他的写操作所看见,但在RC的情况就不一样了,在其他写操作的同时,事务提交了,那么会被其他的事务给看见。

        InnoDB对MVCC的实现,MVCC实现依赖于:隐藏字段、Read View、undo log。隐藏字段有三个字段,一个是事物的ID,一个是回滚的指针所向,一个是在没有主键索引和非空唯一值的自动生成的隐藏聚簇索引。ReadView里面包括的一些字段来判断事务是否可见,比如在这之后创建的事务不可见,在这之前的事务可见,还有一些正在活跃的事务不可见,undo log主要是进行数据恢复,回滚,还有读取之前版本的数据,进行快照读。

        MVCC➕Next-key-Lock 防止幻读,执行当前读的情况下,RR默认使用间隙锁进行锁定,为了防止查找一个范围的时候,其他事务添加新的数据,而这条新增的数据导致了幻读,所以会锁定他们的间隙,防止幻读。

MySQL执行计划分析

可以看到,执行计划结果中共有 12 列,各列代表的含义总结如下表:

列名含义
idSELECT 查询的序列标识符
select_typeSELECT 关键字对应的查询类型
table用到的表名
partitions匹配的分区,对于未分区的表,值为 NULL
type表的访问方法
possible_keys可能用到的索引
key实际用到的索引
key_len所选索引的长度
ref当使用索引等值查询时,与索引作比较的列或常量
rows预计要读取的行数
filtered按表条件过滤后,留存的记录数的百分比
Extra附加信息

(之后补充)

隐式转换

        左右两边的数据类型是不一样的话,就会发生隐式转换,当类型左边为数值类型,右边为字符类型不会有高的效率缩减,但如果反之,效率就会变得很低,变为全表扫描,基本上需要设定的就是类型对类型,并且尽量查询字段要用引号来进行。

Mysql优化

img

        Mysql的语句执行过程,首先进行缓存的查找,如果查找到缓存了,那进行返回,如果没有查找到缓存,那么进行解析器解析成为解析树,解析树来验证语法是否正确,解析完之后会去查询优化器进行优化,优化的方法比如:重新定义表的顺序,最大最小函数通过索引直接快速查找,limit函数当达到数目之后直接停止等待,当优化完了之后,生成一个执行计划,便会查询执行引擎,执行引擎里面包括了各种各样的存储引擎接口,查询执行引擎根据执行计划逐步执行handler API也就是接口便可以得到所想要的结果。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值