MySQL

基本架构

类似一个后端的服务器,数据库会事先开好线程并缓存这些线程,一条语句过来,数据库就会开启一个线程去处理,先去查询缓存中找,解析器中也会有相应的缓存,解析优化完后就通过 API 请求存储引擎

并发控制

读写锁

  1. 共享锁
  2. 排他锁
  3. 读锁
  4. 写锁

表锁,行级锁

事务

对于不需要事务的查询类应用,选择非事务型的存储引擎可以获得更高的性能

隔离级别

脏读:事务中的修改即使没有提交也对其他事务可见可读

可重复读

该级别保证同一事务中多次读取同样记录的结果是一致的

死锁

两个或多个事务在同一资源上相互占用 解决方式:设置锁等待超时,将持有最少行级排他锁的事务进行回滚

AUTOCOMMIT

默认采用自动提交,每个查询都被当做一个事务执行提交操作

存储引擎

MyISAM 存储引擎

5.1 版本以前,是默认的存储引擎,但是不支持事务和行级锁,崩溃后无法安全恢复 使用表锁,对性能影响很大 不修改的表可以使用压缩表极大节省磁盘空间 将表分别存储在数据文件和索引文件中 只读或者大部分只读的表可以使用这个存储引擎

InnoDB

使用文件系统的目录和文件保存数据库和表的定义 使用聚簇索引,对查询主键有很高的性能 从磁盘读取使用可预测性预读 加速读操作的自适应哈希索引

InnoDB VS MyISAM

两种类型最主要的差别就是 Innodb 支持事务处理与外键和行级锁

范式与反范式

范式化的数据库中,每个事实数据只会出现一次,无冗余 反范式的数据库中,信息是冗余的

使用范式的优点:

  1. 更新操作快,修改只需要修改少量数据
  2. 表通常更小,可以放在内存里
  3. 更少需要 DISTINCT 或 GROUP BY 语句 缺点:需要联表,可能使一些索引无效

反范式的优点:不需要关联表,避免了随机IO,即便是最坏情况需要全表扫描,也基本上是顺序IO 缺点:修改麻烦,数据冗余

混用范式与反范式

复制和缓存就是反范式的一个应用,使用触发器更新缓存值 缓存表和汇总表做一些定时统计也比实时的查询要好,但必须选择进行实时重建或者定期重建

主表使用 InnoDB ,用 MyISAM 做缓存只读表节约空间 建立额外索引,增加冗余列

计数器表

更新计数器可能会出现并发问题,因此可以使用 rand 进行随机写加快并发更新的速度,读的时候 SUM 一下即可

索引

好处:

  1. 减少扫描数据量
  2. 避免排序和临时表
  3. 将随机IO变为顺序IO 如果使用某个索引进行范围排序,也就无法再使用另一个索引进行排序

快速创建索引

其中一个技巧是先禁用索引,载入数据,再启用 不能禁用的话删除索引也是一样的

B-Tree 索引

值和指针存储在一起 如果索引包含多个列,列的顺序非常重要,MySQL只能高效地使用索引的最左前缀列 现在大部分的引擎使用的都是 B+树索引

B+树索引

InnoDB 使用 B+树索引 与B树的不同点:非叶子节点只存储值,叶子节点存储值和行指针,这样降低了节点的大小,单个页可以存放更多的节点,意味着更少的磁盘IO;叶子节点像链表一样串在一起,方便范围查询;删除操作更简单;快速下沉找值

限制:

  1. 不是从最左列开始,则无法使用索引
  2. 不能跳过索引中的列
  3. 有某个列的范围查询,则其右边的所有列都无法使用索引优化查找

聚簇索引

是一种数据的存储方式,InnoDB使用。数据行的所有字段实际存储在叶子页中,数据行和相邻键值放在一起,是索引列为主键的 B+树,这使得数据的访问更快 数据分布:索引即为整个表

MyISAM 数据分布

使用B+树索引,使用主键列值做索引,叶子节点存储行指针(即物理地址),然后将索引进行前缀压缩,让更多的索引能够放入内存中

哈希索引

只有 memory 引擎支持,会对所有索引列计算哈希值,哈希值为行指针 缺点:无法用于排序,查询必须使用所有的索引列才能使用索引,只支持等值比较 长字符串索引可以转而使用CRC32做索引列,使用触发器进行更新维护,查询效率极高

自适应哈希索引: InnoDB中有的一种索引,当引擎注意到某些索引值被使用得非常频繁的时候,它会在内存中基于 B-tree 索引之上再创建一个哈希索引,使用哈希值而不是键值在B-tree中查找