初入 Redis 向各位大神讨一个解决方案

2016-06-13 01:12:00 +08:00
 jsonfork

HTML 列表页面每条信息有一个顶、踩数的显示,这个要求显示实时,现在的实现是 HTML 加载完成,发送一个 ajax 到 PHP 然后 PHP 根据发送过来的 catid(栏目 ID) 和 ids(多条信息 id),来查表取信息中的顶、踩数。现在这样给数据库的压力比较大,想用一个中间层作为缓冲。 这个顶踩数用户可以点击,点击一次+1 ,每天只能点一次。

请求数据过来时参数是这样: catid=1 ids=1,2,4,5,6 :查栏目 id 等于 1 下的信息 id 为 1,2,3,4,5,6 的顶踩数 。 返回数据: { "1":{"like":10,"hate":1}, "2":{"like":66,"hate":10}, "3":{"like":238,"hate":90}, "4":{"like":100,"hate":11} }

1.点击顶踩数时做一个延时写入数据库,到一定量时才写入到数据。 2.这种结构怎么存储到 redis 里比较合理,栏目有很多。

各位大神给支个招!!

3738 次点击
所在节点    Redis
12 条回复
Mirana
2016-06-13 02:43:20 +08:00
可以用一个 hset,key 是 catid,value 是 json 序列化的 string
jsonfork
2016-06-13 08:19:44 +08:00
@Mirana 那如果修改某个值不是还要序列化和反序列化吗。有点麻烦。
tonghuashuai
2016-06-13 08:39:49 +08:00
第一种: hset , catid 为 key ,结构为:{‘ 1_like ’: 100, ‘ 1_hate ’: 90, ‘ 2_like ’: 20, ‘ 2_hate ’: 10, ....},不建议 key 中包含长字符串,所以可以用 0 代表 like , 1 代表 hate ,于是成为:{‘ 1_0 ’: 100, ‘ 1_1 ’: 90, ‘ 1_0 ’: 20, ‘ 1_1 ’: 10, ....}
第二种:直接用 catid_id_like 的形式,如: 1_1_like: 100 , 1_1_hate: 90 ,同样 0 代表 like , 1 代表 hate ,成为: 1_1_0: 100 , 1_1_1: 90

上面适合不同的 catid 下有相同的 item_id ,如果不同的 catid 下面的 item_id 不存在重复的,那么就简单了,第二种,并且 key 中去掉 catid ,表示为: id_like ,如: 1_like: 100 , 1_hate: 90 ,同样 0 代表 like , 1 代表 hate ,成为: 1_0: 100 , 1_1: 90

只是一种思路,具体细节根据 lz 情况自行调整。
lianxiaoyi
2016-06-13 09:47:24 +08:00
@jsonfork 做好封装你就不会有这种感觉了。。。。。。
jsonfork
2016-06-13 17:04:23 +08:00
@tonghuashuai 不同的 catid 下会有相同的 item_id 。还有一种方案:使用 hmset , catid 同样为 key ,结构为:{`1`:`100_102`,`2`:`10_22`,...} ,`1` 为 item_id ,`100_102` , 100 为 like , 102 为 hate ,这种结构怎么样,有没有什么问题。
tonghuashuai
2016-06-13 23:37:38 +08:00
@jsonfork
key value 的思想是唯一的 key 对应唯一的 value ,你这种方式叶能实现功能,但是 like 和 hate 操作都会更新同一个 key 的 value ,个人认为不太好,只是个人认为。
jsonfork
2016-06-14 08:36:24 +08:00
@tonghuashuai 嗯,用了第一种方式。 这样操作会方便些。 这个数据量如果大的话会有影响的吗。 就是意味着我们 10W 条数据,要产生 20W 的记录值。这样查询性能有影响吗。
tonghuashuai
2016-06-14 08:47:34 +08:00
@jsonfork
hash 数据结构的时间复杂度是 O(1),所以 hget hset 的时间复杂度都是 O(1),所以数据量不会影响性能。
jsonfork
2016-06-14 10:02:42 +08:00
@tonghuashuai OK, 谢谢老司机指路!!
caixu
2016-06-14 11:44:46 +08:00
我建议是使用 zset, member 是 id, score 是 like << 32 + hate
如果要 like zadd(id, 1<<32 + 1)
如果是 hate zadd(id, 1)

如果要批量获取 id 的 score 可以使用一个临时的 zset, 把 ids 放在这个 zset 总和原始数据进行 ZINTERSTORE:


使用 hget 的问题不是 hget 本身效率的问题. 是太多 round trip.
caixu
2016-06-14 14:08:21 +08:00
@caixu
纠正下:

如果要 like ZINCRBY(id, 1<<32 + 1)
如果是 hate ZINCRBY(id, 1)
jsonfork
2016-06-14 16:26:39 +08:00
@caixu 不太了解你说命令。看不怎么懂。 但是我发现你没有用到 catid ,因为我是用 catid 来做分类的, 每个 catid 下面会有相同的 item_id 。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/285252

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX