【从入门到放弃-Redis】redis的key设计原则

设计原则

redis key设计技巧
1:把表名转换为key前缀 如tag:
2:第2段放置用于区分出key的字段-对应mysql中的主键的列名,如userid
3:第3段放置主键值,如2,3,4…
4:第4段,写要存储的列名

用户表user,转换为key-value存储
userid username password email
9 lisi 12345 lisi@163.com

set user:userid:9:username lisi
set user:userid:9:password 12345
set user:userid:9:email lisi@163.com

keys user:userid:9*

在关系型数据库中,除主键外,还有可能其他列也要查询
在k-v数据中,则要相应的生成一条按照该列为主的k-v
set user:username:lisi:uid 9

这样我们可以根据user:username:lisi:uid 查出userid=9
再查 user:userid:9:password/email 等 就可以了
(通过数据冗余来实现)

这样设计在分布式存储时,有个好处,可以避免缓存无底洞现象
即:当服务器增多时,key也被散落在更多的节点上,导致要连接的节点也越多
于是出现缓存无底洞现象。
解决方案:把某一组key,按其共同前缀,分布在同一个节点上

仿微博key-value设计

注册用户:user
incr global:userid
set user:userid:1:username zhangsan
set user:userid:1:password 111111

set user:username:zhangsan:userid 1

发微博
post:postid:1:time timestamp
post:postid:1:userid 3
post:postid:1:content ‘this is my home’

incr global:postid

关注关系
每人有自己的粉丝记录 set
每人有自己的关注记录 set

aid 关注 bid
following:userid (bid)
follower:userdi (aid)

推送表 lpush(‘receivepost:userid’, postid);
receivepost:userid 每增加一条微博,将微博id推送至用户接受信息链表

拉取表
pull:userid
问:上次拉取了A->5,6,7三条微博,下次刷新时,如何从大于7出开始拉?
答:拉取时,设定一个lastpull点,下次拉取时,取大于lastpull的微博

问:关注了很多人,怎么取?
答:循环自己的关注列表,逐个取出

问:取出来的微博放在那里?
答:pull:userid链表里

问:如何保证个人中心只有一千条
答:用ltrim只去前1000条的

问:如果用hash结构存储微博,那么拉取多人的微博内容,在时间上是交错的,如何做到按时间排序
答:同步时,取微博后,记录本次取得微博的最大id,下次同步时,只取比最大id更大的微博

================每人微博的前1000条存于redis,更旧的存于数据库================
思路:每人1000条以前的都推到一个global:store链表中
用定时任务,取出global:store中的前1000条,存入数据库