MySQL与TiDB基础知识类比

温故而知新 能够为师矣node

1、存储模型

MySQL

Each tablespace consists of database pages with a default size of 16KB. The pages are grouped into extents of size 1MB (64 consecutive pages). The “files” inside a tablespace are called segments in InnoDB. Two segments are allocated for each index in InnoDB. One is for nonleaf nodes of the B-tree, the other is for the leaf nodes. Keeping the leaf nodes contiguous on disk enables better sequential I/O operations, because these leaf nodes contain the actual table data.sql

  • 表空间Tablespace(ibd文件)
  • 段Segment(一个索引2个段)
  • 区Extent(1MB):64个Page
  • 页Page(16KB):磁盘管理的最小单位

从示意图能够清晰的了解到MySQL的行数据Row都是存储到数据页Page上,每一个数据页的大小为16KB。而后64个数据页进而组成一个区Extent,区又是段segment组成元素,一个索引拥有两个段,其中leaf node seagment存储着逻辑上的行数据(主键索引),非主键索引存储的是主键ID。数据库

InnoDB使用了B+树的索引模型。B+树为了维护索引的有序性,在插入新值的时候须要作必须的维护。若是在表尾插入,只需在记录后面增长,要是增长的行在表中间,就须要挪动位置给插入的行腾出空间。更糟糕的是带插入的数据页Page已经满了16KB,这时须要新申请一个新的数据页,而后将部分数据挪过去。这个过程成为也分裂。缓存

既然存在页分裂,那么固然也会存在页合并。将利用率低的Page页进行合并,页分裂的逆过程。bash

不论是页的分裂仍是合并,都会引发性能的损失。这里就须要考虑主键是否必需要自增?主键自增的模式下,每次插入的新纪录都是追加操做,都不涉及其它记录的挪动,不会触发叶子节点的分裂。服务器

TiDB

TiDB的存储与SQL模型是没有关系的,TiKV 没有选择直接向磁盘上写数据,而是把数据保存在 RocksDB 中,具体的数据落地由 RocksDB 负责。全部能够简化TiKV的存储模型为:网络

  1. 这是一个巨大的 Map,也就是存储的是 Key-Value pair
  2. 这个 Map 中的 Key-Value pair 按照 Key 的二进制顺序有序,也就是咱们能够 Seek 到某一个 Key 的位置,而后不断的调用 Next 方法以递增的顺序获取比这个 Key 大的 Key-Value

Regionmvc

对于一个 KV 系统,将数据分散在多台机器上有两种比较典型的方案:一种是按照 Key 作 Hash,根据 Hash 值选择对应的存储节点;另外一种是分 Range,某一段连续的 Key 都保存在一个存储节点上。TiKV 选择了第二种方式,将整个 Key-Value 空间分红不少段,每一段是一系列连续的 Key,咱们将每一段叫作一个 Region,而且咱们会尽可能保持每一个 Region 中保存的数据不超过必定的大小(这个大小能够配置,目前默认是 64mb)。每个 Region 均可以用 StartKey 到 EndKey 这样一个左闭右开区间来描述。分布式

尽管Region跟Page的概念很像,但须要注意的时候Region是键值对的存储区,与关系型数据表没有关系。Region做为TiDB提供分布式和高可用的核心工做单元,将数据划分红 Region 后会作两件事:ide

  • 以 Region 为单位,将数据分散在集群中全部的节点上,而且尽可能保证每一个节点上服务的 Region 数量差很少
  • 以 Region 为单位作 Raft 的复制和成员管理

那么关系型的表是如何在TiKV中进行映射呢?定义个表t1,主键为id,惟一索引name和普通索引age。

CREATE TABLE t1 {
	id BIGINT PRIMARY KEY,
	name VARCHAR(1024),
	age BIGINT,
	content BLOB,
	UNIQUE(name),
	INDEX(age),
};
-- 向t1中插入两条数据
insert into t1 values(1, “a”, 10, “hello”);
insert into t1 values(2, “b”, 12, “world”);
复制代码

上面的两条数据就会映射成下面的键值对存储到TiKV的Map中:

PK
t_11_1 -> (1, “a”, 10, “hello”)
t_11_2 -> (2, “b”, 12, “world”)

Unique Name
i_12_a -> 1
i_12_b -> 2

Index Age
i_13_10_1 -> nil
i_13_12_2 -> nil
复制代码

由于 PK 具备惟一性,因此能够用 t + Table ID + PK 来惟一表示一行数据,value 就是这行数据。对于 Unique 来讲,也是具备惟一性的,因此用 i + Index ID + name 来表示,而 value 则是对应的 PK。若是两个 name 相同,就会破坏惟一性约束。当咱们使用 Unique 来查询的时候,会先找到对应的 PK,而后再经过 PK 找到对应的数据,这里与MySQL的回表有点相似。

对于普通的 Index 来讲,不须要惟一性约束,因此使用 i + Index ID + age + PK,而 value 为空。由于 PK 必定是惟一的,因此两行数据即便 age 同样,也不会冲突。当咱们使用 Index 来查询的时候,会先 seek 到第一个大于等于 i + Index ID + age 这个 key 的数据,而后看前缀是否匹配,若是匹配,则解码出对应的 PK,再从 PK 拿到实际的数据。

2、SQL执行过程

MySQL

TiDB

从两个流程图能够不难看出SQL的被执行的流程分为:

  1. 创建链接。
  2. 客户端发送一条SQL给服务器。
  3. 服务器先检查查询缓存,若是命中缓存当即返回存储在缓存的结果。不然进入下一阶段。
  4. 服务器端进行SQL解析、预处理,再由优化器生成对应的执行计划。
  5. 根据优化器生成的执行计划,调用存储引擎的API来执行查询。
  6. 将结果返回给客户端。

那么TiDB做为分布式数据库,在SQL处理过程当中存在下面几个难点:

  1. SQL语言自己是一门复杂的语言。
  2. SQL是一门表意的语言,只是说『要什么数据』,而不说『如何拿数据』。
  3. 分布式存储引擎。须要考虑下层的数据是分片、网络不通如何处理。

3、事务隔离

MySQL

Mysql事务实现原理

READ UNCOMMITTED

事务中能够读到其余事务未提交的修改,形成脏读。

READ COMMITTED

事务未提交的修改对其它事务是不可见的,事务只会看到被提交的修改。

REPEATABLE READ

在同一事务中读取的数据始终是一致的,就算读取的数据有被其它事务提交过修改。

使用读写锁实现

使用mvcc实现

ERIALIZABLE 事务的执行按照串行执行。

引用表格总结一下始终事务隔离

TiDB

TiKV 的事务采用的是 Percolator 模型。TiKV 的事务采用乐观锁,事务的执行过程当中,不会检测写写冲突,只有在提交过程当中,才会作冲突检测,冲突的双方中比较早完成提交的会写入成功,另外一方会尝试从新执行整个事务。TiKV也实现了MVCC。TiKV 的 MVCC 实现是经过在 Key 后面添加 Version 来实现,简单来讲,没有 MVCC 以前,能够把 TiKV 看作这样的:

Key1 -> Value
Key2 -> Value
……
KeyN -> Value
复制代码

有了 MVCC 以后,TiKV 的 Key 排列是这样的:

Key1-Version3 -> Value
Key1-Version2 -> Value
Key1-Version1 -> Value
……
Key2-Version4 -> Value
Key2-Version3 -> Value
Key2-Version2 -> Value
Key2-Version1 -> Value
……
KeyN-Version2 -> Value
KeyN-Version1 -> Value
……
复制代码

4、索引

MySQL

最左前缀原则

因为覆盖索引(查询中索引已经覆盖了查询的需求,能够直接提供结果不须要回表,称之为:覆盖索引)能够显著的优化查询性能,而且索引的维护也是有代价的。因此如何权衡就是个问题。

最左前缀原则:即最左优先,在检索数据时从联合索引的最左边开始匹配,也能够是字符串索引的最左边的字符开始匹配。在创建联合索引时将高频的字段放置左侧。

索引下推:(index condition pushdown) 索引遍历过程当中,对索引中包含的字段先作判断,直接过滤掉减小回表。

TiDB

这里留个坑,后面去填。 索引范围计算简介

相关文章
相关标签/搜索