MYSQL LEARN

MYSQL 突击复习

事物隔离级别

  • 脏读:A事物读取数据的时候,B事物正好修改了但还未提交,A读取到的是B修改完未提交的数据

  • 不可重复读:A事物读取的时候,第一遍读取一行数据结果是1,此时B事物修改了该行为2,第二次读取到的和第一次的不一样

  • 幻读:A事物读取的时候,第一遍读取数据是10行,此时B事物添加了一行,第二次读取到的是11行 出现冲突 多了一行数据

注意:幻读只指定新增 删除的情况也是不可重复读

隔离级别 脏读 不可重复度 幻读 解决技术
Read Uncommitted(读未提交) x x x 最初级
Read Committed(读已提交) o x x MVCC(每次read快照)
Repeatable Read(可重复读) o o x MVCC(每次read快照)+间隙锁
Serialized(序列化) o o o 全表加锁

MVCC 多版本控制

结构特点

  • hidden fields:每一行数据都有俩个隐藏字段 一个是最近修改的事物id 一个是指向上一次变更的undolog记录表的指针ptr
  • readview
  • m_ids:正在活跃的事物
  • min_id:正在活跃的最小事物
  • max_id:系统将派发的下一个事物
  • undolog:存数据 存链式指向

判断逻辑

比如说有一个事物100 他要进行读操作 这时候创建一个read_view 里面m_ids[]=[99,101],此时max_id=102,min_id=99

  • 当读到的数据的隐藏字段是95的时候 既比100小又不在m_ids里可以直接看数据
  • 当读到的数据的隐藏字段是99,101的时候 不能看 去翻undolog
  • 当读到的数据的隐藏字段是102的时候 不能看 去翻undolog
  • 当读到的数据的隐藏字段是100的时候 能看 自己改的自己可以看
  • 还有一种 比99大 比102小 而且不在黑名单里 比如说有个100.5 虽然比我们大 但提交完了 是可以看的

不同级别

RR:只会复用第一次的readview

RC:每次都创建readview

重点在黑名单的变化 比如 RC 新创建的readview里黑名单里有一个提交了就能看了 而RR还是之前的

索引

MYSQL逻辑层面的最小单位就是页

  1. 每一张“纸”(页)的内部结构

每一页(无论存的是数据还是目录)都包含以下几个固定区域:

  • 文件头 (File Header):存上一页/下一页指针(双向链表)。
  • 页头 (Page Header):存这一页的状态(存了多少行、水位线等)。
  • 记录区 (User Records):真正存内容的地方。
  • 页目录 (Page Directory):页内查找的“小索引”。
  • 文件尾 (File Trailer):校验数据完整性。
  1. 角色分工

虽然物理结构一样,但根据 “记录区” 存的东西不同,页分成了两类:

  • 数据页(叶子节点):记录区里存的是:[主键 ID + 整行数据]。
  • 目录页(非叶子节点):记录区里存的是:[子页的最小主键 ID + 子页的页号]。

索引知识

  1. 为啥需要索引?

    • 单页查找:可以直接通过页结构的页目录 二分查找 速度很快
    • 多页查找:数据多了,页多了,如果没有索引,就只能一个个页沿着页头的双向链表从头开始找,几百万的时候性能差劲
  2. 索引的本质

为了快,MYSQL专门拿出一类特殊的页,专门记录“哪个主键在哪个页”。这就是目录页(也叫索引页/非叶子节点)

- 内容:只有俩个字段:[页中最小的主键ID] [对应的页号]
- 逻辑:如果先找id为500的数据,先看目录页,发现500在第10页,直接跳过去,不用翻前面的9页
  1. B+树的诞生

    当目录页也变多了怎么办?那就给目录页再做一个目录。

    • 最底层(叶子节点):就是你说的数据页,存的是真实数据。
    • 上层(非叶子节点):就是目录页。
    • 最顶层(根节点):索引的入口,永远常驻内存。

    这就形成了一个倒过来的树(B+ Tree):

    1. 从根节点出发,根据 ID 大小判断去哪个目录页。
    2. 在目录页里继续判断,找到最终的数据页。
    3. 进入数据页,用页内二分法找到那一行。

    为啥不是B树

    • 因为B树所有节点都要存数据 效率慢
  2. 两个关键概念:

    • 聚簇索引(Clustered Index):数据和索引是一体的。B+ 树的叶子节点直接就是原始数据页。InnoDB 必须有且只有一个聚簇索引(通常是主键)。
    • 二级索引 / 辅助索引(Secondary Index):比如你给 name 列建索引。它的叶子节点存的不是整行数据,而是 [name 的值 + 对应的主键 ID]。

索引类型

B+树索引和哈希索引 全文索引

哈希相当于hashmap 一次定位
B+树索引支持范围类型