Java必备——MySql 三大知识点——索引、锁、事务

而这个特点会导致非页子节点不能存储大量的索引。

而 B+ Tree 就是针对这个对 B tree 做了优化。如下图所示:

我们看到,B+ Tree 将所有的 data 数据都保存到了叶子节点中,非也子节点只保存索引和指针。

我们假设一个非页子节点是 16kb,每个索引,即主键是 bigint,即 8b,指针为 8b。那么每页能存储大约 1000 个索引(16kb/ 8b + 8b).

而一颗 3 层的 B+树能够存储多少索引呢?如下图:

大约能够存储 10 亿个索引。通常 B+ 树的高度在 2-4 层,由于 MySql 在运行时,根节点是常驻内存的,因此每次查找只需要大约 2 -3 次 IO。可以说,B+ 树的设计,就是根据机械磁盘的特性来进行设计的。

知道了索引的设计,我们能够知道另外一些信息:

  1. MySql 的主键不能太大,如果使用 UUID 这种,将会浪费 B+ 树的非叶子节点。

  2. MySql 的主键最好是自增的,如果使用 UUID 这种,每次插入都会调整 B+树,从而导致页分裂,严重影响性能。

那么,如果项目中使用了分库分表,我们通常都会需要一个主键进行 sharding,那怎么办呢?在实现上,我们可以保留自增主键,而逻辑主键用来作为唯一索引即可。

2. 锁机制

关于 Mysql 的锁,各种概念就会喷涌而出,事实上,锁有好几种维度,我们来解释一下。

1. 类型维度
  • 共享锁(读锁 / S 锁)

  • 排它锁(写锁 / X 锁)

类型细分:

  • 意向共享锁

  • 意向排他(互斥)锁

  • 悲观锁(使用锁,即 for update)

  • 乐观锁(使用版本号字段,类似 CAS 机制,即用户自己控制。缺点:并发很高的时候,多了很多无用的重试)

2. 锁的粒度(粒度维度)
  • 表锁

  • 页锁(Mysql BerkeleyDB 引擎)

  • 行锁(InnoDB)

3. 锁的算法(算法维度)
  • Record Lock(单行记录)

  • Gap Lock(间隙锁,锁定一个范围,但不包含锁定记录)

  • Next-Key Lock(Record Lock + Gap Lock,锁定一个范围,并且锁定记录本身, MySql 防止幻读,就是使用此锁实现)

4. 默认的读操作,上锁吗?
  • 默认是 MVCC 机制(“一致性非锁定读”)保证 RR 级别的隔离正确性,是不上锁的。

可以选择手动上锁:select xxxx for update (排他锁); select xxxx lock in share mode(共享锁),称之为“一致性锁定读”。

使用锁之后,就能在 RR 级别下,避免幻读。当然,默认的 MVCC 读,也能避免幻读。

既然 RR 能够防止幻读,那么,SERIALIZABLE 有啥用呢?

防止丢失更新。例如下图:

这个时候,我们必须使用 SERIALIZABLE 级别进行串行读取。

最后,行锁的实现原理就是锁住聚集索引,如果你查询的时候,没有正确地击中索引,MySql 优化器将会抛弃行锁,使用表锁。

3. 事务

事务是数据库永恒不变的话题, ACID:原子性,一致性,隔离性,持久性。

四个特性,最重要的就是一致性。而一致性由原子性,隔离性,持久性来保证。

  • 原子性由 Undo log 保证。Undo Log 会保存每次变更之前的记录,从而在发生错误时进行回滚。

  • 隔离性由 MVCC 和 Lock 保证。这个后面说。

  • 持久性由 Redo Log 保证。每次真正修改数据之前,都会将记录写到 Redo Log 中,只有 Redo Log 写入成功,才会真正的写入到 B+ 树中,如果提交之前断电,就可以通过 Redo Log 恢复记录。

然后再说隔离性。

隔离级别:

  1. 未提交读(RU)

  2. 已提交读(RC)

  3. 可重复读(RR)

  4. 串行化(serializable)

每个级别都会解决不同的问题,通常是3 个问题:脏读,不可重复读,幻读。一张经典的图:

这里有个注意点,关于幻读,在数据库规范里,RR 级别会导致幻读,但是,由于 Mysql 的优化,MySql 的 RR 级别不会导致幻读:在使用默认的 select 时,MySql 使用 MVCC 机制保证不会幻读;你也可以使用锁,在使用锁时,例如 for update(X 锁),lock in share mode(S 锁),MySql 会使用 Next-Key Lock 来保证不会发生幻读。前者称为快照读,后者称为当前读。

原理剖析:

  • RU 发生脏读的原因:RU 原理是对每个更新语句的行记录进行加锁,而不是对整个事务进行加锁,所以会发生脏读。而 RC 和 RR 会对整个事务加锁。

  • RC 不能重复读的原因:RC 每次执行 SQL 语句都会生成一个新的 Read View,每次读到的都是不同的。而 RR 的事务从始至终都是使用同一个 Read View。

  • RR 不会发生幻读的原因: 上面说过了。

那 RR 和 Serializble 有什么区别呢?答:丢失更新。本文关于锁的部分已经提到。

MVCC 介绍:全称多版本并发控制。

innoDB 每个聚集索引都有 4 个隐藏字段,分别是主键(RowID),最近更改的事务 ID(MVCC 核心),Undo Log 的指针(隔离核心),索引删除标记(当删除时,不会立即删除,而是打标记,然后异步删除);

本质上,MVCC 就是用 Undo Log 链表实现。

125分50秒---162.81M---LabView01---第10章数据的显示.wmv---F:/Resource/video/硬件/AltiumDesigner/LabView01-第10章数据的显示.wmv 92分2秒---143.46M---LabView02---第11章文件的IO及保存.wmv---F:/Resource/video/硬件/AltiumDesigner/LabView02-第11章文件的IO及保存.wmv 37分22秒---58.09M---LabView03---第12章LabVIEW的通信.wmv---F:/Resource/video/硬件/AltiumDesigner/LabView03-第12章LabVIEW的通信.wmv 9分58秒---21.2M---LabView04---第13章LabVIEW与其它软件的连接.wmv---F:/Resource/video/硬件/AltiumDesigner/LabView04-第13章LabVIEW与其它软件的连接.wmv 4分45秒---9.99M---LabView05---第14章LabVIEW中子VI的设置及调用.wmv---F:/Resource/video/硬件/AltiumDesigner/LabView05-第14章LabVIEW中子VI的设置及调用.wmv 34分30秒---61.03M---LabView06---第15章其它高级技巧.wmv---F:/Resource/video/硬件/AltiumDesigner/LabView06-第15章其它高级技巧.wmv 9分41秒---11.37M---LabView07---第2章第一个LabVIEW例子.wmv---F:/Resource/video/硬件/AltiumDesigner/LabView07-第2章第一个LabVIEW例子.wmv 86分58秒---140.25M---LabView08---第3章基本元素.wmv---F:/Resource/video/硬件/AltiumDesigner/LabView08-第3章基本元素.wmv 76分48秒---143.72M---LabView09---第4章程序结构.wmv---F:/Resource/video/硬件/AltiumDesigner/LabView09-第4章程序结构.wmv 5分46秒---14.67M---LabView10---第5章数据采集.wmv---F:/Resource/video/硬件/AltiumDesigner/LabView10-第5章数据采集.wmv 12分50秒---18.35M---LabView11---第6章数据传输及电脑接口.wmv---F:/Resource/video/硬件/AltiumDesigner/LabView11-第6章数据传输及电脑接口.wmv 59分57秒---87.83M---LabView12---第7章数据的分析及处理.wmv---F:/Resource/video/硬件/AltiumDesigner/LabView12-第7章数据的分析及处理.wmv 42分4秒---61.02M---LabView13---第8章LabVIEW的信号调理.wmv---F:/Resource/video/硬件/AltiumDesigner/LabView13-第8章LabVIEW的信号调理.wmv 132分19秒---178.86M---LabView14---第9章分析处理中数学计算.wmv---F:/Resource/video/硬件/AltiumDesigner/LabView14-第9章分析处理中数学计算.wmv
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值