【问题标题】:Checking if a value exists in a list already Redis检查列表中是否已经存在值 Redis
【发布时间】:2012-02-16 14:16:52
【问题描述】:

我想知道是否有办法检查一个键是否已经存在于 redis 列表中?

我不能使用集合,因为我不想强制唯一性,但我确实希望能够检查字符串是否确实存在。

【问题讨论】:

    标签: redis


    【解决方案1】:

    您的选择如下:

    1. 使用LREM 并在找到时替换它。
    2. 与您的LIST 一起维护一个单独的SET
    3. 循环遍历LIST,直到找到该项目或到达终点。

    Redis 列表被实现为 http://en.wikipedia.org/wiki/Linked_list,因此存在局限性。

    我认为您最好的选择是保持重复的SET。这是我倾向于做的事情。只需将其视为一个额外的索引。无论如何,请确保您的操作是使用 MULTI-EXEC 或 Lua 脚本的原子操作。

    【讨论】:

    • @fritzy 能否详细说明如何实现 SET/LIST 或指出我的某个地方,谢谢。
    • 由于 LREM 和 SREM 都是 O(N),所以最好不要单独设置(当然,除非您计划删除整个集合而不是逐项删除)。
    • 确实使用SET
    • @kristen LREM 是 O(N),其中 N 是列表的长度,但 SREM 1 个元素的复杂度是 O(1),因为 N 是要删除的成员数. SISMEMBER 总是 O(1)。
    【解决方案2】:

    列表允许重复,但不提供检查是否存在的简单方法,正如@Fritzy 建议的那样,您需要:

    • 进行多项操作(如果在删除过程中发现,则删除然后再次添加)以进行简单检查 = 时间成本
    • 维护一个单独的集合 = 内存成本

    我很惊讶没有人建议您使用 Hash TableSorted Set,它们结合了 允许重复的优点(通过将元素的数量存储为值-哈希表,或分数-排序集)和索引成员的性质一个哈希表/集合。


    哈希表

    要检查密钥是否存在,请使用HEXISTS 指定特定字段,如果指定成员不存在则返回0。 你也可以使用HGETcommand。如果指定的成员不存在,则返回nil 答案。

    要添加新成员,只需使用HINCRBY 即可更新值(即具有成员名称的元素的数量)或创建新成员(如果不存在)。


    排序集

    要检查密钥是否存在,请使用以下三个命令之一:

    • ZSCORE
    • ZRANK
    • ZREVRANK

    如果指定的成员不存在,它们会返回 nil 答案。

    要添加新成员,只需使用ZINCRBY 即可更新分数(即具有成员名称的元素的数量)或创建新成员(如果不存在)。


    总而言之:排序集哈希表允许您根据您的要求使用单个命令进行所有操作。。 p>

    【讨论】:

    • 但是,如果有人使用排序集,则无法确定这些值的多个实例在列表中的确切位置。如果我在列表中的任意位置有值“Hello World”,那么仅存储它出现的次数并不能帮助我定位这些实例的周围元素。
    • @AnuraagVaidya 这是另一个问题,与当前回答已提出问题的上下文无关。
    【解决方案3】:

    我很惊讶没有人提到 set,它完美地解决了这个问题。
    使用 set 中的 sismember 键值,它会检查该值是否是键的成员。
    示例如下:

    redis 127.0.0.1:6379> SADD myset1 "hello"
    (integer) 1
    redis 127.0.0.1:6379> SISMEMBER myset1 "hello"
    (integer) 1
    redis 127.0.0.1:6379> SISMEMBER myset1 "world"
    (integer) 0
    

    【讨论】:

    • “没有人提到这一套”。除了提问者,就是这样。
    【解决方案4】:

    您也可以使用LPOS

    当项目存在时,它返回一个指示位置的数字:

    LPOS mylist myitem
    3
    

    如果不返回nill:

    LPOS mylist myitem_which_do_not_exits
    (nil)
    

    【讨论】:

      【解决方案5】:

      不,没有办法检查 redis 列表是否包含给定值。参考Redis list commands

      我猜您可以使用LREM 来(尝试)删除该值,并检查返回值是否已删除。但是你必须把它放回去,这看起来很可疑。您的问题可能有更好的解决方案 - 您想要完成什么?

      【讨论】:

      • 你好 linus,我猜他是在问“钥匙”是否存在。不是您假设的给定值
      • @babydudecoder 他说他想检查一个key是否已经存在于redis列表中。我认为他的键是redis列表的值。
      • @Harry 在大多数情况下,他似乎可以将列表替换为hset - 并使用setnx,当然这与拥有真实列表并不完全相同,但哈希表是无论如何,通常查找速度更快。
      猜你喜欢
      • 2011-04-23
      • 2012-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-21
      相关资源
      最近更新 更多