【问题标题】:Redis GET vs. SQL SELECTRedis GET 与 SQL SELECT
【发布时间】:2013-06-02 19:43:14
【问题描述】:

我对 NoSQL 很陌生,但我一直很喜欢它的想法。我查看了Redis,并收到了一些关于存储和接收多个hashes 的最佳方式的问题。

假设如下场景:

Store a list of objects (redis 'Hashes') and select them by their timestamp.

要将其归档到 SQL,需要一个表和两个简单​​查询(INSERT 和 SELECT)。

尝试在Redis 中执行此操作,我最终创建了以下结构:

  1. 密钥object:$id(hash)包含object
  2. index:timestamp:$id(sorted set) score 等于 timestampvalue 包括 id

虽然我可以忍受两个键而不是一个表(SQL)的额外维护工作,但我对选择多个对象的过程感到好奇:

ZRANGEBYSCORE index:timestamp:$id timestampStart timestampEnd

这将返回在timestampStarttimestampEnd 之间创建的所有ID 的array。为了获得对象本身,我通过以下方式请求每个对象:

GET object:$id 
  • 这是正确的做法吗?
  • 与 SQL 数据库相比:由于GETs 的数量过多,它是否仍然明显更快,甚至可能变得更慢?

【问题讨论】:

    标签: nosql redis


    【解决方案1】:

    ZRANGEBYSCORE 的成本为 O(log(N) + M),其中 N=|items in your set|M=|items you're selecting|。因此,执行 ZRANGEBYSCORE 然后 M GET 操作只是 O(long(N)+M+M) = O(log(N)+M) 并且最多会慢两倍。网络来回可能会大大减慢速度,但是由于您的每个获取都是独立的操作,因此您可以将它们流水线化。你也可以把整个东西放在一个 Lua 脚本中,然后只用一个来回,这将是最优化的。我有 99% 的把握说这比在 SQL 中做同样的事情要快。

    另外,如果这对您来说是一个非常频繁的操作,您可以通过将整个对象存储在排序集中而不是仅存储 id 来获得更快的速度。你会有key = object encoded as jsonscore = timestamp。就不需要做任何GETs 而言,这将为您节省O(M) 的操作。

    这是否是一种好的做事方式实际上取决于您的用例。您真正需要多少速度,传统数据库的其他功能对您来说有多重要?请记住,与传统数据库相比,Redis 更像是客户端可访问的数据结构,它必须将所有内容存储在 RAM 中。要知道这是否适合您,我们需要更多信息。

    【讨论】:

    • 非常感谢您为此答案所做的工作!你刚刚向我介绍了 Lua 脚本,所以我会读到它。我还想将整个object 存储在sorted set 中,但话又说回来:如果我必须使用多个索引怎么办?据我所知,Redis 将使用两倍的空间,因为每个索引都将包含整个对象,而 Redis 无法在它们之间链接!?
    • 我以为您只是按一个时间戳进行索引。是的,如果有很多索引,它会使用更多的空间。额外的空间是否值得牺牲速度真的取决于您的用例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-04
    • 2012-01-23
    • 2018-01-26
    • 1970-01-01
    • 2020-11-03
    • 2011-01-21
    • 2014-11-26
    相关资源
    最近更新 更多