MySQL详解

逻辑架构

  • 第一层是服务器层,主要提供连接处理、授权认证、安全等功能。
  • 第二层实现了 MySQL核心服务功能,包括查询解析、分析、优化、缓存以及日期和时间等所有内置函数,所有跨存储引擎的功能都在这一层实现,例如存储过程、触发器、视图等。
  • 第三层是存储引擎层,存储引擎负责 MySQL 中数据的存储和提取。服务器通过 API与存储引擎通信,这些接口屏蔽了不同存储引擎的差异,使得差异对上层查询过程透明。除了会解析外键定义的 InnoDB外,存储引擎不会解析SQL,不同存储引擎之间也不会相互通信,只是简单响应上层服务器请求。

事务

事务的四大特性

  • 原子性 atomicity
    一个事务在逻辑上是必须不可分割的最小工作单元,整个事务中的所有操作要么全部提交成功,要么全部失败回滚,对于一个事务来说不可能只执行其中的一部分。
  • 一致性 consistency
    数据库总是从一个一致性的状态转换到另一个一致性的状态。
  • 隔离性 isolation
    针对并发事务而言,隔离性就是要隔离并发运行的多个事务之间的相互影响,一般来说一个事务所做的修改在最终提交以前,对其他事务是不可见的。
  • 持久性 durability
    一旦事务提交成功,其修改就会永久保存到数据库中,此时即使系统崩溃,修改的数据也不会丢失。

并发事务带来的问题

  • 脏读(Dirty read):
    当⼀个事务正在访问数据并且对数据进⾏了修改,⽽这种修改还没有提交到数据库中,这时另外⼀个事务也访问了这个数据,然后使⽤了这个数据。因为这个数据是还没有提交的数据,那么另外⼀个事务读到的这个数据是“脏数据”,依据“脏数据”所做的操作可能是不正确的。
  • 不可重复读(Unrepeatableread):
    指在⼀个事务内多次读同⼀数据。在这个事务还没有结束时,另⼀个事务也访问该数据。那么,在第⼀个事务中的两次读数据之间,由于第⼆个事务的修改导致第⼀个事务两次读取的数据可能不太⼀样。这就发⽣了在⼀个事务内两次读到的数据是不⼀样的情况,因此称为不可重复读。
  • 幻读(Phantom read):
    幻读与不可重复读类似。它发⽣在⼀个事务(T1)读取了⼏⾏数据,接着另⼀个并发事务(T2)插⼊了⼀些数据时。在随后的查询中,第⼀个事务(T1)就会发现多了⼀些原本不存在的记录,就好像发⽣了幻觉⼀样,所以称为幻读。

MySQL 的隔离级别

  • 未提交读 READ UNCOMMITTED
    在该级别事务中的修改即使没有被提交,对其他事务也是可见的。事务可以读取其他事务修改完但未提交的数据,这种问题称为脏读。这个级别还会导致不可重复读和幻读,性能没有比其他级别好很多,很少使用。
  • 提交读 READ COMMITTED
    多数数据库系统默认的隔离级别。提交读满足了隔离性的简单定义:一个事务开始时只能"看见"已经提交的事务所做的修改。换句话说,一个事务从开始直到提交之前的任何修改对其他事务都是不可见的。也叫不可重复读,因为两次执行同样的查询可能会得到不同结果。
  • 可重复读 REPEATABLE READ(MySQL默认的隔离级别)
    可重复读解决了不可重复读的问题,保证了在同一个事务中多次读取同样的记录结果一致。但还是无法解决幻读,所谓幻读指的是当某个事务在读取某个范围内的记录时,会产生幻行。InnoDB存储引擎通过多版本并发控制MVCC 解决幻读的问题。
  • 可串行化 SERIALIZABLE
    最高的隔离级别,通过强制事务串行执行避免幻读。可串行化会在读取的每一行数据上都加锁,可能导致大量的超时和锁争用的问题。实际应用中很少用到这个隔离级别,只有非常需要确保数据一致性且可以接受没有并发的情况下才考虑该级别。

MVCC

  • MVCC 是多版本并发控制,在很多情况下避免加锁,大都实现了非阻塞的读操作,写操作也只锁定必要的行。
  • InnoDB 的 MVCC通过在每行记录后面保存两个隐藏列来实现,这两个列分别保存了行的创建时间和过期时间。不过存储的不是实际的时间值而是系统版本号,每开始一个新的事务系统版本号都会自动递增,事务开始时刻的系统版本号会作为事务的版本号,用来和查询到的每行记录的版本号比较。
  • MVCC 只能在 READ COMMITTED 和 REPEATABLE READ 两个隔离级别下工作,因为 READUNCOMMITTED 总是读取最新的数据行,而不是符合当前事务版本的数据行,而 SERIALIZABLE 则会对所有读取的行都加锁。

存储引擎

MyISAM和InnoDB区别

  • 是否⽀持⾏级锁 : MyISAM 只有表级锁(table-level locking),⽽InnoDB ⽀持⾏级锁(row-level locking)和表级锁,默认为⾏级锁。
  • 是否⽀持事务和崩溃后的安全恢复: MyISAM 强调的是性能,每次查询具有原⼦性,其执⾏速度⽐InnoDB类型更快,但是不提供事务⽀持。但是InnoDB 提供事务⽀持事务,外部键等⾼级数据库功能。 具有事务(commit)、回滚(rollback)和崩溃修复能⼒(crash recovery capabilities)的事务安全(transaction-safe (ACID compliant))型表。
  • 是否⽀持外键: MyISAM不⽀持,⽽InnoDB⽀持。
  • 是否⽀持MVCC :仅 InnoDB ⽀持。应对⾼并发事务, MVCC⽐单纯的加锁更⾼效;MVCC只在READ COMMITTED 和 REPEATABLE READ 两个隔离级别下⼯作;MVCC可以使⽤ 乐观(optimistic)锁 和 悲观(pessimistic)锁来实现;各数据库中MVCC实现并不统⼀。

索引
MySQL底层索引数据结构是B+树
B+树与B树区别:

  • B 树中每个节点同时存储 key 和 data,而 B+ 树中只有叶子节点才存储 data,非叶子节点只存储 key。
  • InnoDB 对 B+ 树进行了优化,在每个叶子节点上增加了一个指向相邻叶子节点的链表指针,形成了带有顺序指针的 B+树,提高区间访问的性能。

B+ 树的优点在于:

  • 由于 B+ 树在非叶子节点上不含数据信息,因此在内存页中能够存放更多的key,数据存放得更加紧密,具有更好的空间利用率,访问叶子节点上关联的数据也具有更好的缓存命中率。
  • B+树的叶子结点都是相连的,因此对整棵树的遍历只需要一次线性遍历叶子节点即可。而 B树则需要进行每一层的递归遍历,相邻的元素可能在内存中不相邻,所以缓存命中性没有 B+树好。但是 B 树也有优点,由于每个节点都包含 key和 value,因此经常访问的元素可能离根节点更近,访问也更迅速。

主键索引和非主键索引的区别是:非主键索引的叶子节点存放的是主键的值,而主键索引的叶子节点存放的是整行数据,其中非主键索引也被称为二级索引,而主键索引也被称为聚簇索引。
1、如果查询语句是 select * from table where ID = 100,即主键查询的方式,则只需要搜索 ID 这棵 B+树。
2、如果查询语句是 select * from table where k = 1,即非主键的查询方式,则先搜索k索引树,得到ID=100,再到ID索引树搜索一次,这个过程也被称为回表。

如果索引包含所有满足查询需要的数据的索引成为覆盖索引(Covering Index),也就是平时所说的不需要回表操作。简单的说,覆盖索引覆盖所有需要查询的字段(即,大于或等于所查询的字段)。MySQL可以通过索引获取查询数据,因而不需要读取数据行。

索引失效的情况

  • 如果索引列出现了隐式类型转换,则 MySQL 不会使用索引。常见的情况是在 SQL 的 WHERE条件中字段类型为字符串,其值为数值,如果没有加引号那么 MySQL 不会使用索引。
  • 如果 WHERE 条件中含有 OR,除非 OR 前使用了索引列而 OR 之后是非索引列,索引会失效。
  • MySQL 不能在索引中执行 LIKE 操作,这是底层存储引擎 API 的限制,最左匹配的 LIKE比较会被转换为简单的比较操作,但如果是以通配符开头的 LIKE 查询,存储引擎就无法做比较。这种情况下MySQL只能提取数据行的值而不是索引值来做比较。
  • 如果查询中的列不是独立的,则 MySQL 不会使用索引。独立的列是指索引列不能是表达式的一部分,也不能是函数的参数。
  • 对于多个范围条件查询,MySQL 无法使用第一个范围列后面的其他索引列,对于多个等值查询则没有这种限制。
  • 如果 MySQL 判断全表扫描比使用索引查询更快,则不会使用索引。
  • 索引文件具有 B-Tree 的最左前缀匹配特性,如果左边的值未确定,那么无法使用此索引。

优化
explain字段:
在这里插入图片描述

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值