MySQL详解

提起mysql就要巴拉巴拉一下它的三大面试点,索引,锁 和事物,今天一个一个的来说:

    • 提起mysql就要巴拉巴拉一下它的三大面试点,索引,锁 和事物,今天一个一个的来说:
      • mysql架构

        • 先来一张mysql架构图来对mysql有一个整体的认知,mysql只要有一下几个部分组成
      • mysql连接器(Connectors)
        • 主要是和下边这张图片上的各种语言或者工具进行连接
      • 系统管理和控制工具(Management Serveices & Utilities)
        • 只要是DBA数据库人员进行配置维护,比如通过binlog日志进行恢复数据等作为程序员的我们知道即可就不去抢那碗饭了。
      • mysql连接池
        • SQL Layer MySQL业务层
      • SQL接口(SQL Interface)
        • 接收SQL DML(数据库的增删改查) DDL(对表的create、alter和drop操作)
      • 解析器(Parser)
        • 词法分析 分词 ----- 》形成语法树
      • 查询优化器(Optimizer)
        • mysql 觉得你写的SQL 不是完美的将进行优化
        • 例如:
          • where 从左到右 MySQL 找过滤力度最大的 ,先执行where id=1 and sex='男' 而将原来写的 where sex='男' and id=1优化
          • 索引是 1 、2、3 where后边是3、1、2 自动回将where后边的数据优化为 1、2、3 将索引全值命中,提高查询效率
      • 查询缓存(Cache和Buffer)
        • 把查询结果存起来
        • MySQL8.0后不再使用
      • 存储引擎(Pluggable Storage Engines)
        • MySQL的存储引擎是针对表进行指定的。(默认InnoDB)
      • mysql的执行流程
      • mysql的物理结构
        • mysql是通过文件系统对数据和索引进行存储
        • mysql通过物理结构可分为日志文件和数据索引文件
        • MySQL在Linux中的数据索引文件和日志文件都在/var/lib/mysql目录下
        • 日志文件采用顺序IO方式存储(记录速度快,叠加形式存储(首地址、偏移量),浪费空间)、数据文件采用随机IO方式存储(记录相对慢,记录地址,省空间)
      • 日志文件分类(介绍不分重要)
        • binlog日志
          • binlog记录了数据库所有的ddl语句和dml语句,但不包括select语句内容,语句以事件的形式保存,描述了数据的变更顺序,binlog还包括了每个更新语句的执行时间信息。如果是DDL语句,则直接记录到binlog日志,而DML语句,必须通过事务提交才能记录到binlog日志中。 生产中开启数据备份、恢复、主从
        • 慢查询日志(slow query log) 
          • SQL调优 定位慢的 select (默认关闭)
        • 重做日志(redo log)
          • 主要用做日志的持久化
        • 回滚日志(undo log)
          • 数据回滚
          • mvcc版本控制
        • 数据文件
          • .frm文件:主要存放与表相关的数据信息,主要包括表结构的定义信息
          • .ibd:使用独享表空间存储表数据和索引信息,一张表对应一个ibd文件。
          • ibdata文件:使用共享表空间存储表数据和索引信息,所有表共同使用一个或者多个ibdata文件。
      • 索引是面试逼问,工作常用的一个知识点,今天将从mysql的存储引擎到索引类别全方便讲解索引的使用和技巧
      • 先要讲一下为什么要使用索引
        • 索引就好像是一本书的目录,直接通过目录找到想看的章节,快速准确还节约时间,对于mysql就是可以减少IO的次数来提高速度
        • 索引可以自动排序降低了cpu的消耗
        • 但是一切事物都是有两面性,增加索引,数据库在进行增删改的操作时,不仅保存数据还有保存索引,将降低性能并且创建的索引越多,维护的树也多,曾有大佬测试过mysql在五百万数据的时候可以增加,但是这个只是大概数据还有看个人项目。
      • msql 的存储引擎(默认InnoDB)
        • InnoDB的默认数据结构是B+树,B+树不仅可以增加存储量还可以减少数据的IO次数,提高性能
        • B+的特点
          • 叶子节点存储所有的数据,如果是聚集索引,则叶子节点存储数据库中一条记录的所有数据,如果是非聚集索引将存储和索引的字段保持一致外加一个主键id
          • 叶子节点的数据是有顺讯的,有利于数据的查找。
          • 如果是三层的b+树将可以存储20G数据,如果是四层将可以达到几十T数据(存数量大)
      • 索引的分类(介绍重要的)
        • 主键索引
        • 唯一索引
        • 联合索引
        • 覆盖索引
          • 其中主键索引和唯一索引通过名字也可以明白,其中主键索引,假如在创建表时,如果没有创建索引,数据库将自动创建主键,因为她要创建所引书,将数据放到索引书中,其中主键是创建树的依旧,将根据主键的大小来创建一个树状的图(可自行百度查看树的结构),索引为了提高性能,尽量不要用uuid
          • 联合索引是创建多个索引,在查询中where后边的查询条件尽量包含在索引的中,在疲惫时,尽量不要存在计算,><!=,OR,等操作
          • 覆盖索引是为了避免回表
            • 回表:在创建非聚集索引的时候,所引树会根据索引的字段创建索引,但是当select查询的列中数据不包含在索引中,呢么索引树将会根据id去聚集索引树查找,因为聚集索引树存储了所有的数据,这个最后查询两个树,这种行为就是回表
          • 为了避免回表,再创建索引时,尽量创建的索引包含数据要查询索引的列数据
      • 索引创建场景
        • 主键自动建立唯一索引
        • 频繁作为查询条件的字段应该创建索引 where
        • 多表关联查询中,关联字段应该创建索引 on 两边都要创建索引
        • 查询中排序的字段,应该创建索引 B + tree 有顺序
        • 覆盖索引 好处是? 不需要回表 组合索引
        • 统计或者分组字段,应该创建索引
      • 索引失效
        • where后边的条件有计算
        • 有like这样模糊查询(张%)除此之外的like都会失效
        • 最左原则,联合索引的中间不能断
        • 存在><!= OR 这种比较类语句
        • 尽量少些*


      • 乐观锁
        • 乐观锁主要是用程序实现的,这个百度一下就好
      • 悲观锁
        • 表级锁
          • 使用的较少,这里不进行讲解
        • 行级锁
          • InnoDB行锁是通过给索引上的索引项加锁来实现的,因此InnoDB这种行锁实现特点意味着:只有通过索引条件检索的数据,InnoDB才使用行级锁,否则,InnoDB将使用表锁!
          • where 索引 行锁 否则 表锁
        • 间隙锁(RR级别有间隙锁)
          • 间隙锁母的:
            • 防止插入间隙内的数据
            • 防止已有数据更新为间隙内的数据
          • 间隙锁的特点
            • 非唯一索引等值:只要number(where后面的)在间隙里(2 3 4),不包含最后一个数(5)则不管id是多少都会阻塞。
            • 主键索引范围:只要id(在where后面的)在间隙里(2 4 5),则不管number是多少都会阻塞
            • 非唯一索引无穷大:修改的数据在索引外,会导致比这个大的数据全部阻塞
    • 事物
      • 事物的四大特性(ACID)
        • 原子性
        • 一致性
        • 隔离性
        • 持久性
      • 四大特性保证
        • 原子性和持久性是由redolog保证
        • 一致性是由undolog保证
        • 隔离性 :数据库一般有四种隔离级别
          • 脏读
          • 可重复读
          • 不可重复读
          • 串行化
          • mysql默认的隔离级别是RR可重复读(不能读取可以提交的数据),oracle默认的隔离级别是RC(可以读取已提交的数据),脏读是不加锁,读取了没提交的数据,串行化是只能一个一个线程的执行,易死锁,不利于并发,所以只剩下两种,呢两种的实行是根据mvcc进行控制,提到实行不得不提一下redolog和undolog
          • redolog:redolog是辅助数据持久化
          • mysql的落盘机

             

            • mysql是通过左边进行落盘,redolog是在右边进行落盘,当满足检查点的要求,将触动落盘,redolog的落盘是通过三种方式落盘
        • 当右边的落入,则左边的文件进行清除
        • 事务的回滚是根据undolog
          • 每一条数据在进行修改前都会创建undolog,将上一个版本的数据存入undolog
          • 每一条数据都有三个隐含字段,主键id 事物id 和回滚指针,回滚指针指向上一个版本
          • 当数据修改的时候,将会添加行写锁,当执行查询语句的时候,读到加锁的一行,将会上一个版本
        • mvcc
          • 快照读,读取的是记录的可见版本 (有可能是历史版本),不用加锁。(select)
          • 当前读,读取的是记录的最新版本,并且当前读返回的记录,都会加上锁,保证其他事务不会再并发修改这条记录。
          • mvcc是通过控制读取什么版本的数据来控制数据是否重复度和不可重复读问题(无法解决幻读)
          • 至于要读呢个版本就要提到一个事务链,和readview
            • RR隔离级别下,在每个事务开始的时候,会将当前系统中的所有的活跃事务拷贝到一个列表中(readview)
            • RC隔离级别下,在每个语句开始的时候,会将当前系统中的所有的活跃事务拷贝到一个列表中(readview)
            • RR每个事物开始的时候 会将当前系统所有的事物保存一个是readview中,在读的时候会有一个全局的global_readview 直到所有的数据全部提交,所有只能读前一个版本(究竟呢一个是前一个版本),需要用到事务链表最大值为高水位,最小值为低水位 如果当前值比高水位还有大 则当前数据不可读,如果比当前低水位小 则可以读 (事物链表中的数据是没有顺序的例如现在有 1 、 2 、3 、4 四个事物id 如果事物4先提交了呢么比最大的3 还要大 呢么说明还有123 没有提交,如果比1 还小 1 是里边的低水位 已经是最小值 说明这个值就是最新数据 所以可读
            • RC级别下 每次提交就会关闭一个readview 然后创建一个新的readview ,在读取的时候进行比较发现是空的 将读取最新提交的数据
    •  

   

原文地址:https://www.cnblogs.com/fjl0418/p/14022294.html