8

使用 Redis 列表构建分页程序 — blog.huangz.me

 3 years ago
source link: https://blog.huangz.me/2019/redis-paging.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

使用 Redis 列表构建分页程序

本文摘录自即将出版的《Redis使用手册》, 详情请见: RedisGuide.com

对于互联网上每一个具有一定规模的网站来说, 分页程序都是必不可少的: 新闻站点、博客、论坛、搜索引擎等等, 都会使用分页程序将数量众多的信息分割为多个页面, 使得用户可以以页为单位浏览网站提供的信息, 并以此来控制网站每次取出的信息数量。 图 4-19 就展示了一个使用分页程序对用户发表的论坛主题进行分割的例子。


图 4-19 论坛中的分页示例

../_images/IMAGE_V2EX_PAGING.png

代码清单 4-2 展示了一个使用列表实现分页程序的方法, 这个程序可以将给定的元素有序地放入到一个列表里面, 然后使用 LRANGE 命令从列表中取出指定数量的元素, 从而实现分页这一概念。


代码清单 4-2 使用列表实现的分页程序:/list/paging.py

class Paging:

    def __init__(self, client, key):
        self.client = client
        self.key = key

    def add(self, item):
        """
        将给定元素添加到分页列表中。
        """
        self.client.lpush(self.key, item)

    def get_page(self, page_number, item_per_page):
        """
        从指定页数中取出指定数量的元素。
        """
        # 根据给定的 page_number (页数)和 item_per_page (每页包含的元素数量)
        # 计算出指定分页元素在列表中所处的索引范围
        # 例子:如果 page_number = 1 , item_per_page = 10
        # 那么程序计算得出的起始索引就是 0 ,而结束索引则是 9
        start_index = (page_number - 1) * item_per_page
        end_index = page_number * item_per_page - 1
        # 根据索引范围从列表中获取分页元素
        return self.client.lrange(self.key, start_index, end_index)

    def size(self):
        """
        返回列表目前包含的分页元素数量。
        """
        return self.client.llen(self.key)

作为例子, 我们可以通过执行以下代码, 载入并创建出一个针对用户帖子的分页对象:

>>> from redis import Redis
>>> from paging import Paging
>>> client = Redis(decode_responses=True)
>>> topics = Paging(client, "user-topics")

并使用数字 119 作为用户帖子的 ID , 将它们添加到分页列表里面:

>>> for i in range(1, 20):
...   topics.add(i)
...

然后我们就可以使用分页程序, 对这些帖子进行分页了:

>>> topics.get_page(1, 5)   # 以每页 5 个帖子的方式,取出第 1 页的帖子
['19', '18', '17', '16', '15']
>>> topics.get_page(2, 5)   # 以每页 5 个帖子的方式,取出第 2 页的帖子
['14', '13', '12', '11', '10']
>>> topics.get_page(1, 10)  # 以每页 10 个帖子的方式,取出第 1 页的帖子
['19', '18', '17', '16', '15', '14', '13', '12', '11', '10']

最后, 我们可以通过执行以下代码, 取得分页列表目前包含的元素数量:

>>> topics.size()
19

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK