16-实践
3.4.3 实践
1.存储文章ID列表
为了解决小白遇到的问题,我们使用列表类型键 posts:list 记录文章ID列表。当发布新文章时使用 LPUSH 命令把新文章的ID加入这个列表中,另外删除文章时也要记得把列表中的文章ID删除,就像这样: LREM posts:list 1 要删除的文章 ID
有了文章ID列表,就可以使用 LRANGE 命令来实现文章的分页显示了。伪代码如下:
$postsPerPage = 10
$start = ($currentPage - 1) * $postsPerPage
$end = $currentPage * $postsPerPage - 1
$postsID =LRANGE posts:list, $start, $end
# 获得了此页需要显示的文章ID列表,我们通过循环的方式来读取文章
for each $id in $postsID
$post =HGETALL post:$id
print 文章标题:$post.title
这样显示的文章列表是根据加入列表的顺序倒序的(即最新发布的文章显示在前面),如果想让最旧的文章显示在前面,可以使用 LRANGE 命令获取需要的部分并在客户端中将顺序反转显示出来,具体的实现交由读者来完成。
小白的问题至此就解决了,美中不足的一点是散列类型没有类似字符串类型的 MGET命令 那样可以通过一条命令同时获得多个键的键值的版本,所以对于每个文章ID都需要请求一次数据库,也就都会产生一次往返时延(round-trip delay time)11,之后我们会介绍使用管道和脚本来优化这个问题。
114.5节中还会详细介绍这个概念。
另外使用列表类型键存储文章ID列表有以下两个问题。
(1)文章的发布时间不易修改:修改文章的发布时间不仅要修改 post: 文章ID中的 time 字段,还需要按照实际的发布时间重新排列 posts:list 中的元素顺序,而这一操作相对比较繁琐。
(2)当文章数量较多时访问中间的页面性能较差:前面已经介绍过,列表类型是通过链表实现的,所以当列表元素非常多时访问中间的元素效率并不高。
但如果博客不提供修改文章时间的功能并且文章数量也不多时,使用列表类型也不失为一种好办法。对于小白要做的博客系统来讲,现阶段的成果已经足够实用且值得庆祝了。3.6节将介绍使用有序集合类型存储文章ID列表的方法。
2.存储评论列表
在博客中还可以使用列表类型键存储文章的评论。由于小白的博客不允许访客修改自己发表的评论,而且考虑到读取评论时需要获得评论的全部数据(评论者姓名,联系方式,评论时间和评论内容),不像文章一样有时只需要文章标题而不需要文章正文。所以适合将一条评论的各个元素序列化成字符串后作为列表类型键中的元素来存储。
我们使用列表类型键 post:文章ID:comments 来存储某个文章的所有评论。发布评论的伪代码如下(以ID为42的文章为例):
# 将评论序列化成字符串
$serializedComment = serialize($author, $email, $time, $content)
LPUSH post:42:comments, $serializedComment
读取评论时同样使用 LRANGE 命令即可,具体的实现在此不再赘述。