是的,这个问题令人困惑。如果您知道问我要问的更好的方法,请分享!
我正在使用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”。
这很好用,除非同时使用空数据库创建多个用户。这种索引设计不是无状态的,因此会导致发生奇怪的事情。
我的问题是,如何改进此设计?我想到了几个解决方案,但是它们每个都有一些缺点。
从头开始创建二级索引(具有键“ users:role:worker”的列表)。但是,考虑到将为每个具有索引的字段创建两个条目,这似乎是浪费空间。
存储ID的字符串数组,而不是将ID作为每个索引的值存储。这将阻止创建该辅助列表。新的用户ID只会添加到字符串数组中。但是,此方法意味着每当添加新用户时,字符串数组都将被覆盖。这使我相信同时进行的请求只会相互覆盖,从而导致不良结果。
您怎么看?有更好的设计来解决这个问题吗?
非常感谢您的帮助和反馈!
答案 0 :(得分:0)
我最终做了一遍解决方案#1,并且效果很好。我没有设置index: true
,而是从头开始自动创建二级索引。
这意味着任何可能在多个实例之间共享值的字段都将以这种方式“深度索引”。