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