数据管理工具集,如redis,mysql,pg等
1 - DB
DB 相关知识
1.1 - Mysql基础知识
mysql 基础知识
功能模块
- 连接器
- 查询缓存
- 解析器
- 执行器
- 缓存记录
- 执行器调用存储引擎
分为两层: server层和存储引擎层
server层
server 层负责建立连接、分析和执行 SQL。 msyql大多数的功能模块都是这这里实现,主要包括连接器,查询缓存,解析器,预处理器,优化器,执行器等。 所有的内置函数和所有跨存储引擎的功能(如存储过程,触发器,视图等)都在server层实现
存储引擎层
负责数据的存储和提取,支持多个存储引擎。不同的引擎共用一个server层。 常说的索引数据结构,就是由存储引擎层实现的。
细说每一个功能模块
第一步:连接器
首先是连接 Mysql 服务,才能执行sql语句。
连接的过程先经过 TCP 三次握手,因为 Mysql 是基于TCP 协议传输的。
TCP连接建立后,验证用户名和密码,如果都没问题,连接器就会获取该用户的权限,然后保存起来,后续该用户在此连接里的任何操作,都会基于连接开始时读到的权限进行逻辑判断。
一个用户建立了连接,即时管理员中途修改了该用户的权限,也不会影响已经存在连接的权限,生效需要重新建立连接。
# 知道 Mysql 服务被多少个客户端连接了
show processlist;
# 空闲连接的最大时长
show variables like 'wait_timeout';
# 手动断开空闲连接
kill connection + id;
# 连接数限制,默认151个。
show variables like 'max_connections';
mysql的长短连接
一般推荐使用长连接,但是长连接会导致内存增多,这些连接对象只有在断开连接时才会释放。 解决长连接占用内存问题:
- 定期断开长连接
- 客户端主动重置连接
第二步: 查询缓存
如果是查询语句,会去查询缓存里查找缓存数据。key-value存储。key是sql语句,value是查询结果。
如果命中缓存,会直接返回value给客户端。如果没有缓存会继续执行查询,等执行完会在查询缓存中插入。
MYSQL 8.0 将查询缓存删掉了,之前的版本,想关闭查询缓存,可以将参数 query_cache_type 设置成 DEMAND
第三步: 解析SQL
在执行sql之前,会先对sql语句做解析,这个工作由 [解析器] 完成。
解析器
主要做两件事:
- 词法分析:根据输入字符串识别出关键字出来,构建出 SQL 语法树,方便后面模块获取sql类型,表名,字段名,where条件等。
- 语法分析:根据词法分析结果,语法解析器根据语法规则,判断输入的sql语句是否满足mysql语法。输入的sql语法不对,会在解析器这个阶段报错。
第四步: 执行sql
经过解析器后,接着要进入执行sql查询语法的流程,每条select查询语句主要分为以下三个阶段:
- prepare 阶段,预处理阶段;
- optimize 阶段,优化阶段;
- execute 阶段,执行阶段;
预处理器
预处理阶段:
- 检查sql语句中的表或者字段是否存在;
- 将select * 中的 * 符号,扩展为表上的所有列;
优化器
经过预处理后,还需要将sql查询语句先制定一个执行计划,这个工作由【优化器】来完成。
优化器主要负责将sql查询语句的执行方案确定下来,比如有多个索引的时候,优化器会基于查询成本考虑使用哪个索引。
想知道使用哪个索引,可以加一个 explain 命令,输出sql的查询计划,然后执行计划中的key表示使用了哪个索引,为null说明没有使用索引,会全表扫描(type=ALL),这种扫描方式是效率最低的。
执行器
经历过优化器后,就确定了执行方案,接下来mysql就进行开始执行。在执行过程中,执行器会和存储引擎交互,交互是以记录为单位。
用三种方式执行过程,确定一下执行器和存储引擎的交互过程。
- 主键索引查询
- 全表扫描
- 索引下推
#建表
CREATE TABLE `person` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(50) COLLATE utf8mb4_general_ci DEFAULT NULL,
`age` int DEFAULT NULL,
`address` varchar(100) COLLATE utf8mb4_general_ci DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `name` (`name`)
);
主键索引查询
这条语句的查询条件用到了主键索引,而且是等值查询,同时主键id也是唯一,所以优化器决定选用访问类型的 const 进行查询,也就是使用主键索引查询一条记录
select * from product where id = 1;
执行器与存储引擎的流程是这样的:
- 执行器第一次查询,把条件 id = 1 交给存储引擎,让存储引擎定义符合条件的第一条记录。
- 存储引擎通过主键索引的B+树结构定位到 id=1 的第一条记录,将结果返回给执行器。
- 执行器从存储引擎读取到记录后,判断是否符合查询条件,如果符合就发送给客户端,如果不符合就跳过该记录。
- 执行器查询的过程是一个 while 循环,如果函数指针被指向一个永远返回-1的函数,所以当调用该函数时,执行器就退出循环了,也就是查询结束了。
全表扫描
全表扫描没有使用到索引,优化器决定选择访问类型 ALL 进行查询。
EXPLAIN SELECT * FROM person WHERE age = 1;
索引下推
索引下推能够减少二级索引在查询时的回表操作,提高查询的效率,因为它将server层部分负责的时候,交给存储引擎层去处理了。
索引篇
什么是索引?
数据库中索引的定义就是帮助存储引擎快速获取数据的一种数据结构,形象的说就是 索引是数据的目录。
存储引擎说白了就是如何为存储的数据建立索引和如何更新、查找数据等技术实现的方法。 mysql 存储引擎有 InnoDB MyISAM 等。
索引和数据位于存储引擎中。
索引的分类?
常见的有主键索引、二级索引、普通索引、聚集索引、B+树索引、hash索引、唯一索引等。
再根据特点将这些索引分类:
- 按照【数据结构】:B+树索引、hash索引、Full-txt索引
- 按照【物理存储】:聚簇索引(主键索引)、二级索引(辅助索引)
- 按照【字段特征】:主键索引、唯一索引、普通索引、前缀索引
- 按照【字段个数】:单列索引、联合索引
按照数据结构分类
InnoDB引擎和 MyISAM引擎 都支持 B+树索引和 Full-Text索引,都不支持 HASH索引。
在创建表时,InnnoBD 会根据不通的场景选择不同的列作为索引:
- 如果有主键,默认使用主键作为聚簇索引的索引键
- 如果没有主键,选择第一个不包含 NULL 值的唯一列作为聚簇索引的索引键
- 所有在上面两个都没有的情况下,InnnoDB会自动生成一个隐式自增id作为聚簇索引的索引键
其他索引都属于辅助索引,也被称为二级索引和非聚簇索引。 创建的主键索引和二级索引默认使用的是 B+Tree 索引。
B+Tree 存储千万级的数据只需要3-4层高度,数据最多需要 3 - 4 次磁盘 I/O。
主键索引的B+Tree和二级索引的 B+tree区别:
- 主键索引的 B+Tree 的叶子节点存放的是实际数据,所以完整的用户记录都存在在主键索引的 B+Tree 的叶子节点里。
- 二级索引的 B+Tree 的叶子节点存放的是主键值,而不是实际数据。
利用二级索引只查id可以一次查到,这种叫【覆盖索引】,只查询一个 B+Tree 就能找到数据。
执行计划参数
- possible_keys 表示可能用到的索引
- key 实际用的索引
- ken_len 索引的长度
- rows 扫描的数据行数
- type 数据扫描类型
- ALL 全表扫描 - 最差
- index 全索引扫描 -第二差,对索引进行全扫描,不用排序
- range 索引范围扫描 - 尽量让 sql 查询使用到这一级别的访问
- ref 非唯一索引扫描 - 小范围扫描
- eq_ref 唯一索引扫描 - 多表联查较多
- const 结果只有一条的主键或者唯一索引扫描
- extra
- Using indx 使用了覆盖索引,避免了回表
- Using Temporary 使用了临时表保存中间结果,效率低
- Using filesort:效率低
1.2 - Postgresql
Postgresql
使用
查询sql跟mysql一样
-- 查库
SELECT datname FROM pg_database;
-- 查表
SELECT * FROM pg_tables WHERE schemaname = 'public';
2 - Redis
Redis
Redis
2.1 - 基础知识
redis 基础知识
Redis简介
redis是一种基于内存的数据库,用作数据库、缓存、消息代理和流引擎。
常用做mysql的缓存,因为redis具备【高性能】和【高并发】两种特性。
数据类型与使用场景
- string :缓存对象,常规计数,分布式锁,共享session信息等。
- hash : 缓存对象,购物车
- set : 聚合计算场景(并集,交集,差集),如 点赞,共同关注、抽奖活动等。
- list : 消息队列,但是有两个问题:1.生产者需要自行实现全局唯一ID;2.不能以消费者组形式消费数据
- zset : 排序场景,如排行榜、电话、姓名排序等
- bitmap: 统计场景,如签到、判断用户登陆状态,连续签到用户总数等
- hyperloglog: 海量数据基数统计场景,如百万网页 UV 计数等
- GEO 存储地理位置信息的场景,如滴滴叫车
- stream : 消息队列。相比list,1.自动生成全局唯一消息ID,2.支持消费组形式消费数据
线程模型
Redis单线程是指【接受客户端请求->解析请求->进行数据读写等操作->发送数据到客户端】这个过程是由一个线程来完成的。