Redis 快速上手 - 常见数据结构和用法(二)

541 阅读8分钟

这是我参与8月更文挑战的第6天,活动详情查看:8月更文挑战

上一章介绍了 string, hash, list 三种数据结构,本章介绍剩余的 2 种 set, zset

我的 redis 系列,感兴趣的朋友也可以来看看

Redis 快速上手 - 安装配置

Redis 快速上手 - 常见数据结构和用法(一)

Set(集合)

Redis的Set是string类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。 Redis 中 集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。

用途:

  • 可以使用 Redis 集跟踪唯一的东西。想知道访问给定博客文章的所有唯一IP地址吗?每次处理页面视图时只需使用 SADD 即可。不用担心重复ip问题,因为集合会自动过滤。
  • Redis集合很好地表示关系。可以使用 Redis 创建一个标记系统,使用一个集合来表示每个标记。然后,可以使用 SADD 命令将具有给定标记的所有对象的所有id添加到表示该特定标记的集合中。也可以使用 SINTER 命令返回交集成员集合。
  • 可以使用集合使用 SPOP 或 SRANDMEMBER 命令随机提取元素。

命令总结:

添加元素

  • 向集合添加一个或多个成员
  • sadd key member [member...]

获取集合数据

  • 获取集合中的成员数量
  • scard key
  • 返回集合中所有的成员
  • smembers key
  • 返回集合中一个或多个随机元素,如果不指定,count默认为1
  • srandmembers key [count]

移除集合中的成员

  • 随机弹出集合中的一个元素
  • spop key
  • 移除集合中的一个或多个成员
  • srem key member [member...]

特殊操作

  • 判断集合中的某个成员是否存在
    • sismember key member
  • 移动集合中的成员
    • smove fromSet toSet member
    • 将成员从 fromSet 移动到 toSet
    • 如果成员不存在 fromSet,则移动操作失败
  • 迭代集合中的元素
    • SSCAN key cursor [MATCH pattern] [COUNT count]
    • cursor,游标
    • match,匹配的模式
    • count,从结果集返回多少个元素,默认 10
    • 示例用法: sscan mykey 0 MATCH hell* COUNT 10

集合运算

  • 返回第一个集合和其他集合之间的差集
    • sdiff key [key...]
    • 示例:sdiff k1 k2 k3 k4
      1. k1 和 k2 比较,确定所有在 k1 但不在 k2 的元素
      2. 上一步得到的数据集,暂命名为 temp,然后与 k3 进行比较,获取所有在 temp 中但不在 k3 中的数据集,用此数据集更新 temp 数据
      3. 重复上一步,用 temp 和 k4 比较,输出结果
    • 或者,可以这么理解, sdiff k1 k2 k3 k4,先求 k2, k3, k4 的并集,标记为 temp,然后输出在 k1 中但不在 temp 中的所有元素
  • 返回第一个元素和其他集合的差集,存储到指定的集合中
    • sdiffstore targetSet key [key]
    • sdiff 方法类似,最后会多出一步,将 temp 的数据,存储到指定的 set 中
  • 返回所有集合之间的交集
    • sinter key [key...]
    • 返回同时存在指定的集合中的全部元素
  • 返回所有集合的交集,并存储在指定的集合中
    • sinterstore targetSet key [key]
    • sinter 方法类似,最后会多出一步,将 temp 的数据,存储到指定的 set 中
  • 返回所有集合的并集
    • sunion key [key]
    • 返回存在指定 key 中的全部元素,会去除重复项
  • 返回所有集合的并集,并存在指定的集合中
    • sunionstore targetSet key [key...]
    • sunion 方法类似,最后会多出一步,将 temp 的数据,存储到指定的 set 中

sorted set(有序合集)

Redis 有序集合和集合一样也是 string 类型元素的集合,且不允许重复的成员。

不同的是每个元素都会关联一个 double 类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。

有序集合的成员是唯一的,但分数(score)却可以重复。

有了排序集,你可以:

  • 在一款大型在线游戏中,你可以选择一个排行榜,每当有新的分数被提交时,你就可以使用ZADD进行更新。可以轻松地使用ZRANGE获取顶级用户,还可以在给定用户名的情况下,使用ZRANK返回其在列表中的排名。同时使用ZRANK和ZRANGE,可以向用户显示与给定用户类似的分数。这些操作都非常快。
  • 排序集通常用于索引存储在Redis中的数据。例如,如果有许多表示用户的散列,那么可以使用一个已排序的集合,其中的元素以用户的年龄为得分,以用户的ID为值。因此,使用ZRANGEBYSCORE检索给定时间间隔的所有用户既简单又快速。

命令总结:

添加元素

  • 向有序集合添加一个或多个成员,若计划添加的成员存在,则更新其分数
  • zadd key score member [[score memeber]...]

获取集合数据

获取成员数

在命令中使用 [ 表示包括边界, ( 表示不包括边界

  • 获取集合中的成员数
    • zcard key
  • 获取指定分数区间的成员数,[min, max]
    • zcount key min max
    • 支持对 min, max 使用 (, [,不显示写会默认使用 [
  • 在有序集合中计算指定字典区间内成员数量
    • zlexcount key mix max
    • 示例:统计全部成员数
      • zlexcount key - +
      • -,可以理解为 set 的 0 下标
      • +,可以理解为 set 的最大下标
    • 示例:获取指定元素之间共有多少个
      • zadd name 0 a 1 b 2 c 3 d
      • zlexcount name [a [c
    • min, max 必须使用 (, [
获取分数/索引
  • 返回有序集中,成员的分数值
    • zscore key member
  • 返回有序集合中指定成员的排名,有序集成员按分数值递减(从大到小)排序
    • zrerank key member
  • 返回有序集合中指定成员的索引
    • zrank key member
获取集合成员
  • 通过索引区间返回有序集合指定区间内的成员
    • zrange key start end [WITHSCORES]
    • 返回下标从 start 到 end 的全部成员数据
    • [WITHSCORES],可选项,申明后返回结果会带上分数
    • end,结束的下标,特殊值 -1 表示结束下标为集合的最后一位
  • 返回有序集合中指定区间内的成员,通过索引,分数从高到低
    • zrevrange key min max [WITHSCORES]
    • 与命令 zrange 类似,但,是先对集合数据按分数从大到小排列,再跟 [min, max] 来返回数据
  • 通过字典区间返回有序集合的成员
    • zrangebylex key min max
    • 示例: zrangebylex key - +,会返回全部的成员
    • min, max 必须使用 (, [
  • 通过分数返回有序集合指定区间内的成员
    • zrangebyscore key min max [WITHSCORES] [LIMIT offset count]
    • 返回的结果会根据 score 进行升序排列,相同分数则会对 member 进行字典升序排列
    • 可选项为加上 偏移量+数据量 限制进行返回
    • 支持对 min, max 使用 (, [,不显示写会默认使用 [
  • 返回有序集合中指定分数区间内的成员,按分数从高到低排列
    • zrevrangebyscore key max min [WITHSCORES] [LIMIT offset count]
    • 和命令 zrangebyscore 类似,但会先对集合数据按分数从大到小排列,再按 [max, min] 进行返回

变更操作

  • 对指定的成员,为其分数加上增量 increment
    • zincrby key increment member
  • 移除有序集合中的一个或多个成员
    • zrem key member [member...]
  • 移除有序集合中给定的字典区间的所有成员
    • zremrangebylex key min max
    • min, max 必须使用 (, [
  • 移除有序集合中给定的排名区间的所有成员
    • zremrangebyrank key min max
  • 移除有序集合中给定的分数区间的所有成员
    • zremrangebyscore key min max
    • 支持对 min, max 使用 (默认效果为使用了 [,但显示写上会提示语法错误

集合运算

  • 计算给定的一个或多个有序集的交集并将结果集存储在新的有序集合 key 中
    • zinterstore targetZSet numKeys key [key...] [WEIGHTS weight [weight...]] [AGGREGATE SUM|MAX|MIN]
    • 给定 key 的数量必须以 numkeys 参数指定
    • 默认情况下,结果集中某个成员的分数值是所有给定集下该成员分数值之和
    • WEIGHTS,乘法因子,表示对应的 member 在做交集运算之前,需要对 score 乘以多少,默认为 1,顺序和前面的 key 顺序一直
    • AGGREGATE,表示做交集运算时,默认对 member 相同的数据做 score 相加操作,可选为 保留 最大|最小 score
  • 计算给定的一个或多个有序集的并集,并存储在新的 key 中
    • zunionstore targetZSet numsKey key [key...] [WEIGHTS weight [weight...]] [AGGREGATE SUM|MIN|MAX]
    • 特性和 zinterscore 一致,只是一个是求交集,一个是求并集

特殊操作

  • 迭代有序集合中的元素(包括元素成员和元素分值)
  • zscan key cursor [MATCH pattern] [COUNT count]
    • cursor,游标
    • match,匹配的模式
    • count,从结果集返回多少个元素,默认 10
    • 示例用法: sscan mykey 0 MATCH hell* COUNT 10

总结起来就是

对于 zset 中所有关于字典的 min, max 排序比较,需要显示的声明 (, [

对于分数和排名的比较操作,默认是包括边界的,需要的话,可以使用 ( 来排除边界

Redis HyperLogLog

Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。 但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。


为了保证 api 的准确性,我已经肝到吐了,好兄弟们不赏一个赞嘛~