redis数据结构
redis的五种数据结构
字符串、哈希、列表、集合、有序集合。
字符串
常用命令
- nx:key不存在 操作成功 用于新增操作
- setnx: 当key不存在时才能够设置成功,可以用于实现分布式锁
- xx:key存在 操作成功 用于更新操作
- mset: 批量设置
- mget: 批量获取
- 批量操作不是无节制的,过多的批量操作可能导致redis或网络阻塞
- incr: 自增操作
- 返回结果
- 值不是整数,返回错误。
- 值为整数,返回自增结果
- 值不存在,从0开始自增 也就是对一个不存在的值做自增操作 返回1
- 返回结果
- incrby:(指定自增数字)、incrbyfloat(自增浮点数 redis 2.6引入)
内部编码
查看编码命令:object encoding key
- int: 8字节的长整型
- embstr:小于等于39字节的字符串
- raw: 大于39字节的字符串
哈希
常用命令
- 设置值
- hset key field value
- 提供hsetnx
- 返回结果
- 成功:1
- 失败:0
- 获取值
- hget key field
- 删除filed
- hdel key field[field…]
- 删除一个或多个field
- 返回结果
- 成功删除field的个数
- 计算field个数
- hlen key
- 判断field是否存在
- hexist key filed
- 返回结果
- 存在:1
- 不存在:0
批量操作
- 批量设置或获取 field-value
- hmget key field [field …]
- hmset key field value [field value …]
获取所有
- 获取所有fielde
- hkeys key
- 获取所有value
- hvals key
- 获取所有field-value
- hgetall
内部编码
- ziplist:
- 哈希类型元素小于hash-max-ziplist-entries配置(默认512)
- 所有的值都小于hash-max-ziplist-value时 (默认64字节)
- ziplist使用更加紧凑的结构实现多个元素的连续存储,内存节省优于hashtable
- hashtable:
- 当哈希类型无法满足zipList的条件时,redis会使用hashtable作为哈希内部实现,
- 读写效率下降,时间复杂度O(1);
列表
简介
- 最多存储2^32-1个元素
- 可以对列表两端插入弹出
- 可以获取指定索引下标的元素
- 列表是有序的且元素可重复
常用命令
- rpush
- 从右往左插入操作 从右边插入元素
- lpush
- 从左往右插入操作 从左边插入元素
- linsert key before|after xx value
- 在xx元素的前面或者后面插入元素
- lrang
- 指定获取索引范围的所有元素
- 左->右 下标为0到n-1
- 右->左 下标为-1到-n 取值时会包含end自身
- 注意
- lrang在列表两端的性能比较好,但是如果列表较大,获取列表中间范围的元素性能会变差。可以考虑二级拆分,或者使用redis3.2的quicklist内部编码实现。
- 指定获取索引范围的所有元素
- lindex
- 获取指定索引下标元素
- lindex listkey -1 :获取listkey的最后一个元素
- llen
- 获取列表长度
- lpop
- 左侧弹出
- rpop
- 右侧弹出
- blpop、brpop
- 阻塞式弹出
- blpop key [key …] timeout
- key [key …] : 多个列表的键
- timeout:阻塞时间
- 如果列表为空,等到阻塞时间timeout后返回,如果timeout=0,客户端一直阻塞下去
- 如果原本为空,在阻塞时间内添加了数据,客户端立即返回
- 如果列表不为空,客户端会立即返回
- 注意:
- brpop如果有多个键 她会从左至右遍历,一旦有一个键能弹出元素,客户端立即返回。
- 此时有一个客户端向正在操作的list2、list3分别插入元素,会先返回list2的元素,因为list2先有可以弹出的元素。
- ltrem
- 删除指定元素 会查找某个元素并进行删除
- ltrem key count value
- cout>0 从左往右 删除最多count个元素
- count<0 从右往左删除最多count绝对值个元素
- count=0,删除所有
- ltrim:按索引范围修剪列表,只保留start 到end下标的元素 其他都删除
- ltrim key start end
列表使用
- lpush+lpop 栈
- lpush+rpop 队列
- lpush+ltrim 有限集合
- lpush+brpop 消息队列
内部编码
- ziplist(压缩列表):
- 哈希类型元素小于hash-max-ziplist-entries配置(默认512)
- 所有的值都小于hash-max-ziplist-value时 (默认64字节)
- linked(链表):
- 当列表类型无法满足ziplist的条件是,redis会使用linkedlist作为列表的内部实现。
- quicklist:
- redis3.2以后引入了一种新的数据格式quicklist,所有节点都用quicklist存储,省去了临界条件的格式转换,获取中间范围的元素也可以高效的完成。
- 是linkedlist和ziplist的结合,仍旧可以看作一个双向列表,每个节点都是ziplist,也就是quicklist的每个节点ziplist都能够存储多个数据元素。
- push
- 如果当前的节点ziplist能够放入新元素,ziplist的大小没有超过(list-max-ziplist-size),那么直接调用ziplist函数压入。
- 如果当前的节点ziplist不能放入新元素,则新建一个quicklist节点,新数据插入到新的节点上。
集合
简介
- 最多存储2^32-1个元素,不能有重复成员,无序
- 支持集合内的增删改查,支持多个几个取交集、并集、差集。
常用命令
- 单个集合操作
- sadd
- 添加元素
- srem
- 删除元素
- scard
- 计算元素个数,时间复杂度O(1),不会遍历所有元素,直接使用redis内部变量
- sismember
- 判断元素是否在集合中
- 存在返回1
- 不存在返回0
- srandmember key [count]
- 随机返回count个元素(元素不会从集合中删除)
- 默认不指定的话count为1
- spop
- 从集合中随机弹出一个元素(元素会从集合中删除)
- 注意
- 3.2版本以后 spop也支持[count]
- 从集合中随机弹出一个元素(元素会从集合中删除)
- smembers:获取集合所有元素(无序的)
- 注意:
- smembers、hgetall、lrang 都属于比较重的命令,元素过多存在阻塞的可能性,可以使用sscan完成
- 集合间的操作
- sinter key[key …]
- 多个集合交集
- sunion key[key …]
- 多个集合并集
- sdiff key[key …]
- 多个集合差集
- sinterstore destination key [key…]
- 交集的结果保存 其他的结果保存类似 xxxstore destination key[key…]
- sinter key[key …]
内部编码
- intset(整数集合)
- 当集合中元素都是整数且元素个数小于set-max-inset-entries配置(默认512), reids会使用intset集合的内部实现减少内存的使用。
- hashtable(哈希表)
- 当集合类型无法满足intset的条件是,redis内部会使用hahshtable作为集合的内部实现。
使用场景
- 标签,获取用户的相同爱好标签,例如电商用户可以根据用户做不同类型的推荐。
- sadd
- 添加标签
- spop/srandmember
- 用于生成随机数 比如抽奖
- sadd+sinter
- 用于获取社交需求,获取共同好友,共同爱好什么的
- sadd
有序集合
简介
- 和集合相似,不同的是有序集合的元素可以排序,它给每个元素设置一个分数作为排序的依据。
常用命令
- 单个集合操作
- zadd key score member [score member …]
- 添加成员
- 注意
- nx:member 必须不存在才能设置成功 添加操作
- xx: member 必须存在才能操作 更新操作
- ch:返回此次操作后,有序几个元素和分数发生变化的个数
- incr:对score做增加,相当于后面介绍的zincrby
- zadd时间复杂度0(log(n))
- sadd的时间复杂度O(1)
- zcard key
- 计算成员个数
- zscore key member
- 计算某个成员的分数 如果成员不存在 返回nil
- zrank key member
- 计算成员的排名(初始值为0,从低到高,zrevrank反之)
- zrem key member
- 删除成员
- 返回成功删除个数
- zincrby key increment member
- 增加成员分数
- zrange key start end [withscores]
- 返回指定范围的成员
- 从高到低返回
- zrevrange反之
- [withscores]
- 会返回成员分数
- zrangebyscore key min max [withscores] [limit offset count]
- 按照分数从到高返回指定分数范围的成员
- zrevrangebyscore反之
- [withscores]
- 会返回成员分数
- [limit offset count]
- 限制输出的起始位置和个数
- zcount key min max
- 返回指定分数范围成员个数
- zremrangebyrank key start end
- 删除指定排名内的升序元素
- 删除第start到end名的成员(包括start和end排名的元素)
- zremrangebyscore key start end
- 删除指定分数范围的成员
- zadd key score member [score member …]
- 集合间的操作
- zinterstore destination numkeys key [key …] [weights weight [weight] …] [aggregate sum|min|max]
- destination:交集结果保存到这个键
- numkeys:需要做交集计算键的个数
- key [key …]:需要做交集计算的键
- [weights weight [weight] …]:每个键的权重,计算时,每个键中的每个member会将自己的分数乘以这个权重,权重默认为1
- aggregate sum|min|max:计算成员交集后,分数可以按照sum、min、max做汇总 默认sum
并集操作可以套用上面的用法
3.内部编码
ziplist(压缩列表):当集合元素小于zset-max-ziplist-entries(默认128),
每个元素的值小于zset-max-ziplist-entries(默认64字节)
可以有效的减少内存的使用。
skiplist(跳跃表):当ziplist条件不满足时,有序集合会使用skiplist作为内部实现,因此ziplist的读写效率会下降。
4.使用场景
各种排行榜(时间、播放量、获赞数)
- zinterstore destination numkeys key [key …] [weights weight [weight] …] [aggregate sum|min|max]
内部编码
- ziplist(压缩列表)
- 当集合元素小于zset-max-ziplist-entries(默认128),
- 每个元素的值小于zset-max-ziplist-entries(默认64字节)
- 可以有效的减少内存的使用。
- skiplist(跳跃表)
- 当ziplist条件不满足时,有序集合会使用skiplist作为内部实现。
使用场景
- 各种排行榜(时间、播放量、获赞数)