这是我的第一篇学习笔记,认真观看了视频课程之后,结合自己的日常使用,对数据库内容做一个总结。
- mysql
mysql是我们常用的关系型数据库,我从大三开始使用已经4年了,无论是web开发还是服务器开发都离不开数据存储,结合我日常的使用,我对mysql的几大关键节点做出总结。
索引
B树和B+树作为mysql的基础,有很多内容。B+树 比 B树的优势在哪里? B树 所有结点都存储 索引+行数据 B+树 非叶子结点 只存储 索引,叶子结点存储 索引+行数据
相同点:
作为 多路平衡查找树
m阶B/B+树 时间复杂度都是 log以m为底n的对数
不同点:
B+树的优势主要在于:
• 增加/删除结点
由于B+树存在数据冗余,删除时可以直接从叶子中删掉,可以不发生复杂的树的调整。B树结点的删除比B+树复杂
• 存储更多索引
由于B+树的非叶子结点只存储索引,所以可以存储更多的索引
• 范围查找。B+树的叶子结点之间的双向指针可以进行范围查找。 索引失效的情况: 左或者左右迷糊匹配、表达式计算、使用函数、where..or并非都是索引、不满足最左匹配原则、隐式类型转换。
from Products
# where prod_desc like '%toy%';
# where instr(prod_desc , 'toy') > 0;
# having instr(prod_desc , 'toy');
having locate('toy' , prod_desc);
- redis
redis有5大常用数据类型:string,list,hash,set,zset,对应了六七种数据类型 分别是SDS、双向链表、压缩列表、quicklist、listpack、哈希函数、整数集合、跳表
string 就是kv的基础使用
针对C中的char*存在的不足,例如O(N)复杂度获取长度,\0导致二进制不安全,以及strcat字符串拼接缓存溢出问题,redis构造了sds结构体,加了len,alloc,flags元数据和char[]解决了上述问题,取消了字节对齐,节省了内存空间。
list有序可重复字符串集合,侧重组合、排序、增删
| 双向链表 | 缺点是,没有利用cpu缓存,且node较大较浪费,内存开销大 |
|---|---|
| 压缩列表 | 类似数组,但是元素可以不同类型/不同大小,列表元素由3部分组成:前结点长度+当前结点长度及类型+data,即前结点的大小会影响后结点(例如前结点长度为254,我就可以用1B来存储,突然前面变成256,那我就要5B了)。存储连锁更新问题。 |
| ---- | ---------------------------------------------------------------------------------------------------------------------- |
| quicklist | 类似双向链表,即了双向链表+压缩列表,插入结点时判断能否加入当前压缩列表,其实只是缩小了连锁更新范围。 |
| --------- | --------------------------------------------------- |
| listpack | 替代压缩列表,为彻底解决连锁更新。它的结点由3部分组成:encoding类型编码+本结点长度+data。 |
| -------- | ---------------------------------------------------- |
hash,无序且唯一的kv集合,侧重查找
set,无序且唯一的字符串集合,侧重查找
zset,对set加个score进行排序,侧重范围查找+单点查询。
索引下推的英文名叫 index condition pushdown,简称icp 将server层的部分操作,让存储引擎做。
目的:减少回表次数,提高查询效率。
使用条件是:
mysql5.6及以后
innodb,myisam引擎
二级索引
多条件查询,这些条件可以是与、或、范围查询等。 比如,公司员工信息表包含他们的身份证,查询 本地人 且 age>30 的员工
联合索引就是 身份证 + age
条件就是 id like %4206 and age > 30 在MySQL 5.6之前,存储引擎根据通过联合索引找到name likelike '张%' 的主键id(1、4),逐一进行回表扫描,去聚簇索引找到完整的行记录,server层再对完整数据根据age=10进行筛选。
回表2次
而MySQL 5.6 以后, 存储引擎根据(name,age)联合索引,找到,由于联合索引中包含列,所以存储引擎直接再联合索引里按照age=10过滤。按照过滤后的数据再一一进行回表扫描。
回表1次