数据库知识大全
2021-03-05 13:48:48 84 举报
AI智能生成
数据库大纲
作者其他创作
大纲/内容
Redis
数据类型
string
list
set
zset
排序--例如按照文章点赞数排序等
hash
数据结构
dict
字典表有两个dictht哈希表,为了方便rehash。
在扩容时,将一个dictht的键值对rehash到另一个dictht上,然后释放空间、并交换角色
在扩容时,将一个dictht的键值对rehash到另一个dictht上,然后释放空间、并交换角色
跳跃表
可以理解为多层有序链表,下层元素一定包含上层元素,
且每个元素有指向下一个元素和下一层元素的指针
且每个元素有指向下一个元素和下一层元素的指针
插入时是否上浮由概率决定,1/2概率效率最高
使用场景
计数器
对string自增自减实现
缓存
常见问题
缓存穿透
数据库中不存在key导致
- 设置key为null
- 增加布隆过滤器过滤,false不再去查询db
缓存击穿
热点数据失效,导致大量请求打到db
- 更新热点缓存数据加锁
- 同时设置缓存标识(30分钟过期)、缓存数据(60分钟过期),
当缓存标识过期时,主动更新缓存,其他请求依然返回原有缓存数据
缓存雪崩
大量缓存同时过期
在原有过期时间的基础上价格随机值,避免大量缓存数据同时失效
业务层请求db加锁,避免大量请求同时打到db-治标不治本
解决方案
文档:Redis缓存穿透、雪崩.note
链接:http://note.youdao.com/noteshare?id=08eb142f139e10289cc50963ba057608&sub=0181347F60B1404397BED27EFBE85A1B
链接:http://note.youdao.com/noteshare?id=08eb142f139e10289cc50963ba057608&sub=0181347F60B1404397BED27EFBE85A1B
消息队列-发布订阅,建议使用kafka、rocketmq
会话session管理
分布式锁
redis SETNX
Redlock
Redis Memcached
数据类型
- redis支持string/list/set/zset/hash
- memcached支持string
持久化
- redis支持rdb、aof持久化
- memcached不支持持久化
分布式
- redis支持客户端、代理、服务端(RedisCluster)分片
- memcached支持客户端hash分布式存储
内存管理机制
- redis并不是所有的数据都在内存中,可以将一些很久不用的value交换到磁盘,
memcached所有数据都在内存中
- memcached将内存分割成固定大小的块,以解决内存碎片的问题,内存利用率不高
过期时间
可以为每个键设置过期时间
对于hash类型,只能为整个键设置过期时间(整个散列表)
淘汰策略
失效算法
FIFO
先进先淘汰
LRU
Least Recently Used、最近最少使用
LFU
Least Frequently Used、使用频率最少
失效策略
volatile-lru/volatile-random/volatile-lfu
allkeys-lru/allkeys-random/allkeys-lfu
持久化
rdb
数据快照--将某个时间点的所有数据存储在硬盘
aof
always
everysec
no
原子性
事务
事务中的多条命令会一次发送到服务端,减少客户端与服务端通信
watch key
mutil
dosomething
exec
watch类似于乐观锁,exec时发现有其他客户端修改了key,则执行失败
lur脚本
事件模型
网络事件处理器
I/O多路复用程序
同时监听多个套接字,并将到达的事件传送给文件事件分派器
文件事件分派器
根据套接字产生的事件类型调用相应的事件处理器
复制
通过slave of host port实现一个服务器成为另一个服务器的从
- 主服务器创建快照文件并发送给从服务器,在发送期间将写命令记录在缓冲区,
- 从服务器丢弃所有旧数据,加载主服务器发送过来的快照,之后接收主服务器的写命令
- 主服务器没执行一次写命令,就向从服务器发送相同的写命令
分片
客户端分片
代理端分片
服务端分片:Redis Cluster
原理
事务ACID
原子性-Atomicity
事务被视为不可分割的最小单元,要么全部成功,要么全部失败回滚
一致性-Consistency
数据库在事务执行前后保持一致的特性
隔离性-Isolation
一个事务修改操作在提交以前,对其他事务不可见
持久性-Durability
事务一旦提交,所做的修改永久保持在数据库中
并发一致性
修改丢失/覆盖
不同事务写操作覆盖
脏读
t2读取了t1(期间t1回滚)未提交的数据
不可重复度
t2前后两次读取单条数据不一致,由于t1期间执行写操作
幻读
t2前后读取范围值不一致,由于t1期间插入了新数据
封锁
类型
读写锁
X/S
意向锁IX/IS
一个事务获得某个数据行对象锁之前,首先获得意向锁,
其他事务对表加锁时不需要扫描整张表了
其他事务对表加锁时不需要扫描整张表了
粒度
表锁
行锁
三级封锁协议
一级封锁协议
事务t1修改数据a时,必须加写锁,直到事务结束释放
事务t1修改数据a时,必须加写锁,直到事务结束释放
二级封锁协议
在一级封锁协议的基础上,事务t2读取数据a时必须加读锁,读取完毕后立马释放
在一级封锁协议的基础上,事务t2读取数据a时必须加读锁,读取完毕后立马释放
三级封锁协议
在二级封锁协议的基础上,事务t2读取数据a必须加读锁,知道事务结束才释放
在二级封锁协议的基础上,事务t2读取数据a必须加读锁,知道事务结束才释放
隔离级别
Read uncommited
Read commited
Repeatable read
Serializable
MVCC
版本号
系统版本号
每开启一个新的事务,系统版本号自动递增
事务版本号
事务开始时的系统版本号
隐藏的列
每行记录两个隐藏列,创建版本号、删除版本号
Undo 日志
MVCC的快照存储在Undo日志中,
Undo日志通过回滚指针将数据行(Record)所有快照连接起来
Undo日志通过回滚指针将数据行(Record)所有快照连接起来
实现过程
select
- 快照创建版本号 < 事务t版本号 < 快照删除版本号 : 正确姿势
- 快照创建版本号 > 事务t版本号 : 读取的快照被其他事务修改
- 快照删除版本号 < 事务t版本号 : 读取的快照被删除
insert
将当前的系统版本号作为快照的创建版本号
delete
将当前系统版本号作为快照的删除版本号
update
可以理解为先delete,后insert
快照读、当前读
快照读
读取快照中的数据,减少加锁带来的开销
select * from table ...;
select * from table ...;
当前读
select * from table where ? lock in share mode;
select * from table where ? for update;
insert;
update;
delete;
Next-Key Locks
Record Locks
锁定一条记录的索引,而非记录本身
Gap Locks
锁定索引之间的间隙,但不包含索引本身
Next-key-locks
Record Locks 与 Gap Locks的结合,既可以锁定一条记录的索引,也可以锁定索引的间隙
是InnoDB引擎的一种锁实现,通过MVCC+ Next-Key Locks解决幻读
Mysql
索引
B+Tree原理
在B+Tree中,一个节点中的 key 从左到右非递减排列,如果某个指针左右相邻的 key 分别为 keyi 和 key i+1,
则该指针指向的节点的所有 key 大于等于keyi,且小于等于 keyi+1
则该指针指向的节点的所有 key 大于等于keyi,且小于等于 keyi+1
B Tree 和 B+Tree区别
B Tree 叶子节点、非叶子节点都可以存储data,叶子节点无链指针,无法快速区间访问
B+Tree 只有叶子节点存储data,且叶子节点有指针,支持快速区间访问
B+Tree 只有叶子节点存储data,且叶子节点有指针,支持快速区间访问
Mysql 索引
B+Tree 索引
主索引
又名聚簇索引,主索引的叶子节点data域记录着完整的数据,
无法将数据行存放在两个不同的地方,因此一个表只能有一个聚簇索引
无法将数据行存放在两个不同的地方,因此一个表只能有一个聚簇索引
辅助索引
叶子节点data域记录着主键值,根据辅助索引查找时,
先查找到主键值,然后根据主键去主索引查找到完整数据
先查找到主键值,然后根据主键去主索引查找到完整数据
适用场景
既可以用于查找,也可以用于分组和排序
适用于全键值、键值范围、键值前缀查询,键值前缀查找只适用于最左前缀查找
哈希索引
无法分组和排序
只支持快速精确查询,不支持区间范围查询
InnoDB支持自适应哈希索引,当某个索引被频繁引用时,
会在B+Tree索引基础上创建哈希索引,支持快速哈希查找
会在B+Tree索引基础上创建哈希索引,支持快速哈希查找
全文索引
用于全文检索,倒排索引实现,记录着关键词term在文档中的映射
地理空间索引
用于地理位置数据存储
索引优化
单列索引
使用表达式、函数索引失效
多列索引
多列查询条件时,最好创建多列索引
覆盖索引
查询的列包含在索引中,或者说索引覆盖了查询列
对于InnoDB引擎,若辅助索引能够覆盖查询列,则不用再次查询主索引
前缀索引
对于 blob text varchar 类型字段,使用前缀索引,前缀的长度根据选择性决定
索引顺序
选择性:不重复的索引值与总记录数的比值
最大值为1,此时每条记录都有唯一的索引与其对应,选择性越高,查询效率越高
最大值为1,此时每条记录都有唯一的索引与其对应,选择性越高,查询效率越高
将选择性强的索引放在靠前的位置
索引优点
减少了服务器扫描数据的行数
帮助服务器分组、排序,无需再创建临时表
不创建索引,分组、排序都是要创建临时表的,explain观察Extral -> Using temporary
不创建索引,分组、排序都是要创建临时表的,explain观察Extral -> Using temporary
将随机 I/O 转换为顺序 I/O,B+Tree 是有序的,将相邻的数据存储在一起
索引使用条件
适用于中大型表
不适用于小型表,小型表直接全表扫描更快
不适用于特大型表,如数据超过千万或100G,此时考虑分库、分表策略
查询性能优化
Explain分析
select_type
查询类型:简单、关联、子查询等
key
使用到的索引
rows
扫描的行数
优化数据访问
只返回必要的列,不要select * from
只返回必要的行,limit限制
缓存重复查询的数据
服务端减少扫描行数,见上述索引优化
优化查询方式
切分大查询
一个大查询数据一次执行,可能会锁住很多数据,耗尽系统资源,阻塞很多小但重要的查询
分解大连接查询
缓存更高效,不会因为一个表发生变化导致整个缓存失效
缓存复用,分解成单表查询,查询结果缓存很可能被其他查询复用
减少锁竞争
提高伸缩性,在应用层连接,更容易对数据库拆分,更容易做到高性能和伸缩性
存储引擎
InnoDB
MySQL默认存储引擎
MyIIAM
支持全文索引、空间数据索引
读写分离,slave读可以使用MyISAM引擎
切分,详见文档
文档:数据库分库分表汇总.md
链接:http://note.youdao.com/noteshare?id=125e21e8e36bd27d013eda0b6c34101c&sub=0EB04585708948249AB3049117B572A0
链接:http://note.youdao.com/noteshare?id=125e21e8e36bd27d013eda0b6c34101c&sub=0EB04585708948249AB3049117B572A0
复制
主从复制
binlog线程
将主服务器上的写操作写入binlog
I/O线程
读取主服务器上的binlog,并写入从服务器的中继日志Relay Log
SQL线程
读取中继日志,解析出主服务器的数据更改并在从服务器上执行
读写分离
主服务器处理写操作、以及实时性要求比较高的读操作
读写分离原因
主从服务器各自负责自己的读和写,极大缓解了锁的竞争
从服务器可以使用MyISAM引擎,提高性能、节约系统开销
增加冗余,提高可用性
读写分离常使用代理方式来实现?
HAproxy
ProxySQL
...
代码方式:sharding-jdbc等?
研究下实现方式,及强制走主库如何实现?代理 + 代码方式
0 条评论
下一页
为你推荐
查看更多