前言

最近突发新型肺炎,本来只有七天的春节假期也因为各种封锁延长到了正月十五,在家实在闲的蛋疼便重新研究了一下Mysql数据库的相关知识,特此总结梳理一下。本文主要围绕以下几点进行:

1、Mysql的索引与引擎

2、事务隔离级别

3、Mysql的九种锁

4、几点常用规范

一、Mysql的索引与引擎

Mysql最常用的引擎是InnoDB,但还有很多种其他类型的引擎,平时最常用来与它进行比对的是MyISAM。

1、 Mysql是采用B+树作为索引存放的数据结构。B+树结构如下图所示。为什么采用这种类型呢?

因为: M阶的B+树高度不高就能存储大量数据;根据局部性原理,B+树能充分利用磁盘预读,一个叶子节点块存放磁盘读一次的容量;叶子节点用双向链表连接,极大提高了范围查找的速度。

2、Mysql数据库的索引分为两种:主键索引、普通索引 InnoDB的是聚集索引(Clustered Index),MyISAM是非聚集索引(UnClustered Index)

非聚集索引:索引与行记录分开存储。叶子节点存储数据行的地址,定位到叶子节点后再根据地址去找到具体的数据。在非聚集索引下,主键索引和普通索引的实现是一致的,都是非叶子节点存储索引列,叶子节点存储索引列和数据的指针。所以此种情况下可以没有主键索引。

非聚集索引示意图

聚集索引:主键索引与行记录存储在一起,普通索引与主键索引存储在一起。所以InnoDB的主键索引很快,但普通索引走完普通索引的B+树获取到主键索引后还要走一遍主键索引的B+树才能获取到最终的行记录。

所以聚集索引只能有一个且必须要有主键,如果用户未定义主键,则InnoDB会已第一个非空的唯一列作为聚集索引,还不行就会自己创建一个row-id。

二、Mysql的七种锁

1、自增锁

如果表字段中设置了AUTO_INCRUMENT,为保证同一个事务插入数据的递增,在插入时会触发自增锁,阻塞其他事务的插入,它是一种特殊的表级别锁。另外可以通过innodb_autoinc_lock_mode来修改配置。

2、插入意向锁(Insert intention locks)

如果插入的表中没有自增字段,则会使用插入意向锁(间隙锁的一种),即锁定要插入的索引,只要多个事物并发插入时位置不冲突就不会阻塞。

3、意向锁(Intention Locks)

InnoDB允许行级锁与表级锁共存,使用的就是意向锁。意向锁是一个表级别的锁。select * from table where id = 2 lock in share mode; 设置意向共享锁;select * from  table where id = 2 for update; 设置意向排他锁。

意向锁协议:事物要获取某些行的共享锁,需先获取意向共享锁;要获取排他锁,需先获取意向排他锁。

意向锁的共享排他锁之间不互斥,但与普通共享排他锁互斥(只有意向共享锁与普通共享锁可并行)

4、共享/排他锁(Shared and exclusive Locks)

InnoDB中共享/排他锁是标准的行级锁,互斥关系与普通的读写锁一致。

5、记录锁(Record Locks)

锁定指定的索引记录,如select * from table where id = 1 for update;就是记录锁,锁定id=1的这条索引记录

6、间隙锁(Gap Locks)

锁定索引区间,如select * from table where id between 1 and 9 for update;执行后,如果插入id=8的数据会失败。主要目的是防止写导致不可重复读,所以间隙锁也只有在隔离级别是可重复读时生效。

7、临键锁(Next-Key Locks)

可以看成记录锁与间隙锁的组合。它非锁定范围即包含索引记录也包含索引区间。临键锁也是只有在可重复读隔离级别下生效。

三、事务隔离级别

Mysql数据库有四种事务隔离级别(Oracle也是):读未提交(Read Uncommitted)、读提交(Read Committed)、可重复读(Repeated Read)、串行化(Serializable)。Mysql默认是可重复读,但一般都会改成读提交。下面针对读提交和可重复读来看看InnoDB是如何实现的。

1、首先说明一下快照读,Mysql中不带锁普通的sql语句(如select * from table where id < 2)是快照读。普通的读写锁在进行写的时候,读会被堵塞,而mysql针对此情况采用数据多版本,使得在写的时候普通读也不会阻塞。mysql在回滚段(rollback segment)中存放了undo日志,用于记录被事务操作之前事务未提交时数据的old version。这样普通读只要读老版本的数据即可。 此外还有一个redo日志,用于存放事务提交之后的数据。因为每次提交事务后都去刷磁盘,随即写效率低,所以mysql利用类似于缓存的redo日志来临时存放数据,统一往磁盘顺序写,提高吞吐量。

2、在读提交下,select /update/delete *** for update; 采用的是记录锁,即不会锁区间,只是锁匹配到的记录。如果有并发插入会导致幻读。

 3、在可重复读下,select /update/delete *** for update;如果是在唯一索引上使用唯一的查询条件,会使用记录锁,不会锁区间;而如果是范围查询,则使用间隙锁或临键锁,锁住索引记录之间的范围。在此隔离级别下,快照读在事物中第一次调用时mysql会记录一个副本,后续再有读只是从这个副本中读,不会读到之后其他事物提交的改动。

可以看到,InnoDB使用间隙锁和临键锁来避免可重复读下的幻读现象。

四、几个常用规范

1、InnoDB主键不要长了,因为每个普通索引都会存放一遍主键;InnoDB主键必须要设置,并且最好是UNSIGNED整型递增的,这样在插入行时就不会出现大量索引分裂导致数据行换位置;(参见一、2)。

2、必须把字段定义为NOT NULL并设置默认值。

3、where条件禁止用隐性类型转换、函数操作索引行,注意like的最左前缀

Mysql梳理-关于索引/引擎与锁的更多相关文章

  1. MySQL数据库InnoDB存储引擎中的锁机制

    MySQL数据库InnoDB存储引擎中的锁机制    http://www.uml.org.cn/sjjm/201205302.asp   00 – 基本概念 当并发事务同时访问一个资源的时候,有可能 ...

  2. (转)MySQL优化笔记(八)--锁机制超详细解析(锁分类、事务并发、引擎并发控制)

    当一个系统访问量上来的时候,不只是数据库性能瓶颈问题了,数据库数据安全也会浮现,这时候合理使用数据库锁机制就显得异常重要了. 原文:http://www.jianshu.com/p/163c96983 ...

  3. mysql中InnoDB存储引擎的行锁和表锁

    Mysql的InnoDB存储引擎支持事务,默认是行锁.因为这个特性,所以数据库支持高并发,但是如果InnoDB更新数据的时候不是行锁,而是表锁的话,那么其并发性会大打折扣,而且也可能导致你的程序出错. ...

  4. 重新学习MySQL数据库7:详解MyIsam与InnoDB引擎的锁实现

    重新学习Mysql数据库7:详解MyIsam与InnoDB引擎的锁实现 说到锁机制之前,先来看看Mysql的存储引擎,毕竟不同的引擎的锁机制也随着不同. 三类常见引擎: MyIsam :不支持事务,不 ...

  5. Mysql存储引擎以及锁机制

    一.常用命令 1.查看引擎(默认为InnoDB) 查看mysql提供的存储引擎:show engienes 查看mysql当前默认的存储引擎:show variables like '%storage ...

  6. 【转】MySql 三大知识点——索引、锁、事务

    索引 索引,类似书籍的目录,可以根据目录的某个页码立即找到对应的内容. 索引的优点:1. 天生排序.2. 快速查找. 索引的缺点:1. 占用空间.2. 降低更新表的速度. 注意点:小表使用全表扫描更快 ...

  7. 一步一步带你入门MySQL中的索引和锁 (转)

    出处: 一步一步带你入门MySQL中的索引和锁 索引 索引常见的几种类型 索引常见的类型有哈希索引,有序数组索引,二叉树索引,跳表等等.本文主要探讨 MySQL 的默认存储引擎 InnoDB 的索引结 ...

  8. mysql的innodb 引擎 表锁与行锁

    innodb 引擎 行锁与表锁 行锁与表锁是基于索引来说的(且索引要生效) 不带索引 (表锁)要全表扫描 1. 执行select @@autocommit; 查看结果 0是不自动提交事务,1是自动提交 ...

  9. mysql基础(三)存储引擎和锁

    存储引擎的概念: 关系型数据库表是用于存储和组织信息的数据结构,可以将表理解为由行和列组成的表格,各种各样,不同的表结构意味着存储不同类型的数据,在数据的处理上也会存在着差异,对于mysql来说,它提 ...

随机推荐

  1. git push报错大文件,删除后重新commit依然报错

    git push报错: github不能上传大文件,按道理删掉重新提交就行了 可是删掉后,git add -A,再git commit,再git push,依然报错 后来我想明白了 github上传时 ...

  2. Hadoop Authentication

    我被被派去做别的事情了,所以与hadoop相关的工作就只能搁下.写篇总结,把最近遇到的和kerberos相关的东西列一下. JAAS是Java 认证和授权服务(Java Authentication ...

  3. 第三阶段:3.Web端产品设计:1.以用户为中心的产品设计2

    从功能到体验.提供不同的附加值.

  4. $CF1063B\ Labyrinth$ $01$最短路/$01BFS$

    \(Des\) 有一个网格图,上面的格子分为空地和障碍,障碍是不可以走的.现在从给定的起点出发开始到处乱走,最多可以往左走\(l\)次,往右走\(r\)次.求可能到达的点数. \(Sol\) 如果只限 ...

  5. 使用Django进行后端开发

    目录 更换pip源 搭建虚拟环境 项目目录设置 项目相关配置 更换pip源 更换pip源 搭建虚拟环境 搭建虚拟开发环境 项目目录设置 项目目录设置 项目相关配置 项目相关配置

  6. Exceptionless运用结果

    一.后台页面功能 列表菜单 SubmitLog - 记录一般日志 log Messages SubmitException - 记录一次日志 Exceptions SubmitNotFound - 4 ...

  7. 这份前端面试小册子dog cheng带来啦~

    写在前面 没有错,就是我啦dog cheng,好久不见,从17年在博客园写下第一篇文章,转身间已然两年,从大二到现在的大四预备毕业生,我仍然在这条道路上前进.秋招早已经结束,在拿到用友,滴滴的offe ...

  8. AcWing 220. 最大公约数 | 欧拉函数

    传送门 题目描述 给定整数N,求1<=x,y<=N且GCD(x,y)为素数的数对(x,y)有多少对. GCD(x,y)即求x,y的最大公约数. 输入格式 输入一个整数N 输出格式 输出一个 ...

  9. 探究Dubbo的拓展机制: 下

    承接上篇, 本篇博文的主题就是认认真真捋一捋, 看一下 Dubbo是如何实现他的IOC / AOP / 以及Dubbo SPI这个拓展点的 总览: 本篇的话总体上分成两部分进行展开 第一点就是 Dub ...

  10. EntityFramework Core表名原理解析,让我来,揭开你神秘的面纱

    前言 上一节我们针对最开始抛出的异常只是进行了浅尝辄止的解析,是不是有点意犹未尽的感觉,是的,我也有这种感觉,看到这里相信您和我会有一些疑惑,要是我们接下来通过注解.Fluent APi.DbSet分 ...