不太推荐LS用HASH来存储点赞的数据. 因为没办法进行排序(如果需要的话. 我想一定需要)
目前 我们是这样处理的.
可以使用ZSET有序集合进行存储. 理论上说一个ZSET中, 10W以内的数量并无任何鸭梨. 也就是说一条微博点赞的人数再10W以内(这是不可能的).
$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这样的数据库来存储类似微博的数据的话, 可以这样存储:).
$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($tid as $key=> $value){
$pipe->GET("t:$value");
}
$list = $pipe->EXEC();
//$list就是你的数据啦
再再PS一下, 微博评论也是类似的存储方法. 只是需要约定$redis KEYS的名称. 比如:
c:<评论ID> 怎么和微博数据关联起来可以这样:
t:$tid:comments:scores (ZSET timestmap 评论ID);
这样取数据的时候就用PIPELINE方便很多了.
最后啰嗦一句, NOSQL这种数据库的 KEY 一定要设置好.
时间: 2024-11-08 05:51:45