首页 > 解决方案 > 使用 Redis 存储索引的最佳方法?

问题描述

是的,这个问题令人困惑。如果你知道更好的方法来问我在问什么,请分享!

我正在使用 NodeJS 和 Redis 设计一个不可知的 REST API。服务器设置为索引模型规范中设置为这样做的任何字段。

前任:

// user object
{ 
  firstName: 'Peter',
  lastName: 'Boyd',
  role: 'worker'
}

现在,当添加用户时,被索引的字段是“角色”字段。数据库将如下所示:

// user objects stored as regular key
key: "users:<ID1>" | value: "{ ...userData }"

// "role" indexes stored as hash key
hash key: "users:role" | field: "worker" | value: "users:<ID1>"

当添加第二个用户时,“角色”字段的值也为“工人”,这就是数据库的样子:

// user objects stored as regular key
key: "users:<ID1>" | value: "{ ...userData1 }"
key: "users:<ID2>" | value: "{ ...userData2 }"

// "role" indexes stored as hash key (previous value gets replaced)
hash key: "users:role" | field: "worker" | value: "users:role:worker"

// "worker" value for "role" gets created as list
key: "users:role:worker" | value: [ "users:<ID1>", "users:<ID2>" ]

这样,除非为了节省空间而需要,否则不会创建二级索引。二级索引是一个保存用户对象键的列表。初始索引值保存此列表的键,因为它的值在本例中为“users:role:worker”。

这很好用,除非同时使用空数据库创建多个用户。这种索引设计不是无状态的,因此会导致奇怪的事情发生。

我的问题是,我该如何改进这个设计?我已经想到了几个解决方案,但它们都有一些缺点。

可能的解决方案#1

从头开始创建二级索引(带有“users:role:worker”键的列表)。然而,考虑到它会为每个具有索引的字段创建两个条目,这似乎会浪费空间,这通常是不必要的。

可能的解决方案#2

不是将 ID 存储为每个索引的值,而是存储 ID 的字符串数组。这将阻止创建该辅助列表。新的用户 ID 将被添加到字符串数组中。但是,此方法意味着无论何时添加新用户,都会覆盖字符串数组。这让我相信同时的请求只会相互覆盖,导致不想要的结果。


你怎么看?有没有更好的设计来处理这个问题?

非常感谢您的帮助和反馈!

标签: node.jsdatabaseindexingredis

解决方案


我最终做了一个扭曲的解决方案#1,并且效果很好。index: true我没有为这个特定字段设置模式规范,而是设置了一个deepIndex: true从头开始自动创建二级索引的方法。

这意味着任何可能在多个实例之间具有共享值的字段都将以这种方式“深度索引”。


推荐阅读