Redis怎么实现标签

Redis实现一个类似segmentfault的标签系统

阅读 10.1k
3 个回答

问题给的细节有点少啊。。标签本质上就是一个set,可以用redis set实现。但是实际上有很多需求用set是做不到的。所以我建议还是用mysql实现,只把性能瓶颈交给redis处理。不过要是非得用redis的话。。。

我假设你这个系统有以下几点要求:
1. 能增删tag,一个对象可以有好几个tag
2. 能增删tag下的内容
3. 对象是有序的(时间顺序、关注度、……),按tag过滤之后仍要保持有序

假设你的每个对象都是redis string。
先用sorted set存储所有的对象key列表,将其命名为A,按你想要的方式设置score来排序。
然后把每个tag集合也存为一个sorted set,如果一个对象有X这个tag,那么就在X这个sorted set里加入此对象,将score设为0。
之后进行一个预处理步骤。用zInterStore指令将tag X的sorted set和A的sorted set做intersection,让结果的score等于前两者中的score之加权和(默认的),tag X中的权值是0,A中的权值是1。让zInter把结果保存在X'。
以后要读取一个tag下的内容,就可以用zRange X'等命令。
要是增加了一个tag,就可以对那个新tag进行zInterStore。要是删除了一个对象,就可以用zInterStore刷新所有受影响的tag。大多数变化都可以用一条redis指令完成。当tag内元素数目小的时候,这个操作的时间复杂度是O(tag X的大小)。具体复杂度可以参考redis官网。

如果要同时选定多个tag,过滤掉其他内容,也可以用zInter指令,并进行适当的预运算(处理常用的tag组合?)

我现在一个网站就是这么办的,所以这个设想绝对可行,但说实话用redis实现真的麻烦。不过。。求采纳啊~

说说我的实现吧。
前几天刚做了标签模块。一直觉得 SegmentFault 的标签做的不错,然后就开始打 Typecho 的主意 ^-^

问题来了。我们这个项目的需求是标签必须存在于数据库,所以在用户输入的时候必须有 Recommendation,因此得根据用户输入进行实时的数据库查询。看了一下 Typecho 的实现,标签是提交后处理的,跟我们的需求不一样。蛋疼。

最后的实现是用 MySQL + Redis,把 Redis 当做缓存用,用 SortSet 存储标签,用户输入时的提醒直接交给 Redis 查。最后提交还是交给 MySQL。

之所以采用 SortSet,是因为 SortSet 有一个 Score 字段可以记录 标签热度(其实就是排序), 这样在 Recommendation 的时候就比较稳一点(命中率高一点)。


补充:

刚重新看了下 Typecho,输入提示的标签跟网页一起加载的。我们的网站由于标签库体量太大(目前已经有近 2M 的数据),所以不可能跟网页一起加载。所以暂时采用了上面这种办法。各位如果有什么好主意欢迎回复,3Q~

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏