RDBMS | 青训营笔记

112 阅读4分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 9 天

RDBMS 关系型数据库

事务Transaction:一组SQL语句组成的一个程序执行单元,需要满足ACID特性

  • 原子性Atomicity:事务中的操作要么都发生,要么都不发生
  • 一致性Consistency:事务不能破坏关系数据的完整性以及业务逻辑的一致性(状态必须合法)
  • 隔离性Isolation:一个事务不能影响其他事务
  • 持久性Durability:事务完成后,该事务对数据库的更改持久地保存在数据库中,不会因为宕机等问题丢失

高并发、高可靠、高可用

关系模型 所有的数据都是一张二维表(无论是实体,还是实体的联系)
每一行数据代表一个实体或者一个关系

一个关系型数据库系统的关键:

  • SQL引擎:解决SQL执行问题
  • 存储引擎:解决存储问题
  • 事务引擎:解决事务ACID问题

SQL引擎

解析器Parser —— 词法分析、语法分析、语义分析

优化器Optimizer —— 基于规则的优化 / 基于代价的优化

为查询生成性能最优的执行计划

执行器Executor

将执行计划翻译成可执行的物理计划并驱动它执行
拆分成不同算子,一面对用户千变万化的SQL

  • 火山模型:每个Operator调用Next操作,访问下一层Operator,获得下层Operator返回的一行数据,计算处理后返回给上层
    优点:每个算子独立抽象实现,相互之间没有耦合,逻辑结构简单
    缺点:每计算一条数据有多次函数调用开销(CPU效率不高)
  • 向量化:每次一批数据(Batch N 行)  函数调用次数1/N;CPU cache命中率更高;可以利用CPU的SIMD(single Instruction Multi Data)机制
  • 编译执行:动态编译技术 编译成一个执行函数

存储引擎

如何存储数据?(是否可并发处理、是否可构建索引、行存列存或行列混合)
如何读写数据?(使用场景:读多写少 / 写多读少、点查场景、分析型场景)

  • 管理内存数据结构
    • 索引
    • 内存数据
    • 缓存(Query cache、Data cache、Index cache)
  • 管理磁盘数据(磁盘数据的文件格式 & 增删改查)
  • 封装读写算子(写入 / 读取逻辑)

In Memory 部分

Buffer Pool:数据缓存
把整个BufferPool分成各个Instance 降低页面访问的冲突 通过HashMap定位block
LRU算法实现淘汰机制

Log Buffer:用于写日志

On Disk 部分

系统表 存储元信息(描述数据库中的表和用户)
普通的表 存数据
Undo表

B+树构建索引
页面内页目录先通过二分法定位到对应槽,然后遍历该槽的分组中的记录找到指定记录
节点间双向链表连接以适合范围查询
一张数据表一般对应一颗或多颗树的存储,树的数量与建索引的数量有关,每个索引都会有一颗单独的树

聚簇索引和非聚簇索引: 主键索引也是聚簇索引,非主键索引都是非聚簇索引。除格式信息外,两种索引的非叶子节点都是只存索引数据的,比如索引为id,那非叶子节点就是存的id数据。 叶子节点的区别如下:

  • 聚簇索引的叶子节点一般情况下存的是这条数据的所有字段信息。所以我们 select * from table where id = 1 的时候,都是要去叶子节点拿数据的。
  • 非聚簇索引的叶子节点存的是这条数据所对应的主键和索引列信息。比如这条非聚簇索引是username,然后表的主键是id,那该非聚簇索引的叶子节点存的就是 username 和 id,而不存其他字段。

相当于是先从非聚簇索引查到主键的值,再根据主键索引去查数据内容,一般情况下要查两次(除非索引覆盖),这也称之为回表 ,就有点类似于存了个指针,指向了数据存放的真实地址。

B+树的查询是从上往下一层层查询的,一般情况下我们认为B+树的高度保持在3层以内是比较好的,也就是上两层是索引,最后一层存数据,这样查表的时候只需要进行3次磁盘IO就可以了(实际上会少一次,因为根节点会常驻内存),且能够存放的数据量也比较可观

在Innodb的B+树中,我们常说的节点被称之为 页(page)。 是InnoDB存储引擎管理数据库的最小磁盘单位,我们常说每个节点16KB,其实就是指每页的大小为16KB。每个页当中存储了用户数据,所有的页合在一起组成了一颗B+树


若有联合索引(A,B) 查询条件中如果没有A的支持,B的索引是散列的、不是连续的,不会走索引