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+DBM的同学录程序(3)
Oct 09 PHP
那些年一起学习的PHP(一)
Mar 21 PHP
一个简洁的PHP可逆加密函数(分享)
Jun 06 PHP
探讨PHP使用eAccelerator的API开发详解
Jun 09 PHP
php对称加密算法示例
May 07 PHP
PHP5.3安装Zend Guard Loader图文教程
Sep 29 PHP
PHP 数据结构队列(SplQueue)和优先队列(SplPriorityQueue)简单使用实例
May 12 PHP
php文件操作之小型留言本实例
Jun 20 PHP
PHP安全下载文件的方法
Apr 07 PHP
Yii全局函数用法示例
Jan 22 PHP
快速解决PHP调用Word组件DCOM权限的问题
Dec 27 PHP
PHP全局使用Laravel辅助函数dd
Dec 26 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生成年月日下载列表的方法
2015/04/24 PHP
PHP简单处理表单输入的特殊字符的方法
2016/02/03 PHP
smarty的section嵌套循环用法示例
2016/05/28 PHP
datePicker——日期选择控件(with jquery)
2007/02/20 Javascript
Jquery + Ajax调用webService实例代码(asp.net)
2010/08/27 Javascript
JavaScript 操作键盘的Enter事件(键盘任何事件),兼容多浏览器
2010/10/11 Javascript
让你的博客飘雪花超出屏幕依然看得见
2013/01/04 Javascript
jquery中使用$(#form).submit()重写提交表单无效原因分析及解决
2013/03/25 Javascript
Javascript Web Slider 焦点图示例源码
2013/10/10 Javascript
javascript窗口宽高,鼠标位置,滚动高度(详细解析)
2013/11/18 Javascript
javascript学习笔记整理(概述、变量、数据类型简介)
2015/10/25 Javascript
[原创]jQuery常用的4种加载方式分析
2016/07/25 Javascript
简单几步实现返回顶部效果
2016/12/05 Javascript
防止重复发送 Ajax 请求
2017/02/15 Javascript
你可能不知道的前端算法之文字避让(inMap)
2018/01/12 Javascript
vue elementUI 表单校验的实现代码(多层嵌套)
2019/11/06 Javascript
jQuery实现消息弹出框效果
2019/12/10 jQuery
[01:23:45]DOTA2-DPC中国联赛 正赛 CDEC vs Dragon BO3 第一场 1月22日
2021/03/11 DOTA
介绍Python的@property装饰器的用法
2015/04/28 Python
深入解析Python中的urllib2模块
2015/11/13 Python
Django1.9 加载通过ImageField上传的图片方法
2018/05/25 Python
详解从Django Rest Framework响应中删除空字段
2019/01/11 Python
python调用c++ ctype list传数组或者返回数组的方法
2019/02/13 Python
selenium python 实现基本自动化测试的示例代码
2019/02/25 Python
在python 中split()使用多符号分割的例子
2019/07/15 Python
python3.7添加dlib模块的方法
2020/07/01 Python
Pytorch框架实现mnist手写库识别(与tensorflow对比)
2020/07/20 Python
美国最大的袜子制造商和零售商:Renfro Socks
2017/09/03 全球购物
丝芙兰波兰:Sephora.pl
2018/03/25 全球购物
优秀求职信范文分享
2014/01/26 职场文书
初中同学聚会感言
2014/02/11 职场文书
安全责任书模板
2014/07/22 职场文书
2014年度个人总结范文
2015/03/09 职场文书
2015年司机年终工作总结
2015/05/14 职场文书
Java后台生成图片的完整步骤
2021/08/04 Java/Android
微软Win11有哪些隐藏功能? windows11多个功能汇总
2021/11/21 数码科技