比如说有一个微博的TID是1。UID为1,2,3,4,5,6,7,8,9的用户都给这个微博点赞了。用redis缓存框架存储的话如何存储。微博可能有几十万个。如果用key->set(value)这种形式的话key是微博ID的标示value是[1,2,3,4,5,6,7,8,9]这种形式,这样的话有多少个微博就有多少个K-V存储。我想知道这样会有什么弊端吗?或者有什么更好的方法吗?
2 回答
繁花如伊
TA贡献2012条经验 获得超12个赞
不太推荐LS用HASH来存储点赞的数据.因为没办法进行排序(如果需要的话.我想一定需要)目前我们是这样处理的.可以使用ZSET有序集合进行存储.理论上说一个ZSET中,10W以内的数量并无任何鸭梨.也就是说一条微博点赞的人数再10W以内(这是不可能的).php$redis->ZADD("t:$tid:liked",time(),$uid);//$tid为你的微博ID,$uid为你的点赞人的UID//取出点赞的人(支持按照点赞时间来排序的哦:))..按照LSD的说的HASH取出来的值没有任何顺序的.$uids=$redis->ZREVRANGE("t:$tid:liked",$offset,$max,TRUE);//倒序取值$uids=$redis->ZRANGE("t:$tid:liked",$offset,$max,TRUE);//顺序取值//$offset和$max这样来算$pagesize=20;$offset=($page>1)?($page-1)*$pagesize:0;$max=($page*$pagesize)-1;//一次性取出所有的这样取.$total=$redis->ZCARD("t:$tid:liked");$uids=$redis->ZREVANGE("t:$tid:liked",0,$total-1,TRUE);//拿到的$uids是一个array哦..//判断一个用户是否点赞了这一来哦$redis->ZSCORE("t:$tid:liked",$uid);//取消赞这样来$redis->ZREM("t:$tid:liked",$uid);//批量取消某短时间内的点赞这样操作$redis->ZREMRANGEBYSCORE("t:$tid:liked",$start_timestamp,$end_timestamp);//诸如此类的操作,要比HASH强很多.恩再PS一下!!!如果需要用到NOSQL这样的数据库来存储类似微博的数据的话,可以这样存储:).php$pipe=$redis->MULTI(Redis::PIPELINE);$pipe->SET("t:$tid",json_encode($data))//json这种格式存储貌似有点废物.如果能想到更好的格式的话,不要用JSON,因为JSON太大了..比如MSGPACK这个个是就比JSON要好很多->ZADD("t:scores",time(),$tid);$pipe->EXEC();//PIPE这样的操作赞爆了.如果你的REDIS支持事务的话,PIPE就不是一个原子性的操作了//取出数据的话就很好取出了!!$tid=$reids->ZREVRANGE("t:scores",0,100);$pipe=$redis->MULTI(Redis::PIPELINE);foreach($tidas$key=>$value){$pipe->GET("t:$value");}$list=$pipe->EXEC();//$list就是你的数据啦再再PS一下,微博评论也是类似的存储方法.只是需要约定$redisKEYS的名称.比如:c:<评论ID>怎么和微博数据关联起来可以这样:t:$tid:comments:scores(ZSETtimestmap评论ID);这样取数据的时候就用PIPELINE方便很多了.最后啰嗦一句,NOSQL这种数据库的KEY一定要设置好.
添加回答
举报
0/150
提交
取消