s¶
时间线(timeline)¶
应用
在有些应用程序中,数据通常带有一个时间值,程序以时间为单位操作数据(可以是一个时间范围,或者是单独的一个时间点):比如求一个博客在6月至8月的所有日志,或者是今天写博客的文章数。
还有一些微博客,只显示最近两天的内容,等等。
定义
一个时间线对象最少有两个属性
- 时间值
- 数据内容
针对时间线对象的操作通常都是一些范围型的操作:比如求某个时间点起到另一个时间点内的所有数据,或者是统计某个时间点起到另一个时间点内的数据数目,等等。
实现
在Redis中我们可以用sorted_set_struct表示时间线。
当增加一个新条目时,我们将条目内容作为有序集元素的member
参数,使用当前时间的UnixTime格式,作为有序集元素的score
值。
比如一条在2011年8月22日时47分7秒发出的信息,会被储存为:
ZADD tweet 1313981227.681918 "hello my friend"
其中tweet
是时间线的key
,1313981227.681918
是UnixTime格式的UTC时间,而"hello my friend"
则是条目内容。
这样一来,就可以用ZREVRANGE进行按条目数读取(比如读出最新10条数据),使用ZREVRANGEBYSCORE进行时间范围型的读取操作(比如读出2011年8月20日到2011年8月22日的所有数据),用ZREM对单条数据进行删除,用ZREMRANGEBYRANK和ZREMRANGEBYSCORE进行时间范围型的删除操作。
# coding: utf-8
# file: ./s/timeline/sorted_set_implement.py
from redis import Redis
from time import time
# Redis有序集边界
LEFTMOST = 0
RIGHTMOST = -1
class Timeline:
def __init__(self, name, client=Redis()):
self.name = name
self.client = client
def append(self, content):
# time()函数生成当前时间的unixtime值
self.client.zadd(self.name, score=time(), value=content)
def range(self, start=LEFTMOST, stop=RIGHTMOST, display_time=False):
# 使用zrevrange命令,读出最新的数据
return self.client.zrevrange(self.name, start, stop, withscores=display_time)
def range_between_time(self, min, max, display_time=False):
# min和max也必须是unixtime值
# 注意zrevrangebyscore命令参数的摆放是max先而min后
return self.client.zrevrangebyscore(self.name, max, min, withscores=display_time)
def delete(self, content):
return self.client.zrem(self.name, content)
def delete_between_time(self, min, max):
# min和max也必须是unixtime值
return self.client.zremrangebyscore(self.name, min=min, max=max)
def length(self):
return self.client.zcard(self.name)