PHP 使用 Redis 實現分頁

lar_cainiao 發表於 2019-08-13
   講一下為什麼使用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'=>''));
    }
}

相關文章

PHP 基礎 PHP

PHP 基礎

註釋:// 多行註釋.// 單行註釋.變數命規範(1))以$開頭; 如:$a(2)由字母數字下劃線組成,但是不能以數字開頭;(3)可以使用中文,但是不推薦使用;(4)變數名嚴格區分大小寫;(5)
phpStudy 後門如何檢測和修復 PHP

phpStudy 後門如何檢測和修復

原文:http://soft.antted.com/news/8背景一篇《Phpstudy官網於2016年被入侵,犯罪分子篡改軟體並植入後門》讓人觸目驚心,從官網的下載官方安裝包也會有問題,由此可想而
laragon 新增 PHP_Redis 擴充套件 Redis|PHP

laragon 新增 PHP_Redis 擴充套件

上篇laragon 簡單好用的 PHP 環境PECL官網按需下載redis擴充套件http://pecl.php.net/package/redis/4.0.2/windows例如/d/laragon
docker 實現 Redis 的哨兵機制 Redis|Docker

docker 實現 Redis 的哨兵機制

redis 哨兵的由來redis 的主從都需要人工來切換,如果生成環境中 redis 主伺服器 掛掉了,無法提供服務。 這時候需要人工自動把從伺服器設定 主伺服器; 這個方法就會存在一定弊端,導致無法
Redis專題(3):鎖的基本概念到Redis分散式鎖實現 Redis

Redis專題(3):鎖的基本概念到Redis分散式鎖實現

擴充閱讀:Redis閒談(1):構建知識圖譜Redis專題(2):Redis資料結構底層探祕近來,分散式的問題被廣泛提及,比如分散式事務、分散式框架、ZooKeeper、SpringCloud等等。本
JavaScript 和 PHP base64 加密解密 亂碼問題 JavaScript|PHP|加密

JavaScript 和 PHP base64 加密解密 亂碼問題

記錄以下base64加解密base64是通用的加解密方法,JavaScript也有現成的庫可以使用,PHP更是有現成函式可用。1 前端引入一個庫var html_source = base64.enc
PHP 多程式與訊號中斷實現多工常駐記憶體管理【Master/Worker 模型】 PHP

PHP 多程式與訊號中斷實現多工常駐記憶體管理【Master/Worker 模型】

本文章基於pcntl擴充套件做的多程式測試。程式排程策略:父子程式的排程由作業系統來負責,具體先排程子程式還是父程式由系統的排程演算法決定,當然可以在父程式加上延時或是呼叫程式回收函式pcntl_wa
使用 Casbin 作為 ThinkPHP 的許可權控制中介軟體 PHP|中介軟體

使用 Casbin 作為 ThinkPHP 的許可權控制中介軟體

PHP-Casbin 是一個強大的、高效的開源訪問控制框架,它支援基於各種訪問控制模型的許可權管理。Think-Casbin 是一個專為ThinkPHP5.1定製的Casbin的擴充套件包,使開發者更
redis實現閘道器限流(限制API呼叫次數1000次/分) Redis

redis實現閘道器限流(限制API呼叫次數1000次/分)

新增maven依賴,使用springboot2.x版本 &lt;dependency&gt; &lt;groupId&gt;org.springframework.
吃透了這些 Redis 知識點,面試官一定覺得你很 NB 面試|Redis

吃透了這些 Redis 知識點,面試官一定覺得你很 NB

很多文章都會說,redis支援5種常用的資料型別,這其實是存在很大的歧義。redis裡存的都是二進位制資料,其實就是位元組陣列(byte[]),這些位元組資料是沒有資料型別的,只有把它們按照合理的格式
手把手使用 PHP 實現 LRU 快取淘汰演算法 演算法|PHP

手把手使用 PHP 實現 LRU 快取淘汰演算法

:pencil2:LRU(cache):hourglass:LRU介紹快取是一種提高資料讀取效能的技術。但是對於計算機來說,並不可能快取所有的資料,在達到它的臨界空間時,我們需要通過一些規則用新的資料