PHP+redis实现微博的拉模型案例详解


Posted in PHP onJuly 10, 2019

本文实例讲述了PHP+redis实现微博的拉模型。分享给大家供大家参考,具体如下:

上回写了一篇推模型的内容,这回分享一篇拉模型的内容。

拉模型

拉模型就是展示微博的时候,获取自己的所有关注的人,然后从关注的人中拉取最新微博。

微博项目数据结构设计

user表设计

注册的时候将user数据写入redis中,key如下:

user数据的key
用户名=user:uesrid:$uesrid:username
密码=user:userid:$userid:password

还需要这样写一份,因为需要靠用户名来登录,这样就可以根据用户名来查询用户id。

user:username:userid:$userid

关注的人和粉丝设计

每个用户在产生关注的动作后,在redis中维护两个无序集合set,一个是following,一个是follower,following集合保存的是我关注的人,follower集合保存的是我的粉丝。注意是每个用户都要维护这样的两个集合,用userid来区别。

单条微博表设计

每条微博的信息用hash结构来存储,根据不同的微博id来区分,每条微博有如下信息:发布人id,发布人昵称,发布时间,微博内容。

拉取关注者微博表 设计

每个用户发布微博后,维护20条最新微博,并保存到有序集合sorted set中,用不同的userid来区分。

注意:有序集合的score用微博id,集合保存的也是微博id。

个人微博表

每个用户维护自己的微博,保存到链表中,只保存1000条,redis中只保存1000条微博数据,如果想查询更多,去数据库中查询。

个人已拉取表设计

每个用户在拉取微博后,将微博保存到已经拉取的表中,这个表是一个链表结构,最多保存1000条微博。

发布微博

首先将微博保存成hash结构,然后将微博保存到拉取表,还保存到个人微博表。

//1、保存微博
$conn = connredis();
$postid = $conn->incr('global:postid');
$conn->hmset('post:postid:'.$postid,['userid'=>$user['userid'],'username'=>$user['username'],'time'=>time(),'content'=>$content]);
//2、每个人维护20条最新微博,保存到有序集合中
$conn->zadd('starpost:userid:'.$user['userid'],$postid,$postid);
if($conn->zcard('starpost:userid:'.$user['userid']) > 20){
  $conn->zremrangebyrank('starpost:userid:'.$user['userid'],0,0);
}
//3、维护个人的1000条微博,保存到链表中
$conn->lpush('mypost:userid:'.$user['userid'],$postid);
if($conn->llen('mypost:userid:'.$user['userid']) > 1000){
  $conn->rpoplpush('mypost:userid:'.$user['userid'],'global:post');
}

展示微博

首先获取所有关注的人,获取上次拉取微博的位置,根据上次拉取的微博位置来拉取数据。然后给微博排序,设置新的拉取的位置,写入到已拉取表中,获取微博的详细内容,最后获取粉丝和关注数。进行展示即可。

//1、获取拉取对象
$stars = $conn->smembers('following:'.$user['userid']);//获取所有关注的人
$stars[] = $user['userid'];//需要拉取自己的微博
//2、获取上次拉取的位置
$lastpull = $conn->get('lastpull:userid:'.$user['userid']);
if(!$lastpull){
$lastpull = 0;
}
//3、拉取微博 
$latest = [];
foreach($stars as $star){
$latest = array_merge($latest,$conn->zrangebyscore('starpost:userid:'.$star,$lastpull+1,1<<32-1));
}
//4、给微博排序
sort($latest,SORT_NUMERIC);
//5、设置拉取的位置
if(!empty($latest)){
  $conn->set('lastpull:userid:'.$user['userid'],end($latest));
}
//6、写入到已拉取表中
foreach($latest as $l){
  $conn->lpush('receivepost:'.$user['userid'],$l);
}
$conn->ltrim('receivepost:'.$user['userid'],0,999);//至多显示1000条微博
//7、获取微博的详细内容
$postids = $conn->sort('receivepost:'.$user['userid'],['sort'=>'desc']);
$posts = [];
foreach($postids as $postid){
  $posts[] = $conn->hmget('post:postid:'.$postid,['userid','username','time','content']);
}
//8、获取粉丝和关注数
$fansnum = $conn->scard('follower:'.$user['userid']);
$follownum = $conn->scard('following:'.$user['userid']);

Q&A

如何保证拉取的数据时最新的?

在拉取的时候,将最近拉取的微博id保存到redis中,然后下次我们只需要去拉取比这次保存的微博id大的微博,就可以保证拉取的数据是之前没有拉取的。

如何拉取所有关注者的数据?

遍历关注者,然后拉取数据

假设拉取A关注者的微博1,4,5 B关注者2,3,但是他们的发布时间交错,怎么展示数据?

将所有关注者的最新微博都取出来,然后根据微博id进行排序。

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
收集的php编写大型网站问题集
Mar 06 PHP
win7+apache+php+mysql环境配置操作详解
Jun 10 PHP
解析yii数据库的增删查改
Jun 20 PHP
Ajax+PHP快速上手及简单应用说明
Jul 24 PHP
PHP中ini_set与ini_get用法实例
Nov 04 PHP
php 的反射详解及示例代码
Aug 25 PHP
PHP入门教程之操作符与控制结构流程详解
Sep 09 PHP
PHP页面跳转实现延时跳转的方法
Dec 10 PHP
php实现的二叉树遍历算法示例
Jun 15 PHP
ThinkPHP5 的简单搭建和使用详解
Nov 15 PHP
浅谈Laravel模板实体转义带来的坑
Oct 22 PHP
Laravel6.18.19如何优雅的切换发件账户
Jun 14 PHP
php解压缩zip和rar压缩包文件的方法
Jul 10 #PHP
PHP+redis实现微博的推模型案例分析
Jul 10 #PHP
实例分析10个PHP常见安全问题
Jul 09 #PHP
PHP批斗大会之缺失的异常详解
Jul 09 #PHP
PHP结合Redis+MySQL实现冷热数据交换应用案例详解
Jul 09 #PHP
PHP+Redis开发的书签案例实战详解
Jul 09 #PHP
使用composer命令加载vendor中的第三方类库 的方法
Jul 09 #PHP
You might like
PHP 数组基础知识小结
2010/08/20 PHP
php+ajax实现的点击浏览量加1
2015/04/16 PHP
php实现的任意进制互转类分享
2015/07/07 PHP
Yii2实现让关联字段支持搜索功能的方法
2016/08/10 PHP
php操作路径的经典方法(必看篇)
2016/10/04 PHP
PHP实现Unicode编码相互转换的方法示例
2020/11/17 PHP
js Date概念详细介绍
2013/11/22 Javascript
javascript制作sql转换为stringBuffer的小工具
2015/04/03 Javascript
js给selected添加options的方法
2015/05/06 Javascript
javascript排序函数实现数字排序
2015/06/26 Javascript
基于jquery实现全屏滚动效果
2015/11/26 Javascript
快速掌握Node.js中setTimeout和setInterval的使用方法
2016/03/21 Javascript
手机图片预览插件photoswipe.js使用总结
2016/08/25 Javascript
Vue异步组件使用详解
2017/04/08 Javascript
vue.js 图片上传并预览及图片更换功能的实现代码
2018/08/27 Javascript
微信小程序云开发 搭建一个管理小程序
2019/05/17 Javascript
vue实现商城秒杀倒计时功能
2019/12/12 Javascript
[52:00]2018DOTA2亚洲邀请赛 4.1 小组赛 A组加赛 LGD vs Optic
2018/04/02 DOTA
使用Python中PDB模块中的命令来调试Python代码的教程
2015/03/30 Python
python 添加用户设置密码并发邮件给root用户
2016/07/25 Python
Pycharm 操作Django Model的简单运用方法
2018/05/23 Python
Python3.5面向对象与继承图文实例详解
2019/04/24 Python
python Gunicorn服务器使用方法详解
2019/07/22 Python
详解Python在使用JSON时需要注意的编码问题
2019/12/06 Python
查看keras各种网络结构各层的名字方式
2020/06/11 Python
Canvas 文字碰撞检测并抽稀的方法
2019/05/27 HTML / CSS
为什么要优先使用同步代码块而不是同步方法?
2013/01/30 面试题
大四自我鉴定
2014/02/08 职场文书
申请任职学生会干部自荐书范文
2014/02/13 职场文书
大学中国梦演讲稿
2014/04/23 职场文书
学校安全防火方案
2014/06/07 职场文书
党员评议个人总结
2014/10/20 职场文书
2015银行年终工作总结范文
2015/05/26 职场文书
2016见义勇为事迹材料汇总
2016/03/01 职场文书
2019公司借款合同范本2篇!
2019/07/24 职场文书
2019年度政务公开考核工作总结模板
2019/11/11 职场文书