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