dot Redis 8 来了——而且是开源的

了解更多

使用 Redis 进行索引

本文最初发布在 nosqlgeek.org

如果您关注我在 Twitter 上的新闻,那么您可能已经意识到我刚刚开始更多地使用 Redis。Redis (=Remote Dictionary Server) 被称为数据结构存储。这意味着我们不仅可以处理键值对(在 Redis 中称为字符串),还可以处理诸如哈希(哈希映射)、列表、集合或排序集合等数据结构。有关数据结构的更多详细信息,请参见此处

键值存储中的索引

对于纯粹的键值存储,您通常会通过应用一些 KV 存储模式来手动维护索引结构。这里有一些例子

  • 通过主键直接访问: 键本身在语义上是有意义的,因此您可以通过知道键的结构(通过使用键模式)来直接访问一个值。一个例子是通过知道用户的 id 来访问用户资料。键看起来像 ‘user::<uid>’。
  • 通过二级键进行精确匹配: KV 存储本身可以被视为一个巨大的哈希映射,这意味着您可以使用查找项来引用其他项。这为您提供了一种哈希索引。一个例子是通过用户的电子邮件地址查找用户。查找项的键为 'email::<email_addr>',其中值是用户的键。为了获取具有特定电子邮件地址的用户,您只需要对具有电子邮件前缀的键执行 Get 操作,然后对具有用户前缀的键执行另一个操作。
  • 通过二级键进行范围查询: 这在纯粹的 KV 存储中变得有点复杂。它们中的大多数允许您检索所有键的列表,但执行完整的“键空间扫描”效率不高(复杂度为 O(n),n=键的数量)。您确实可以通过将列表存储为值并通过在它们之间引用来构建自己的树结构,但在应用程序端维护这些搜索树通常不是您想做的事情。

Redis 的方法

那么 Redis 如何解决这些例子?我们正在利用数据结构(如哈希和排序集合)的力量。

通过主键直接访问

Get 操作的复杂度已经是 O(1)。Redis 也是如此。

通过二级键进行精确匹配

哈希(顾名思义)可以直接用来构建哈希索引,以支持精确匹配“查询”。访问 Redis 哈希中的条目的复杂度确实是 O(1)。这是一个例子

HMSET idx_email [email protected] user::dmaier
HMSET idx_email [email protected] user::mustermann
HGET idx_email [email protected]
"user::dmaier"

此外,Redis 哈希支持 HSCAN 等操作。这为您提供了一种基于游标的方法来扫描哈希。更多信息请参见此处

这是一个例子

HSCAN idx_email 0 match d*
1) "0"
2) 1) "[email protected]"
2) "user::dmaier"

通过二级键进行范围查询

排序集合可用于支持范围“查询”。 它的工作方式是我们使用我们要搜索的值作为分数(顺序号)。扫描这样一个排序集合的复杂度为 O(log(n)+m),其中 n 是集合中元素的数量,m 是结果集的大小。这是一个例子

ZADD idx_age 37 user::david
ZADD idx_age 9 user::philip
ZADD idx_age 36 user::katrin
ZADD idx_age 13 user::robin
ZADD idx_age 0 user::samuel
ZRANGEBYSCORE idx_age 0 10
1) "user::samuel"
2) "user::philip"

如果您添加 2 个具有相同分数的元素,则它们按字典顺序排序。这对非数值非常有趣。 ZRANGEBYLEX 命令允许您通过考虑字典顺序来执行范围“查询”。

模块

Redis 现在支持模块(自 v4.0 起)。模块允许您扩展 Redis 的功能。一个与此博客文章的主题完美匹配的模块是 RediSearch。 RediSearch 基本上为 Redis 提供了全文索引和搜索功能。它在幕后使用倒排索引。有关 RediSearch 的更多详细信息,请参见此处

这是一个来自 RediSearch 文档的非常基本的例子

FT.CREATE myIdx SCHEMA title TEXT WEIGHT 5.0 body TEXT url TEXT
FT.ADD myIdx doc1 1.0 FIELDS title "hello world" body "lorem ipsum" url "https://redis.ac.cn"
FT.SEARCH myIdx "hello world" LIMIT 0 10
1) (integer) 1
2) "doc1"
3) 1) "title"
2) "hello world"
3) "body"
4) "lorem ipsum"
5) "url"
6) "https://redis.ac.cn"

像往常一样,我希望您觉得这篇文章有用且内容丰富。欢迎反馈!