使用 Redis 列表构建分页程序

Note

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

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

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

代码清单 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