最好的方法是使用Redis存储索引的索引吗?

时间:2019-05-15 03:52:09

标签: node.js database indexing 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>"

添加第二个用户时,“ role”字段的值也为“ worker”,这就是数据库的样子:

// 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只会添加到字符串数组中。但是,此方法意味着每当添加新用户时,字符串数组都将被覆盖。这使我相信同时进行的请求只会相互覆盖,从而导致不良结果。


您怎么看?有更好的设计来解决这个问题吗?

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

1 个答案:

答案 0 :(得分:0)

我最终做了一遍解决方案#1,并且效果很好。我没有设置index: true,而是从头开始自动创建二级索引。

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

相关问题