You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

105 lines
5.6 KiB

+ String
+ hash
+ list
+ set
+ zset
# 一、数据结构
## 1. string
字符串由多个字节组成每个字节由8个bit组成可以将一个字符串看成很多bit的组合这就是bitmap数据结构。
redis提供的字符串是动态字符串是可以修改的字符串内部使用数组结构实现采用**预分配**冗余空间的方式来减少内存的频繁分配如图所示预分配的空间capacity要高于实际字符串长度len。
![[Snipaste_2023-02-22_14-56-05.png]]
当字符串长度小于1MB时扩容都是加倍现有空间。如果字符串长度超过1MB扩容时一次只会多扩1MB空间并且字符串最大长度为512MB。
### 1.1常用命令
#### 1.1.1 键值对
![[Snipaste_2023-02-22_14-56-05 1.png]]
#### 1.1.2 批量键值对
对多字符串进行批量读写
![[Snipaste_2023-02-22_14-56-05 2.png]]
#### 1.1.3 过期和set命令扩展
对key设置过期时间到期自动删除
![[Snipaste_2023-02-22_14-56-05 3.png]]
等价命令 setex name 3 zr 等价于set + expire
![[Snipaste_2023-02-22_14-56-05 4.png]]
setnx name zr 如果name不存在则创建
![[Snipaste_2023-02-22_14-56-05 5.png]]
#### 1.1.4 计数
如果value值是一个整数可以对它进行自增操作自增范围在long的最大值和最小值之间
![[Snipaste_2023-02-22_14-56-05 6.png]]
## 2.list
Redis的list相当于Java的LinkedList是链表不是数组。插入和删除很快时间复杂度为O(1)。索引定位慢时间复杂度为O(n)。list的每个元素都使用了双向指针可以支持前向后向遍历因此可以作为队列或栈使用。
![[Snipaste_2023-02-22_14-56-05 7.png]]
### 2.1 常用命令
#### 2.1.1 队列
队列是先进先出的数据结构,用于消息排队和异步逻辑处理。支持左进右出、右进左出,会确保元素的访问顺序性。
![[Snipaste_2023-02-22_14-56-05 8.png]]
使用pop命令后元素会删除
#### 2.1.2栈
栈是后进先出的数据结构
![[Snipaste_2023-02-22_14-56-05 9.png]]
#### 2.1.3慢操作
lindex类似于java的get(int index)方法需要对list进行遍历性能随着参数index增加而变差。
ltrim类似于截取操作由两个参数start_index和end_index定义一个区间保留在区间内的值区间外的删除可以用来实现一个定长的链表。
index可以为负数index=-1表示倒数第一个元素同理index=-2表示倒数第二个元素。
![[Snipaste_2023-02-22_14-56-05 10.png]]
### 2.2底层数据结构quicklist
实际上Redis的list并不是一个简单的linkedlist而是quicklist快速链表
在元素较少情况下会使用一块连续的内存存储这个结构是ziplist压缩列表。将所有的元素彼此紧挨着存储也可以看作是数组结构。当数据量比较多的时间才会变成quicklist因为普通的链表需要的附加指针空间前后指针所以Redis将链表和ziplist结合组成quicklist将多个ziplist使用双向指针连接使用。
quicklist内部默认单个ziplist长度为8kb超过这个字节数就会另启一个ziplist
![[Snipaste_2023-02-22_16-10-55.png]]
## 3.hash
Redis字典相当于Java的HashMap属于无序字典在数据结构上使用的是数组+链表也就是散列表结构。
![[Snipaste_2023-02-22_16-10-55 4.png]]
### 3.1 常用操作
![[Snipaste_2023-02-22_16-10-55 1.png]]
#### 获取字典中的所有值
![[Snipaste_2023-02-22_16-10-55 2.png]]
#### 获取字典中的所有键值对
![[Snipaste_2023-02-22_16-10-55 3.png]]
### 3.2 底层数据结构
采用于HashMap相同的散列表结构redis字段的值只能是字符串
![[Snipaste_2023-02-22_16-10-55 5.png]]
#### 3.2.1 rehash
Redis为了追求高性能采用了渐进式rehash策略可以不堵塞服务但是需要牺牲空间可以理解为空间换时间。渐进式rehash会在执行同时保留新旧两个hash结构查询时会同时查询两个hash然后再后续的定时任务以及hash操作指令中循序渐进地将旧hash的内容迁移到新hash结构当迁移完成就使用新hash代替。空间换时间
![[Snipaste_2023-02-22_16-10-55 6.png]]
### 3.3优缺点
2 years ago
hash结构可以结构化存储用户信息相比于json存储可以单独获取或修改某几个字段。如果以整个字符串形式保存的话只能一次性读取比较浪费流量。缺点是存储消耗要高于单个字符。
## 4.set
相当于Java的HashSet其内部键值对是无序且唯一的内部实现相当于一个特殊的字典字典中所有的value都是NULL
### 4.1 常用操作
![[Snipaste_2023-02-22_16-10-55 7.png]]
#### 查询某个值是否存在
![[Snipaste_2023-02-22_16-10-55 8.png]]
#### 获取长度
![[Snipaste_2023-02-22_16-10-55 9.png]]
#### 弹出一个
![[Snipaste_2023-02-22_16-10-55 10.png]]
## 5.zset
类似于Java的SortedSet和HashMap结合体set保证内部value的唯一性另外可以给每个value赋予一个score代表排序权重内部是使用跳跃列表实现。
![[Snipaste_2023-02-23_10-00-41.png]]
### 5.1 常用操作
![[Snipaste_2023-02-23_10-00-41 1.png]]
#### 逆序输出
![[Snipaste_2023-02-23_10-00-41 2.png]]
#### 统计
![[Snipaste_2023-02-23_10-00-41 3.png]]
#### 获取指定value的score
![[Snipaste_2023-02-23_10-00-41 4.png]]
#### 排名
![[Snipaste_2023-02-23_10-00-41 5.png]]
#### 删除value
![[Snipaste_2023-02-23_10-00-41 6.png]]
#### 根据score区间遍历
0 2 表示分数区间
![[Snipaste_2023-02-23_10-00-41 7.png]]
### 5.2 底层数据结构(跳跃列表)
查看数据结构相关文档
### 5.3 假如元素score值相同
zset的排序元素不只看score值如果score相同还会比较value值字符串比较