字符串类型是redis的最基本类型,首先无论值是什么数据类型,其键都是字符串,且其他数据类型的数据结构都是在字符串的基础上搭建的,相信读者能够体会到字符串在redis的地位是有多么的重要。
那么字符串的值可以是什么呢?
当然值的大小不是无限的,不然的话你买内存的钱就可以买整个宇宙了。redis规定其值最大不能大过512M。
往redis种插入字符串类型的值
set key value
根据键获取值
get key
查看字符串长度
strlen key
批量设置值
mset key value [key value]
批量取值
mget key [key]
批量操作的命令可有效地提高开发命令,但mget、mset的时间复杂度是O(n),因此一次设置的键值对多的话,可能会引起redis服务器的阻塞。
如果字符串类型的值是数字,自增命令(每次加1)
incr key
指定每次加的值
incrby key amount
如果字符串类型的值是数字,自减命令(每次减1)
decr key
往字符串里面追加字符串 (类似JAVA中StringBuilder的append)
append key value
根据开始索引和结束索引获取字符串的部分
getrange key start_index end_index
根据索引设定指定位置的值
setrange key index value
设置后,其他命令不能够修改该键值,直到键删除或者时间到了后释放(redis官方给出了使用setnx实现分步锁的方式)
set key value nx ex 10
为键设置秒级过期时间/毫秒级过期时间
setex/setpx key 10 value
字符串类型的内部编码有三种类型:
redis的底层数据结构类似JAVA中的ArrayList类型,都是有着预分配冗余空间,防止反复的空间扩展降低效率,redis中规定如果当前的字符串大小小于1M时扩容都是当前大小的加倍,而如果字符串的大小大于1M的时候,无论大于多少只会扩容1M,而前面说到redis规定值的大小只有512M。
List类型是用来存储多个有序字符串的,List中的每个元素称为元素,可以往左push添加元素,也可以往右push元素,当然也可以获取指定范围的元素,还可以按照自己的需求获取List中指定的元素。一个列表中最多可以存储2^23-1个元素,它底层其实是一个双向的链表,对两端的性能很高,而通过索引下标操作中间的节点时性能会较差。
List有如下两个特点:
往左插入元素
lpush key value [value]
往右插入元素
rpush key value [value]
往值位置的前面或者后面加入元素
linsert key BEFORE|AFTER value new_value
根据起始索引和终止索引查看范围的值
lrange key start_index end_index
根据值在列表中的索引查找值
lindex key index
获取列表的长度
lren key
弹出列表左边的元素
lpop key
弹出列表右边的元素
rpop key
删除指定元素
lrem key count value
裁剪列表
ltrim key start_index end_index
修改特定的值
lset key index value
阻塞式向右弹出
brpop key
阻塞式向左弹出
blpop key
列表类型的内部编码有两种。
但在redis3.2版本之后(笔者采用的是redis6.2.5),当元素大于512个或元素大小超过64个字节,内部编码已从linkedlist变为quicklist。
quicklist采用了ziplist的优点和linkedlist的优点,也就是每个节点都是一个ziplist节点之间用双向的指针联系起来,这样即使得内存使用的减少满足了快速的插入和删除,也减少了空间的冗余。
Set类型也是用来存储多个元素的,但是集合内的元素是无序的,而且它不允许有重复的元素出现在同一个键中,类似JAVA中的Set集合。这些特性促使了用户在操作集合时没有办法通过索引去查找元素,也没有办法去获取一个范围之内的值。与List一样,redis规定一个集合类型中最多可以存储2^23-1个元素,同时集合还支持交集、并集、差集,功能颇多。
往集合中插入元素
sadd key value [value]
删除集合中的元素
srem key value
查询一个集合中的元素的个数
scard key
判断一个元素于一个集合中存在与否
sismember key value
随机在集合中获取想要个数的元素(默认是一个)
srandmember key [count]
随机在集合中弹出想要个数的元素(默认是一个)
spop key [count]
查询一个集合中所有的元素
smembers key
对两个集合做交集计算
sinter first_key second_key
对两个集合做并集计算
sunion first_key second_key
对两个集合做差集计算
sdiff first_key second_key
将两个集合交\并\差集的计算结果存入另一个键中
sinterstore store_key first_key second_key sunionstore store_key first_key second_key sdiffstore store_key first_key second_key
Hash可以是哈希,字典,也可以是关联数组。在redis中,哈希类型指值是一个键值对结构,这有点套娃,不知道为什么笔者总感觉其值很像JSON对象。哈希类型中的映射关系叫作field-value,这里的value是指值中field对应的值,可不敢是键的值。笔者认为Hash特点适合去存储对象,当然String类型也可以去存储对象的信息,但是你说一个人的特征拆成块,放到大海中,需要的时候去寻找,你就不怕男变女吗? Hash中键可以存储多个field-value,每个field不能相同,field与value映射,这就很好地把一个对象兜起来了。
插入数据
hset key field value [field value]
根据field取出值
hget key field
批量插入数据
hmset key field value [key field value]
根据field批量取出数据
hmget key field [field]
根据field删除数据
hdel key field [field]
查看哈希类型所有的field
hkeys key
查看哈希类型所有的value
hvals key
判断field是否存在
hexists key field
获取哈希所有的field-value
hgetall key
Zset与Set相似,一样是集合,集合中的元素不能够相同,但是不同的是有序集合的每一个元素都有自己的分数,所以有序集合可以根据分数来进行排序,这也说明我们能够以索引/分数的方式获取到一个或者一个范围中的值。在实际的开发中,有序集合给我们提供了分数查询,范围查询,事物排行榜的功能。
尽管有序集合中,元素不能够相同,但是各元素的分数是能够相同的!拜托!你是你我是我,又不是抄你试卷,为什么分数不能一样呢?
往有序集合中添加元素
zadd key score value [score value]
删除有序集合中的元素
zrem key value
计算有序集合中元素的个数
zcard key
计算某个元素的分数
zscore key value
查询某个元素的排名
zrank key value zrevrank key value//倒序排名
获取指定排名的元素
zrange key start end zrange key start end withscores zrevrange key start end zrevrange key start end withscores
有序集合是按照分数的高低来排名的,所以zrange命令获取的是一份从低到高的排行榜,zrevrange反之,而后面带着withscores命令的,在展示排行榜的时候会带上每一个元素的分数。
为指定元素增加指定分数
zincrby key value score
根据分数的范围获取指定范围的元素
zrangebyscore key min max [withscores] zrevrangebyscore key max min [withscores]
其中min、max支持开区间,闭区间,而-inf和+inf分别代表无穷小和无穷大。
示例:
有序集合的交\并\差集计算
zinterstore store_key num_key actual_key [actual_key] zunionstore store_key num_key actual_key [actual_key] zdiffstore store_key num_key actual_key [actual_key]
此计算与集合的计算一致,多了个num_key,其实就是你要计算的键的数量,相较于集合来说便是一次可计算多个键。
所谓的跳跃表便是不循环地遍历每个节点,而是跳跃形式地搜查,如果搜查到的节点比要找的节点要小的话便继续跳跃搜查,如果要大的话,便转换到下一层的搜查,直到找到为止,这比ziplist的查找减少了次数,提高了查找的效率。