第一章 MySQL的架构与历史

1.2 并发控制

首先我们要了解什么是并发?什么时候会出现并发问题?简单的说,当不同的DML同时要修改同一条记录的时候,就会造成并发问题。
这里用一个例子来说明什么是并发问题。 Unix 中的Email 中的所有邮件都是串行的在一起的,并利用定义好的分隔符来区分不同的邮件。当有新邮件时,新邮件就会自动贴在上一封邮件之后。
这里存在的并发问题就是:如果同一时刻发送了2篇及以上的邮件过来,那么邮件就会发生接收的乱码从而破坏邮件。此时就必须要引入必要的并发控制,比如当有一封邮件在传输时要锁定接收(一封收完了才能收下一封)。这种锁我们可以理解为MySQL中阻塞锁,拥有很高的安全性,但是当大量邮件同时来时会出现阻塞。
1.2.1 读写锁
在实际的环境中会出现多个客户端同时读取某一条数据,这是可行的,因为读取数据不会对数据安全造成影响。但是如果在A客户端读取某一条数据时,B客户端正在修改这条数据,甚至删除这条数据呢?此时出现的情况就会有很多不同(涉及到具体数据库的隔离级别)。
为了避免这种情况的发生,数据库引入了锁机制来实现并发控制。分别是读锁(shared lock)和写锁(exclusive lock)。顾名思义读锁是共享的,不会被阻塞的;写锁是排他的,为了数据安全是排他的。
1.2.2 锁的粒度
对于不同的系统,在设计之初我们要评估要采取何种锁的策略来达成一个安全高效的系统健壮度。因为加锁是需要消耗资源的。在系统的使用中,获取,查看锁是否被占用,释放锁都是需要消耗资源。
决策锁的粒度,如这个表采用表锁还是行锁这个在系统设置时就需要考虑到。MySQL中有现成的存储引擎实现了一些默认的锁粒度控制。如InnoDB,MyIsam等等。这里介绍2种最常见的锁策略。
表锁:
顾名思义,表锁就是当有线程在操作该表时,其他线程对该表处于阻塞状态。这种实现对系统开销最小,但是不适用于高吞吐的系统。
行锁:
这是一个对数据库资源细粒度并发控制的实现,我们仅对表中的一行被操作的记录加锁,从而最大化的减少系统的阻塞概率。这种实现对系统的开销较大,但是是当下最广泛引用的实现。

1.3 事务

在sql中,事务被定义为一组不可分割的sql语句。即要么当前事务全部执行,要么全部不执行。(当在执行中因为某种原因引起的执行失败,数据库会进行事务回滚来保证数据的可靠性)。事务通常被四种属性所定义,也就是ACID。
1.3.4 MySQL中的事务
在MySQL中,如果没有显示的声明要开启一个事务,那么所有的语句都是自动提交的(commit),我们可以通过指令来查看当前数据库设置中的自动提交是否开启
show variables like 'autocommit'
MySQL中支持数据的存储引擎是Innodb

1.5 MySQL的存储引擎

第五章 索引

5.1 索引基础

当我们翻书的时候,如果没有目录我们总是要逐页的寻找,类似的,在一个没有索引的数据表中,总是要遍历的去查找我们想要的记录。
在MySQL中,索引的数据结构主要是BTREE。(决定数据结构的往往是不同的存储引擎),这里主要讨论InnoDb存储引擎。

5.2 B+Tree的数据结构

请注意:
1.所有的非叶子节点都不保存真实数据,而是维系了一个指针
2.所有的数据都保存在叶子节点上,被索引结构中的非叶子节点维系的指针指向
3.树的最大深度为3层
4.分页的大小为16KB

mysql 并发性能能支持qps mysql高并发写_存储引擎

5.2.1 查询的原理
之所以使用索引之后能够加快查询效率,是因为我们不再遍历的去真实数据中匹配目标记录,而是从索引结构中的根节点开始,去查找我们目的记录。首先从根节点开始去找到目的记录所在的页,再从页中去查找,如果查到了数据(存在)则从这个索引节点的指针定位到真实的数据记录并返回。
5.2.2辅助索引
什么是辅助索引呢?当我们在创建数据库表的时候,InnoDB引擎会默认是的使用主键索引来创建一个可使用索引树,这个索引树是一个聚簇索引(clustered)。如果我们要使用其他的列来构建索引,都被称为辅助索引。
5.2.3 辅助索引类型
  1. 普通索引:我们可以在某一列创建一个索引
  2. 唯一索引:如果这个列的值是唯一的,那么我们可以使用unique关键字来创建一个唯一索引
  3. 全文索引:
  4. 前缀索引:必须满足最左前缀原则

使用索引的说明限制:

  1. 如果不是按照索引的最左列开始查找,则无法使用索引。
  2. 不能跳过中间列进行索引,如果跳过,那么右侧的索引无法生效
  3. 如果某个列有范围查找,那么他右边的列都无法使用索引。
    总结: 当我们建立了一个索引,那么当使用时他的顺序非常重要。索引大大减少了服务与其需要扫描的数据量,帮助服务器避免排序和临时表。把随机I/O变为顺序I/O。
    索引的三星原则:
    索引把相关的记录放在一起获得一星;如果索引中的数据顺序和查找顺序一致则获得二星;如果索引中包含了查询中需要的全部列则获得三星;

5.3 高性能索引的策略

为了正确高效的使用索引,我们在建立索引是就要使用一定的策略。

5.3.1 独立的列

什么是独立的列?独立的列是指索引列不能是表达式的一部分,也不能是函数的参数。

select id from table where id + 1 = 5;

程序员可以看出,这个表达式等价于 id = 4,但是MySQL无法自动解析这个方程式。我们必须要简化where条件。让where能拿到一个值而不是表达式或者函数。

5.3.2 前缀索引和索引选择性