如何在redis中构建1级嵌套注释?
我一直在努力寻找嵌套评论的数据结构(只有1层的嵌套,例如脸书)如何在redis中构建1级嵌套注释?
为了实现评论的非嵌套“饲料”我一直在使用有序集跟踪评论,将评分作为时间戳和成员用作json编码的一组属性,其中包含呈现评论所需的所有信息。
所以添加注释可能是这样的:
zadd 'users:1:comments', 123456789, {body : 'hello'}
和检索它是如此简单:
zrevrange 'users:1:comments', 0, 20
为了支持嵌套评论我一直在努力,在这个扩大在某种程度上 我已经头脑风暴两种不同的方式,但每个都有问题:
1)
添加到COMMENT_ID属性的列表,COMMENT_ID指向父评论
zadd 'users:1:comments', 123456789, {id : 1, body : 'hello'}
zadd 'comments:1:comments', 123456789, {id : 2, body : 'nested hello', comment_id : 123 }
应该是这样的:
-hello
-nested hello
这种方法的问题是,当涉及到分页。如果评论有20个嵌套评论,而我只显示前10个评论,则嵌套树将被截断(父评论+ 9嵌套评论将被检索)
2)
把嵌套评论到它自己的饲料:
This is a parent comment
zadd 'users:1:comments', 123456789, {id: 1, body : 'hello'}
this is a nested comment
zadd 'comments:1:comments' 123456789, {id: 2, body : 'nested hello'}
然而,这将导致N + 1个Redis的查询试图显示用户的饲料时:
zrevrange 'users:1:comments', 0, 20
zrevrange 'comments:1:comments', 0, 20
zrevrange 'comments:2:comments', 0, 20
etc...
...不至 提到嵌套注释可能不应该用范围来选择。
理想情况下,我希望这可以与单个redis查询一起工作,但我不确定如何构建我的数据以便可能。
想法?
我能想出的唯一方法就是使用Lists来得到单个redis查询。
添加父项时,您可以将LPUSH
简单地置于列表的顶部(左侧)。当添加一个孩子的评论,你会使用像LINSERT 'user:1:comments' AFTER parent-comment-data child-comment-data
。
这会导致redis搜索父注释数据并将子数据立即放在其后面。这是一个O(N)操作,并在顶部(左侧)到底部(右侧)完成,因此父表的下一级父母是该操作需要的时间越长,因此对于极其长列表,这可能证明存在问题(但如果您将列表/线程大小保持在4或5位数范围内,应该没问题)。
然后,一个简单的LRANGE
可以获取最新的评论,父母和孩子,只限于任何数量。
您可以使用排序集中的分数值做类似的事情,给孩子的分数低于父母。不过,这可能会使插入操作复杂化,因为您可能会耗尽两个父注释之间的可用分数,这意味着您必须运行操作才能为许多(或甚至大部分)注释重新分配分数。如果每次插入都发生这种情况,您的插入可能会(不必要地)成本高昂。
很确定这不能解决我在原帖的#1中描述的分页问题。 – jsharpe