前言

最近突发新型肺炎,本来只有七天的春节假期也因为各种封锁延长到了正月十五,在家实在闲的蛋疼便重新研究了一下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. css3 移动端旋转动画暂停

    音乐播放图片旋转动画 ios不支持暂停: animation-play-state: paused; @-webkit-keyframes rotate{ 100% { transform: rota ...

  2. IdentityServer4 Clients

    原文地址 Clients 的定义 Client是指那些从 identityserver获取 token的应用 通常需要为client定义下面通用的设置 唯一的client id secret, 如果需 ...

  3. MySQL 命令行(转)

    1.登录mysql 本地:mysql -u root -p, 回车后输入密码; 也可以p后不加空格,直接加密码.回车就登录了 远程:mysql -hxx.xx.xx.xx -u -pxxx 2.查看数 ...

  4. Zookeeper面试总结,年后涨薪轻而易举

    此文不是入门教程,是需要一定的zookeeper基础的 zookeeper应用 同意命名服务 在分布式系统中,各个系统都有可能做为服务提供者,可以向外提供服务,这个时候就需要对服务的名字进行统一规划, ...

  5. 0006 列表(ul、ol、dl)

    1. 列表标签(重点) 学习目标 理解 无序列表的应用场景 自定义列表的应用场景 应用 无序列表语法 自定义列表语法 问? 前面我们知道表格一般用于数据展示的,但是网页中还是有很多跟表格类似的布局,如 ...

  6. 从零开始のcocos2dx生活(一)内存管理

    cocos中所有的对象都是继承自Ref基类,Ref的职责就是对对象进行引用计数管理 内存管理中最重要的是三个方法retain().release().autorelease() 在cocos中创建对象 ...

  7. 大白话抽象工厂模式(Abstract Factory Pattern)

    实例分析 大白话工厂方法模式(Factory Method)一文中,我们讲解了日产4S店工厂规模的扩大,创建了针对不同车型的工厂,减少了工厂的工作内容,提高了效率.下面我们继续以4S店的故事讨论抽象工 ...

  8. 小小知识点(四十七)——发送端已知CSI,基于注水算法的功率分配方法,实现功率受限下的信道容量最大化

    1. 注水算法的使用条件和推导 注水算法是根据某种准则,并根据信道状况对发送功率进行自适应分配,通常是信道状况好的时刻,多分配功率,信道差的时候,少分配功率,从而最大化传输速率.实现功率的“注水”分配 ...

  9. 腾讯自研万亿级消息中间件TubeMQ为什么要捐赠给Apache?

    导语 | 近日,云+社区技术沙龙“腾讯开源技术”圆满落幕.本次沙龙邀请了多位腾讯技术专家围绕腾讯开源与各位开发者进行探讨,深度揭秘了腾讯开源项目TencentOS tiny.TubeMQ.Kona J ...

  10. 图解 kubernetes scheduler 架构设计系列-初步了解

    资源调度基础 scheudler是kubernetes中的核心组件,负责为用户声明的pod资源选择合适的node,同时保证集群资源的最大化利用,这里先介绍下资源调度系统设计里面的一些基础概念 基础任务 ...