万丈高楼平地起-redis基础数据结构
5种基础数据结构
Redis有5种基础数据结构,分别为string(字符串), list(列表), hash(哈希), set(集合), zset(有序集合)
string
-
当前字符串分配的空间capacity一般要高于实际字符串长度len。
-
当字符串长度小于1M时,扩容都是加倍现有的空间;如果字符长度大于1M,扩容时最多只会多扩1M的空间。
-
字符串的最大长度为512M。
-
命令:
setex: 等价于 set + expire
setnx: 等价于 set + not + exist(如果不存在,就执行set创建)
incr:自增操作,范围在signed long的最大值的最小值间,如果超出范围,Redis会报错。
incrby:指定步长自增
list(列表)
基础使用
-
Redis的列表相当于Java中的LinkedList,是链表而不是数组。其插入和删除操作非常快,索引速度很慢。
-
当列表弹出最后一个元素之后,该数据结构被自动删除,内存被回收。
-
Redis列表结构常用来作异步队列使用。将需要延后处理的任务结构体序列化成字符串,塞进Redis列表。另一个线程从这个列表中轮询数据进行处理。
-
列表主要存在2种使用方法:
- A侧进,B侧出,即为队列(rpush-lpop,或者lpush-rpop)
- A侧进,A侧出,即为栈(rpush-rpop, 或者lpush-lpop)
慢操作
- lindex:相当于Java中的get(int index)方法,需要遍历,性能随着index增大而变差。
- ltrim:列表截断,保留指定区间的数据,该操作会变更原来数据
- index可以为负数,index为‘-1’,表示为最后一个元素,index为‘-2’,表示倒数第二个元素。
- 其它命令:lrange, len
快速链表
Redis底层存储的不是一个简单的LinkedList,而是一个快速链表(quicklist)结构。
首先在列表元素较少的情况下,会使用一块连续的内存存储,这个结构是ziplist(压缩列表)。它将所有的元素紧挨着一起存储,分配的是一块连续的内存。当数据比较多的时候才会变成quicklist。因为普通的链表需要的附加指针空间太大,会浪费空间,加重内存的碎片化。所以Redis将链表和ziplist结合起来组成quicklist,也就是将多个ziplist通过双向指针串起来,既满足了快速的插入删除性能,又不会出现太大的空间冗余。
hash(字典)
- Redis的字典相当于Java中的HashMap。
- 不同之处在于,Redis的字典值只能是字符串,而且两者的rehash方式不同。
- java的rehash:当字典很大时,rehash是个耗时操作,需要一次性全部rehash。
- Redis的rehash:需要满足高性能,不能阻塞服务,使用渐进式rehash策略。
渐进式rehash会在rehash的同时,保留新旧两个hash结构。查询时会同时查询两个hash结构,然后在后续的定时任务以及hash操作指令中,循序渐进地将旧hash内容一点点地迁移到新hash结构中。当搬迁结束,就会使用新的hash结构取而代之。
- 当hash移除了最后一个元素后,该数据结构会被自动删除,内存被回收。
- 使用场景:可以用来存储用户信息,可以对用户结构中的每个字符串单独存储。
- 常用命令:
hset:设置hash的key-value
hgetall:获取hash中的所有key-value
hlen:查询hash长度
hget:查询hash中指定key的value
hmset:批量设置
set(集合)
- Redis中的集合,相当于Java中的HashSet,内部的键值对是无序的,唯一的。其内部实现相当于是一个字典,字典中的所有的value都是一个值NULL。
- 当集合中的最后一个元素被删除之后,数据结构被自动删除,内存被回收。(与list和hash一致)。
- set可以用来存储在某活动中中奖的用户id,因为有去重功能,可以保证同一个用户不会中奖2次。
- 常用命令:
sadd:向集合中添加元素
smembers:查询集合中现存的元素
sismember:判断某个value是否存在于集合中
scard:查询集合中元素数量
spop:从集合中删除一个元素
zset(有序列表)
- zset中value是唯一的,并且给每个每个value赋予一个score,代表这个value的排序权重。
- zset中最后一个value被移除后,数据结构被自动删除,内存被回收。
- 使用场景:
- zset可以用来存储粉丝列表,value值是粉丝的用户id,score是关注时间
- zset可以用来存储学生的成绩,value值是学生的id,score是考试成绩。
- zset内部使用的数据结构是跳跃链表,这块内容后边再专门研究。
- 常用命令:
- zadd:向zset中添加元素。
> zadd books 9.0 “think in java”
- zrange:按score排序列出,参数区间为排名范围。
> zrange books 0 -1
- zrevrange:按score逆序列出,参数区间为排名范围。
> zrevrange books 0 -1
- zcard:统计集合中数量。
> zcard books
- zscore:获取指定value的score值。
> zscore books “think in java”
- zrank:获取排名。
> zrank books “think in java”
- zrangebyscore:根据分值区间遍历集合。
> zrangebyscore books 0 8.91
“think in java”
> zrangebyscore books -inf 8.91 withscores
“think in java”
9.0000000004
- zrem:删除value
> zrem books “think in java”
- zadd:向zset中添加元素。
4种数据结构能用规则
- create if not exist。
- drop if no elements.
过期时间
- 过期是以对象为单位的,比如一个hash结构的过期是整个hash对象的过期,而不是其中的某个子key的过期。
- 如果一个字符串已经设置了过期时间,然后再用set方法修改了它,它的过期时间就会消失。
- 命令:
- expire:设置过期时间
expire codehole 600
- ttl:查看剩余存活时间
ttl codehole
- expire:设置过期时间
共同学习,写下你的评论
评论加载中...
作者其他优质文章