redis实现分页
Posted two-bees
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了redis实现分页相关的知识,希望对你有一定的参考价值。
redis实现分页功能,主要是将数据缓存起来,无需频繁查询数据库,减少数据库的压力。
适用场景:单用户操作列表界面分页,如博客列表。
缺点:不可模糊查询,缺少灵活性。
封装类:
class XgRedis { protected $_redis; public function __construct($hash_prefix=‘‘){ $this->_redis = connectRedis::getinstance();; //$this->_redis = Redis::connection(); } /* * 添加记录 * @param $hash_prefix 前缀 * @param $id 记录id * @param $data 数据 * @return bool 返回值 */ public function set_redis_page_info($hash_prefix,$id,$data){ if(!is_numeric($id) || !is_array($data)) return false; $hashName = $hash_prefix.‘_‘.$id; //同时设置 hash 的多个 field,已存在会自动更新 $this->_redis->hmset($hashName, $data); //添加元素到有序集合,元素在集合中存在则更新对应的score(权)(key,权,值) $this->_redis->zadd($hash_prefix.‘_sort‘,$id,$id); return true; } /* * 获取分页数据 * @param $hash_prefix 前缀 * @param $page 当前页数 * @param $pageSize 每页多少条 * @param $hashName Hash 记录名称 * @param $SortName Redis SortSet 记录名称 * @param $redis Redis 对象 * @param $key 字段数组 不传为取出全部字段 * @return array */ public function get_redis_page_info($hash_prefix,$page,$pageSize,$key=array()){ if(!is_numeric($page) || !is_numeric($pageSize)) return false; $limit_s = ($page-1) * $pageSize; $limit_e = ($limit_s + $pageSize) - 1; //类似lrange操作从集合中去指定区间的元素,返回的是带有 score 值(可选)的有序结果集: $range = $this->_redis->zrange($hash_prefix.‘_sort‘,$limit_s,$limit_e); //统计ScoreSet集合元素总数 $count = $this->_redis->zcard($hash_prefix.‘_sort‘); $pageCount = ceil($count/$pageSize); //总共多少页 $pageList = array(); foreach($range as $qid){ if(count($key) > 0){ $pageList[] = $this->_redis->hmget($hash_prefix.‘_‘.$qid,$key); //获取hash表中的field所有的数据 }else{ $pageList[] = $this->_redis->hgetall($hash_prefix.‘_‘.$qid); //获取hash表中所有的数据 } } $data = array( ‘data‘=>$pageList, //需求数据 ‘page‘=>array( ‘page‘=>$page, //当前页数 ‘pageSize‘=>$pageSize, //每页多少条 ‘count‘=>$count, //记录总数 ‘pageCount‘=>$pageCount //总页数 ) ); return $data; } /* * 获取单条记录 * @param $id id * @return array */ public function show_redis_page_info($hash_prefix,$id){ $info = $this->_redis->hgetall($hash_prefix.‘_‘.$id); return $info; } /* * 删除记录 单条或多条 * @param $ids ids 数组形式 [1,2,3] * @param $hashName Hash 记录名称 * @param $SortName Redis SortSet 记录名称 * @param $redis Redis 对象 * @return bool */ public function del_redis_page_info($hash_prefix,$ids){ if(!is_array($ids)) return false; foreach($ids as $value){ $hashName = $hash_prefix.‘_‘.$value; $this->_redis->del($hashName); $this->_redis->zrem($hash_prefix.‘_sort‘,$value); } return true; } /* * 清空数据 * @param string $type db:清空当前数据库 all:清空所有数据库 * @return bool */ public function clear($type=‘db‘){ if($type == ‘db‘){ $this->_redis->flushdb(); }elseif($type == ‘all‘){ $this->_redis->flushall(); }else{ return false; } return true; } /* * 入栈单条数据,针对某个用户可以,多用户并发就不好了 * @param $hash_prefix 前缀 * @param $data 数据 * @return bool 返回值 */ public function in_data($hash_prefix,$data){ if(count($data) != count($data,1)) echo ‘须为一维数组‘;return false; if(!is_array($data)) return false; //统计ScoreSet集合元素总数 $id = $this->_redis->zcard($hash_prefix.‘_sort‘); $hashName = $hash_prefix.‘_‘.$id; //同时设置 hash 的多个 field,已存在会自动更新 $this->_redis->hmset($hashName, $data); //添加元素到有序集合,元素在集合中存在则更新对应的score(权)(key,权,值) $this->_redis->zadd($hash_prefix.‘_sort‘,$id,$id); return true; } }
连接redis:
class connectRedis { static $redis_port = ‘6379‘; static $redis_host = ‘127.0.0.1‘; private function __construct() { } static public $instance; static public function getinstance() { if (!self::$instance) self::$instance = new self(); try { $redis = new Redis(); $redis->connect(static::$redis_host, static::$redis_port); } catch (Exception $e) { die(‘RedisException : Can\‘t connect to ‘ . static::$redis_host . ‘:‘ . static::$redis_port); } return $redis; } }
连接数据库:
class connectVboxDb{ static $db = ‘demo‘; static $host = ‘192.168.1.20‘; static $pdo; private function __construct(){ $pdo = new PDO(‘mysql:host=‘.static::$host.‘;dbname=‘.static::$db,‘root‘,‘Aaa2019.cn‘); $pdo->query(‘set names utf8‘);//设置字符集 static::$pdo = $pdo; } static public $instance; static public function getinstance(){ if(!self::$instance) self::$instance = new self(); return self::$instance; } static public function fetchAll($sql){ $qry = static::$pdo->query($sql); $rst = $qry->fetchAll(PDO::FETCH_ASSOC); return $rst; } }
index:
require_once(‘../connectRedis.php‘); require_once(‘xgredis.php‘); require_once(‘../../connectVboxDb.php‘); $XgRedis = new XgRedis(); connectVboxDb::getinstance(); $post = connectVboxDb::fetchAll(‘select * from PaydayCardOrder‘); $key_name = ‘PaydayCardOrderList‘; //var_dump($post);die; foreach ($post as $k => $v) { //将每条数据信息存储起来,这里key是数组key,信息后期有添加可以入栈添加,不影响其他信息, $XgRedis->set_redis_page_info($key_name, $k, $v); } //$XgRedis->in_data($key_name,$post[0]); //var_dump($XgRedis->del_redis_page_info($key_name,[52,53])); var_dump($XgRedis->get_redis_page_info($key_name, 1, 100)); //var_dump($XgRedis->show_redis_page_info($key_name,0));
总结:redis做为缓存工具使用,
① 定义的key要简洁明了,不可过长。
② 无用数据要及时清除掉,防止服务器内存过大。清除的时候,建议设置过期时间,防止当前有其他用户使用。
③ 更新缓存数据,应当先更新数据库,再更新redis缓存,防止并发下出现脏数据。
当然网上很多也很全,自己整理的先就这些。
以上是关于redis实现分页的主要内容,如果未能解决你的问题,请参考以下文章