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数字格式化
Dec 06 PHP
php下检测字符串是否是utf8编码的代码
Jun 28 PHP
PHP 模拟$_PUT实现代码
Mar 15 PHP
PHP中register_globals参数为OFF和ON的区别(register_globals 使用详解)
Feb 05 PHP
php读取二进制流(C语言结构体struct数据文件)的深入解析
Jun 13 PHP
页面乱码问题的根源及其分析
Aug 09 PHP
ThinkPHP实现事务回滚示例代码
Jun 23 PHP
php简单实现无限分类树形列表的方法
Mar 27 PHP
最准确的php截取字符串长度函数
Oct 29 PHP
Yii2增删改查之查询 where参数详细介绍
Aug 08 PHP
解决微信授权回调页面域名只能设置一个的问题
Dec 11 PHP
如何在PHP中使用数组
Jun 09 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制作简单的内容采集器的原理分析
2008/10/01 PHP
javascript天然的迭代器
2010/10/29 Javascript
ExtJS4 动态生成的grid导出为excel示例
2014/05/02 Javascript
javascript实现在某个元素上阻止鼠标右键事件的方法和实例
2014/08/12 Javascript
jQuery实现不断闪烁文字的方法
2015/05/15 Javascript
浅谈Javascript实现继承的方法
2015/07/06 Javascript
swtich/if...else的替代语句
2015/08/16 Javascript
jQuery fancybox在ie浏览器下无法显示关闭按钮的解决办法
2016/02/19 Javascript
基于MVC+EasyUI的web开发框架之使用云打印控件C-Lodop打印页面或套打报关运单信息
2016/08/29 Javascript
windows 下安装nodejs 环境变量设置
2017/02/02 NodeJs
微信小程序 图片加载(本地,网路)实例详解
2017/03/10 Javascript
React简单介绍
2017/05/24 Javascript
vue2组件之select2调用的示例代码
2017/10/12 Javascript
教你搭建按需加载的Vue组件库(小结)
2019/07/29 Javascript
JS实现使用POST方式发送请求
2019/08/30 Javascript
vue插件--仿微信小程序showModel实现模态提示窗功能
2020/08/19 Javascript
python3实现短网址和数字相互转换的方法
2015/04/28 Python
Python实现基于多线程、多用户的FTP服务器与客户端功能完整实例
2017/08/18 Python
深入理解Python中range和xrange的区别
2017/11/26 Python
Python3 XML 获取雅虎天气的实现方法
2018/02/01 Python
python实现超市管理系统(后台管理)
2019/10/25 Python
python 计算概率密度、累计分布、逆函数的例子
2020/02/25 Python
pycharm中import呈现灰色原因的解决方法
2020/03/04 Python
python读取excel进行遍历/xlrd模块操作
2020/07/12 Python
毕业生如何写自荐信
2014/03/26 职场文书
怀念母亲教学反思
2014/04/28 职场文书
党员干部廉洁承诺书
2014/05/28 职场文书
教师专业自荐信
2014/05/31 职场文书
小学学习雷锋活动总结
2014/07/03 职场文书
学习三严三实对照检查材料思想汇报
2014/09/22 职场文书
四风问题自我剖析材料
2014/10/07 职场文书
党的群众路线教育实践活动学习计划
2014/11/03 职场文书
2015年社区工会工作总结
2015/05/26 职场文书
Python中X[:,0]和X[:,1]的用法
2021/05/10 Python
MySQL定时备份数据库(全库备份)的实现
2021/09/25 MySQL
openEuler 搭建java开发环境的详细过程
2022/06/10 Servers