对于阻塞弹出命令和弹出并推入命令,最常见的用例就是消息传递(messaging)和任务队列(task queue),将在以后对这两个主题进行介绍。 P44
练习题:通过列表来降低内存占用 P44在上篇文章中,我们使用了有序集合来记录用户最近浏览过的商品,并把用户浏览这些商品时的时间戳设置为分值,从而使得程序可以在清理旧会话的过程中或是在执行完购买操作后,进行相应的数据分析。但由于保存时间戳需要占用相应的空间,所以如果分析操作并不需要用到时间戳的话,那么就没有必要使用有序集合来保存用户最近浏览过的商品了。为此,请在保证语义不变的情况下,将 UpdateToken 函数里面是用的有序集合替换成列表。
提示:如果在解答这个问题时遇上困难的话,可以到 6.1.1 节中找找灵感。
由于列表是有序的,所有最新访问的一定在列表的左端,所以每次操作时先删除列表中这个访问记录,再推入列表左端,最后修剪列表为长度为 25 即可。由于每次需要遍历整个列表,所以时间复杂度较高,但是列表长度总共只有 25 ,时间上相差不大,但是空间可以节省很多。
// 更新最近商品访问列表 func UpdateLatestViewedItem(conn redis.Conn, itemId int) { // 移除列表中所有值为 itemId 的元素 _ = conn.Send("LREM", "latestViewedItem", 0, itemId) // 将最近访问的商品推入列表最左端 _ = conn.Send("LPUSH", "latestViewedItem", itemId) // 修剪列表,保留最近访问的 25 个 _ = conn.Send("LTRIM", "latestViewedItem", 0, 24) // 执行上述命令 _ = conn.Flush() } 集合 P44 一些常用的集合命令 P45 命令 格式 描述SADD SADD key member [member ...] 将一个或多个元素添加到集合中,返回添加到集合中的新元素的数量(不包括已存在的元素)
SREM SREM keymember [member ...] 将一个或多个元素从集合中删除,返回成功从集合中删除的元素(不包括不存在的元素)
SISMEMBER SISMEMBER key member 判断元素 member 是否在集合 key 中
SCARD SCARD key 返回结合中元素的数量
SMEMBERS SMEMBERS key 返回集合的所有元素
SRANDMEMBER SRANDMEMBER key [count] 随机返回集合中一个或多个元素。count 为正数时,返回 count 个各不相同的元素(最多返回整个集合);count 为负数时,返回 |count| 个可能会重复的元素,无最长限制。
SPOP SPOP key 随机移除并返回集合中的一个元素
SMOVE SMOVE source destination member 将元素 member 从集合 source 移动到集合 destination 中
相关演示代码如下:
// 执行集合类型相关操作 func executeSetOperation(conn redis.Conn) { // 删除原有值 handleResult(redis.Int(conn.Do("DEL", "source", "destination"))) // 集合中添加三个元素,输出 -> 6,source 变为 -> 1 2 3 4 5 6 7 handleResult(redis.Int(conn.Do("SADD", "source", 1, 2, 3, 4, 5, 6, 7, 1))) // 从集合中删除两个元素: 1 2,输出 -> 2,source 变为 -> 3 4 5 6 7 handleResult(redis.Int(conn.Do("SREM", "source", 1, 2))) // 判断集合是否含有元素 3,输出 -> 1 handleResult(redis.Int(conn.Do("SISMEMBER", "source", 3))) // 返回集合的元素个数,输出 -> 5 handleResult(redis.Int(conn.Do("SCARD", "source"))) // 返回集合的所有元素,输出 -> [3 4 5 6 7] handleResult(redis.Ints(conn.Do("SMEMBERS", "source"))) // 随机返回集合中不同的 3 个元素,输出 -> [6 5 3] (随机结果可能存在不同,以实际为准) handleResult(redis.Ints(conn.Do("SRANDMEMBER", "source", 3))) // 随机返回集合中可重复的 6 个元素,输出 -> [7 5 6 3 7 6] (随机结果可能存在不同,以实际为准) handleResult(redis.Ints(conn.Do("SRANDMEMBER", "source", -6))) // 随机删除集合中的 1 个元素,输出 -> 3 ,source 变为 -> 4 5 6 7(随机结果可能存在不同,以实际为准) handleResult(redis.Int(conn.Do("SPOP", "source"))) // 移动 source 集合中的元素 7 到 destination 集合中(由于前面存在随机,结果可能存在不同,以实际为准) // 输出 -> 1 ,source 变为 -> 4 5 6 ,destination 变为 -> 7 handleResult(redis.Int(conn.Do("SMOVE", "source", "destination", 7))) } 用于组合和处理多个集合的命令 P45 命令 格式 描述SDIFF SDIFF key [key ...] 返回存在于第一个集合,而不存在于其他集合的元素(差集)
SDIFFSTORE SDIFFSTORE destination key [key ...] 将存在于第一个集合,而不存在于其他集合的元素(差集)存储到 destination 中,返回差集大小
SINTER SINTER key [key ...] 返回同时存在于所有集合中的元素(交集)
SINTERSTORE SINTERSTORE destination key [key ...] 将同时存在于所有集合中的元素(交集)存储到 destination 中,返回交集大小
SUNION SUNIONkey [key ...] 返回至少存在于一个集合中的元素(并集)
SUNIONSTORE SUNIONSTORE destination key [key ...] 将至少存在于一个集合中的元素(并集)存储到 destination 中,返回并集大小