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中的一个中文字符串截取函数
Feb 14 PHP
怎样去阅读一份php源代码
Aug 21 PHP
php 无极分类(递归)实现代码
Jan 05 PHP
PHP5中使用DOM控制XML实现代码
May 07 PHP
一个比较不错的PHP日历类分享
Nov 18 PHP
详谈PHP编码转换问题
Jul 28 PHP
php对二维数组进行相关操作(排序、转换、去空白等)
Nov 04 PHP
php连接微软MSSQL(sql server)完全攻略
Nov 27 PHP
php实现36进制与10进制转换功能示例
Jan 10 PHP
php事务回滚简单实现方法示例
Mar 28 PHP
PHP实现的日历功能示例
Sep 01 PHP
PDO::lastInsertId讲解
Jan 29 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 5.0对象模型深度探索之属性和方法
2008/03/27 PHP
一道求$b相对于$a的相对路径的php代码
2010/08/08 PHP
基于PHP+Ajax实现表单验证的详解
2013/06/25 PHP
JS查看对象功能代码
2008/04/25 Javascript
JavaScript入门教程 Cookies
2009/01/31 Javascript
javascript URL编码和解码使用说明
2010/04/12 Javascript
浏览器脚本兼容 文本框中,回车键触发事件的兼容
2010/06/21 Javascript
jquery $.each 和for怎么跳出循环终止本次循环
2013/09/27 Javascript
JS常用字符串方法(推荐)
2021/01/15 Javascript
JavaScript高仿支付宝倒计时页面及代码实现
2016/10/21 Javascript
关于vue-router路径计算问题
2017/05/10 Javascript
基于Vue组件化的日期联动选择器功能的实现代码
2018/11/30 Javascript
详解JavaScript 新语法之Class 的私有属性与私有方法
2019/04/23 Javascript
vue中使用vee-validator完成表单校验方案
2019/11/01 Javascript
vue 使用lodash实现对象数组深拷贝操作
2020/09/10 Javascript
JavaScript实现通讯录功能
2020/12/27 Javascript
Vue页面渲染中key的应用实例教程
2021/01/12 Vue.js
vue浏览器返回监听的具体步骤
2021/02/03 Vue.js
[01:56]林书豪DOTA2上海特级锦标赛励志短片
2016/03/05 DOTA
Python中的MongoDB基本操作:连接、查询实例
2015/02/13 Python
pandas进行数据的交集与并集方式的数据合并方法
2018/06/27 Python
python3+selenium实现126邮箱登陆并发送邮件功能
2019/01/23 Python
python 变量初始化空列表的例子
2019/11/28 Python
Python二次规划和线性规划使用实例
2019/12/09 Python
PyTorch中topk函数的用法详解
2020/01/02 Python
Python数据结构dict常用操作代码实例
2020/03/12 Python
python pandas.DataFrame.loc函数使用详解
2020/03/26 Python
英国最受欢迎的价格比较网站之一:MoneySuperMarket
2018/12/19 全球购物
同学聚会老师邀请函
2014/01/28 职场文书
服务员岗位责任制
2014/02/11 职场文书
水利公司纪检监察自我鉴定
2014/02/25 职场文书
优秀班组长事迹
2014/05/31 职场文书
行政文员岗位职责
2015/02/04 职场文书
公司年会开场白
2015/06/01 职场文书
selenium.webdriver中add_argument方法常用参数表
2021/04/08 Python
新手初学Java List 接口
2021/07/07 Java/Android