06-实践
3.2.3 实践
1.文章访问量统计
博客的一个常见的功能是统计文章的访问量,我们可以为每篇文章使用一个名为 post: 文章 ID:page.view 的键来记录文章的访问量,每次访问文章的时候使用 INCR 命令使相应的键值递增。
提示
Redis对于键的命名并没有强制的要求,但比较好的实践是用“对象类型:对象ID:对象属性”来命名一个键,如使用键
user:1:friends来存储ID为1的用户的好友列表。对于多个单词则推荐使用“.”分隔,一方面是沿用以前的习惯(Redis以前版本的键名不能包含空格等特殊字符),另一方面是在redis-cli中容易输入,无需使用双引号包裹。另外为了日后维护方便,键的命名一定要有意义,如u:1:f的可读性显然不如user:1:friends好(虽然采用较短的名称可以节省存储空间,但由于键值的长度往往远远大于键名的长度,所以这部分的节省大部分情况下并不如可读性来得重要)。
2.生成自增ID
那么怎么为每篇文章生成一个唯一ID呢?在关系数据库中我们通过设置字段属性为 AUTO_INCREMENT 来实现每增加一条记录自动为其生成一个唯一的递增ID的目的,而在Redis中可以通过另一种模式来实现:对于每一类对象使用名为对象类型(复数形式):count5的键(如 users:count )来存储当前类型对象的数量,每增加一个新对象时都使用 INCR 命令递增该键的值。由于使用 INCR 命令建立的键的初始键值是1,所以可以很容易得知, INCR 命令的返回值既是加入该对象后的当前类型的对象总数,又是该新增对象的ID。
5这个键名只是参考命名,实际应用中可以使用任何容易理解的名称。
3.存储文章数据
由于每个字符串类型键只能存储一个字符串,而一篇博客文章是由标题、正文、作者与发布时间等多个元素构成的。为了存储这些元素,我们需要使用序列化函数(如PHP中的 serialize 和JavaScript中的 JSON.stringify )将它们转换成一个字符串。除此之外因为字符串类型键可以存储二进制数据,所以也可以使用MessagePack6进行序列化,速度更快,占用空间也更小。
6 MessagePack和JSON一样可以将对象序列化成字符串,但其性能更高,序列化后的结果占用空间更小,序列化后的结果是二进制格式。MessagePack的项目地址是http://msgpack.org。
至此我们已经可以写出发布新文章时与Redis操作相关的伪代码了:
# 首先获得新文章的ID
$postID =INCR posts:count
# 将博客文章的诸多元素序列化成字符串
$serializedPost = serialize($title, $content, $author, $time)
# 把序列化后的字符串存一个入字符串类型的键中
SET post:$postID:data, $serializedPost
获取文章数据的伪代码如下(以访问ID为42的文章为例):
# 从Redis中读取文章数据
$serializedPost =GET post:42:data
# 将文章数据反序列化成文章的各个元素
$title, $content, $author, $time = unserialize($serializedPost)
# 获取并递增文章的访问数量
$count =INCR post:42:page.view
除了使用序列化函数将文章的多个元素存入一个字符串类型键中外,还可以对每个元素使用一个字符串类型键来存储,这种方法会在3.3.3节讨论。