2011-10-03 43 views
2

我一直在努力尋找嵌套評論的數據結構(只有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查詢一起工作,但我不確定如何構建我的數據以便可能。

想法?

回答

0

我能想出的唯一方法就是使用Lists來得到單個redis查詢。

添加父項時,您可以將LPUSH簡單地置於列表的頂部(左側)。當添加一個孩子的評論,你會使用像LINSERT 'user:1:comments' AFTER parent-comment-data child-comment-data

這會導致redis搜索父註釋數據並將子數據立即放在其後面。這是一個O(N)操作,並在頂部(左側)到底部(右側)完成,因此父表的下一級父母是該操作需要的時間越長,因此對於極其長列表,這可能證明存在問題(但如果您將列表/線程大小保持在4或5位數範圍內,應該沒問題)。

然後,一個簡單的LRANGE可以獲取最新的評論,父母和孩子,只限於任何數量。

您可以使用排序集中的分數值做類似的事情,給孩子的分數低於父母。不過,這可能會使插入操作複雜化,因爲您可能會耗盡兩個父註釋之間的可用分數,這意味着您必須運行操作才能爲許多(或甚至大部分)註釋重新分配分數。如果每次插入都發生這種情況,您的插入可能會(不必要地)成本高昂。

+0

很確定這不能解決我在原帖的#1中描述的分頁問題。 – jsharpe