1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        Redis實(shí)現(xiàn)列表數(shù)據(jù)查詢?cè)O(shè)計(jì)

        共 10628字,需瀏覽 22分鐘

         ·

        2021-03-01 04:46

        文章簡(jiǎn)介

        本文總結(jié)個(gè)人在使用Redis存儲(chǔ)列表數(shù)據(jù)業(yè)務(wù)場(chǎng)景下的一些思路。平常在使用數(shù)據(jù)查詢時(shí),我們一般會(huì)將查詢出來(lái)的數(shù)據(jù)使用json_encode()序列化一下,然后根據(jù)數(shù)據(jù)ID存儲(chǔ)到Redis中。這樣針對(duì)列表類的數(shù)據(jù),或許就不是很好的實(shí)現(xiàn)了(因?yàn)樯婕暗椒猪?yè)計(jì)算)。本文使用String和zset類型實(shí)現(xiàn)這樣的功能。

        數(shù)據(jù)存儲(chǔ)結(jié)構(gòu)

        上圖為zset緩存數(shù)據(jù)ID,和String緩存實(shí)際信息的一個(gè)映射關(guān)系。

        1. zset中的分?jǐn)?shù)和值都是數(shù)據(jù)的ID,是因?yàn)閿?shù)據(jù)的ID是唯一的,zset中的值和分?jǐn)?shù)也是唯一的。正好符合這種關(guān)系。

        2. String存儲(chǔ)實(shí)體信息。緩存key則以數(shù)據(jù)ID作為鍵名,值為序列化后的數(shù)據(jù)信息。

        3. zset中的值和String緩存中的key一一映射。

        接口數(shù)據(jù)處理

        接口獲取數(shù)據(jù)一般就是傳遞一個(gè)頁(yè)碼(page)和一個(gè)分頁(yè)大小(size)。我們先去zset中獲取對(duì)應(yīng)的ID。然后根據(jù)ID依次獲取String中的數(shù)據(jù)。如何根據(jù)分頁(yè)去讀取zset中的ID呢?可以根據(jù)下面的公式:

        // 開(kāi)始位置
        $start = ($page - 1) * $size;
        // 結(jié)束位置
        $end   = $start + $size;
        // 獲取ID
        $idArray = $redis->zRange($key, $start, $end);
        var_dump($idArray);
        // output
        [12456]
        // 根據(jù)ID向Redis獲取數(shù)據(jù)
        $returnArray = [];
        foreach ($idArray as $key => $value) {
            $returnArray[$key] = json_decode('cache:' . $value, true);
        }

        return $returnArray;

        后臺(tái)數(shù)據(jù)維護(hù)

        用戶端獲取數(shù)據(jù)解決了,如果后臺(tái)數(shù)據(jù)變更了,該如何處理呢?這里只要我們對(duì)后臺(tái)的數(shù)據(jù)做了操作,去操作對(duì)應(yīng)的緩存即可。整體思路如下:

        代碼演示

        Redis連接

        class RedisConnection
        {
            public $redisConnection;

            public function __construct()
            
        {
                $redis = new Redis();
                $redis->connect('192.168.2.102'63791);
                $redis->auth(6379);
                $this->redisConnection = $redis;
            }
        }

        MySQL連接

        class DBConnection
        {
            /**
             * 數(shù)據(jù)庫(kù)類型
             * @var string
             */

            private $dbms = 'mysql';

            /**
             * 主機(jī)地址
             * @var string
             */

            private $host = 'mysql5';

            /**
             * 端口號(hào)
             * @var int
             */

            private $port = 3306;

            /**
             * 數(shù)據(jù)庫(kù)名稱
             * @var string
             */

            private $dbName = 'tools';

            /**
             * 用戶名稱
             * @var string
             */

            private $user = 'root';

            /**
             * 密碼
             * @var string
             */

            private $pass = '123456';

            /**
             * 連接對(duì)象
             * @var PDO
             */

            public $dbConnection;

            public function __construct()
            
        {
                try {
                    $dbh                = new PDO("{$this->dbms}:host={$this->host};port:{$this->port};dbname={$this->dbName}",
                        $this->user,
                        $this->pass, [
                            PDO::ATTR_PERSISTENT => true
                        ]);
                    $this->dbConnection = $dbh;
                } catch (Exception $exception) {
                    var_dump('MySQL連接異常:' . $exception->getMessage());
                }
            }
        }

        管理端

        class Manage
        {
            /**
             * Redis連接對(duì)象
             * @var Redis
             */

            private $redis;

            /**
             * MySQL連接對(duì)象
             * @var PDO
             */

            private $db;

            public function __construct()
            
        {
                $this->db = (new DBConnection())->dbConnection;

                $this->redis = (new RedisConnection())->redisConnection;
            }

            /**
             * 數(shù)據(jù)增加
             * @return void
             */

            public function insert()
            
        {
                // 添加的數(shù)據(jù)
                $data = [];
                // 1. 插入數(shù)據(jù)庫(kù)
                $insertId = 0;
                // 2. 插入Redis
                // 2.1 插入string
                $this->redis->set('cache:' . $insertId, json_encode($data));
                // 2.2 插入zset
                $this->redis->zAdd('list', [], $insertId, $insertId);
            }

            /**
             * 數(shù)據(jù)更新
             * @return void
             */

            public function update()
            
        {
                // 更新數(shù)據(jù)
                $data = [];
                // 1. 更新數(shù)據(jù)庫(kù)
                $updatedId = 0;
                // 2. 更新Redis
                $this->redis->set('cache:' . $updatedId, json_encode($data));
            }

            /**
             * 數(shù)據(jù)刪除
             * @return void
             */

            public function delete()
            
        {
                // 1.刪除數(shù)據(jù)id
                $deleteId = 0;
                // 2.刪除Redis
                // 2.1刪除string
                $this->redis->del('cache:' . $deleteId);
                // 2.2刪除zset
                $this->redis->zDelete('list', $deleteId);
            }
        }

        接口端

        class Api
        {
            /**
             * Redis連接對(duì)象
             * @var Redis
             */

            private $redis;

            public function __construct()
            
        {

                $this->redis = (new RedisConnection())->redisConnection;
            }

            /**
             * 獲取列表
             * @return array
             */

            public function list()
            
        {
                /**
                 * 這里羅列普通的查詢
                 * 如果涉及到條件查詢,可以先根據(jù)條件去MySQL中查詢到主表的ID。在根據(jù)ID走這樣的邏輯。
                 */

                // 頁(yè)碼
                $page = 1;
                // 分頁(yè)大小
                $size = 10;
                // 1.先根據(jù)分頁(yè)獲取zset中的id(分?jǐn)?shù))
                $start   = ($page - 1) * $size;
                $idArray = $this->redis->zRange('list', $start, $size + $start);
                // 2.根據(jù)獲取到的id,去string中查找
                $returnArray = [];
                foreach ($idArray as $key => $value) {
                    $returnArray[$key] = json_decode('cache:' . $value, true);
                }

                return $returnArray;
            }

            // 獲取詳情
            public function find()
            
        {
                // 客戶端請(qǐng)求的,數(shù)據(jù)id
                $id = 1;

                return json_decode($this->redis->get('cache:' . $id), true);
            }

        }

        問(wèn)題總結(jié)

        1. 列表參數(shù)化查詢?nèi)绾翁幚恚?/section>

        列表數(shù)據(jù)一般都是有傳遞用戶查詢參數(shù),這時(shí)候我們可以實(shí)現(xiàn)根據(jù)條件去數(shù)據(jù)庫(kù)篩選出對(duì)應(yīng)的數(shù)據(jù)ID,并且只查詢ID即可,然后根據(jù)ID去執(zhí)行上面的邏輯。

        推薦閱讀

        1. Redis緩存數(shù)據(jù)一致性解決方案分析

        2. Redis事務(wù)處理機(jī)制分析與總結(jié)

        3. Redis數(shù)據(jù)類型應(yīng)用場(chǎng)景總結(jié)

        4. Redis的過(guò)期策略和內(nèi)存淘汰策略最全總結(jié)與分析

        5. Redis持久化存儲(chǔ)詳解(一)



        瀏覽 56
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            国产三级欧美 | 日韩人妻无码一区二区三区久久99 | 日本护士肉体取精视频 | 欧美另类色色 | 操批视频| 囯产精品久久久久久久免牛肉蒲团 | 26uuu亚洲精品国产精 | 别揉我胸啊嗯上课呢古代 | 欧美一级高潮片免费的 | 裸体迷惑台湾三级 |