講一下為什麼使用redis實現分頁
1.後端寫介面的時候 維護資料表的curd 快取key總要更新 這樣一來有一批key 未被使用 就被refresh 掉了
2.從許多表 跨庫查詢的時候 查詢出來的結果集 需要分頁的時候 再次查詢 耗時 增加了資料庫的負擔
下面說一下 實現思路 :把維護結果集中id 為分值 存入指定key 的有序集合中 這樣這個指定key的有序集合 就會維護一個按分值大小排序 的有序集合 值得注意的是這個有序集合 一定設定過期時間和長度 不然的話 無限長的集合和不過期 雖然redis裡 有過期設定 不過更喜歡代 碼掌握自己掌控範圍內
程式碼實現:
namespace app\Constants\Nomal;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Redis;
class RedisList{
// 新增一條資料到redis中
public function zAdd($key,array $value){
return Redis::zadd($key,$value);
}
// 從Redis返回一條資料
public function zRange($key,$start,$end,$withScores){
return Redis::zRange($key,$start,$end,$withScores);
}
// Redis 返回一條資料從大小返回資料
public function zrevRange ($key,$start,$end,$withScores){
return Redis::ZREVRANGE($key,$start,$end,$withScores);
}
// Redis 返回某個資料 按分數正序排序 //ZRANGEBYSCORE
public function zRangByScore($key,$start,$end,$withScores){
return Redis::ZRANGEBYSCORE($key,$start,$end,$withScores);
}
// Redis 返回資料按分數倒敘排序 // ZREVRANGEBYSCORE
public function zRevRangBySore($key,$start,$end,$withScores){
return Redis::ZREVRANGEBYSCORE($key,$start,$end,$withScores);
}
// 刪除某個成員的值
public function zRem($key,$member){
return Redis::zRem($key,$member);
}
// 返回zset集合中所有元素的個數
public function zSize($key){
return Redis::zcard($key);
}
// 返回比元素$member分數大的元素的個數
public function zRevRank($key,$member){
return Redis::zRevRank($key,$member);
}
// 如果在名稱為key的zset中已經存在元素member,則該元素的score增加increment;否則向集合中新增該元素,其score的值為increment
public function zIncrBy($key,$increment,$member){
return Redis::zIncrBy($key,$increment,$member);
}
// 求有序集合的並集
public function zUnion($output,$zsetkey){
return Redis::zUnion($output,$zsetkey);
}
//求有序集合的交集
public function zInter($output,$zsetkey){
return Redis::zInter($output,$zsetkey);
}
// redis 分頁處理
public function limitAndPage($pageIndex,$pageNum){
return array('pageIndex'=>$pageIndex-1,'pageNumber'=>$pageIndex*$pageNum-1);
}
// redis 佇列操作 入佇列
public function lPush($key,$value){
return Redis::LPUSH($key,$value);
}
// redis 根據索引取資料
public function lIndex($key,$position){
return Redis::lIndex($key,$position);
}
// redis list維護一個長度為100000的佇列
public function lTrim($key,$start=0,$stop=100000){
return Redis::lTrim($key,$start,$stop);
}
// 設定key的過期時間 現在設定的是一個月的時間 做二級快取使用
public function expire($key,$timesec =0){
if($timesec == 0){
$expire_time = 0<$timesec? $timesec: strtotime(date('Y-m-d')) + 2592000 - time();
}else{
$expire_time = $timesec;
}
return Redis::expire($key,$expire_time);
}
// 設定zset的長度
public function SetZsetTime($key,$data,$lenth =4){
if($this->zSize($key)>$lenth){
Redis::zremrangebyrank($key,0,count($data)-1);
}
}
public function getListInfoByCondition($key,$start,$end,array $limit,$sort = 'asc'){
if($sort == 'desc'){
$pageNum = $limit['limit'][0]*$limit['limit'][1];
$limit['limit'][0] = $this->zSize($key)-$pageNum;
// 本方法只使用於app分頁 上一頁 下一頁 不支援跳頁查詢
}
return $sort == 'desc'?array_reverse($this->zRangByScore($key,$start,$end,$limit)):$this->zRangByScore($key,$start,$end,$limit);
}
// 新增一條資料
public function addOneInfo($key,array $data){
if(Redis::exists($key)){
if(count($data)>4){
return false;
}
$ret = $this->zAdd($key,$data);
$this->SetZsetTime($key,$data);
return $ret;
}else{
$this->expire($key,60);
return $this->zAdd($key,$data);
}
}
// 更新一條資料
public function updateOneById($key,$id,$data){
$this->deleteOneById($key,$id);
return $this->zAdd($key,$data);
}
// 刪除一條資料
public function deleteOneById($key,$id){
return Redis::zremrangebyscore($key,$id,$id);
}
// 獲取一條資料
public function getOneInfoById($key,$id){
return $this->zRangByScore($key,$id,$id,array('withScores'=>''));
}
}