logo头像

一路过来,不过游牧自己。。

Redis小趣(三)


上一篇讲了位图和列表的操作,所以今天就讲讲hash散列:

一、Hash散列

由field 和关联的value组成的map键值对
field和value是字符串类型
一个hash中最多包含2^32-1键值对
举例:
一个key message ,其值是:map{id=10086,sender=peter,…}
这里有一种思路,很多零散的key value,可以被hash散列!
例如一个人,那我直接以人名为key ,其余通过hash去存,sex=男,age=24等

所有关于Hash散列的,其首字母就是H
设置单个字段:
HSET key field value
HSETNX key field value (在key中,field字段不存在的时候,直接创建)

设置多个字段
HMSET key field value(field value….)

返回字段
HLEN key

判断字段是否存在
HEXISTS key field
key或者field不存在,返回0

返回字段值
HGET key field

返回多个字段值
HMGET key field(field…)

返回所有的键值对
HGETALL key

返回所有的字段名
HKEYS key

返回所有值
HVALS key

在字段对应的值上进行整数的增量计算
HINCRBY key field increment

在字段对应的值上进行浮点的增量计算
HINCRBYFLOAT key field increment

删除指定的字段
HDEL key field[field…]
举例略

hash用途:
(1)节约空间
(2)每创建一个键,它都会为这个键存储一些附加的管理信息(比如键的类型,这个键最后一次被访问的时间等)
(3)所以数据库里键越多,redis在附加信息方面就消耗越多内存,花在管理数据库键上的CPU也会越多在字段对应的值下行进行浮点数的增量计算
局限性:
所有的过期信息是作用在键上的,不是在字段上的

不适合hash的情况
(1)使用二进制位操作命令:英文Redis目前支持对字符串进行SETBIT,GETBIT,BITOP等操作,如果你想使用,只能用字符串键,虽然hash散列也能保存二进制数据
(2)使用过期功能键:因为Reais的过期功能键只能对键进行过期操作,而不能对散列字段进行过期操作。因此,如果你要对键值对使用过期功能的话,那么只能把键值对存储在字符串里

案例:
微博的好友关注
用户ID为key,Field为好友ID,value为关注事件
USER:1000,user:606 20150808
用户维度统计
统计数包括:关注数,粉丝数,喜欢商品数,发帖数
用户为KEY,不同维度为field,value为统计数
比如关注了5个人
HSET user:1000000 follow 5
HINCRBY user:100000 follow 1

二、set集合

(1)无序的,去重的
(2)元素是字符串类型
(3)最多包含2^32-1集合

命令
增加一个或多个元素
SADD key member[member]这里的s表示set
如果元素已经存在,则自动忽略
举例:
SADD friends peter
SADD friends jack tom john
SADD friends may tom

移除一个或多个元素
SREM key member
元素不存在,则自动忽略
举例:
SREM friends peter
返回集合里的所有元素:SMEMBERS key(因为无序,所以有可能每次顺序都不同,结果不同)
如果元素过多。例如百万个,需要比哪里,会造成服务器阻塞,生产环境应避免使用
检查给定元素是否存在于集合:SISMEMBER key member

随机返回集合中指定个数的
(1)SRANDMEMBER key[count]
(2)如果count为正数,且小于集合基数,则返回count个元素的数组,每个元素都不同,如果其大于集合基数,那么返回整个集合
(3)如果count为负数,返回一个数组,数组中的元素可能会重复多次,二而数组的长度为count的绝对值
(4)如果count为0,返回空
(5)若count不指定,随机返回一个元素

返回集合中元素的个数:SCARD key
键的结果会保存信息,集合长度就记录在里面,所以不需要遍历
随机从集合中移除并返回这个被移除的元素:spop key
把元素从源集合移到目标集合:SMOVE source destination member

set的集合操作
差集
SDIF key [key…] 从第一个KEY的集合中取出宇其他集合和自己相交的那部分
SDIFSTORE destination key [key…],将差集结果存储在目标KEY中

交集
SINTER key [key…]取所有集合交集部分
SINTER destination key [key…]将交集结果存储到目标key中

并集
SUNION key [key…],取所有集合并集
SUNIONSTORE key [key…],将交集结果存储到目标key中

案例:新浪微博的共同关注
需求:当用户访问另一个用户的时候,会显示出两恶搞用户共同关注那些相同的用户
设计:将每个用户关注的用户放到集合里,求交集即可!
实现如下:
peter={“john”,”jack”,”may”}
ben={“jhon”,”jack”,”tom”}
则共同关注是
SINTERSTORE shared Peter ben

三、SortedSet 有序的集合

(1)类似于Set集合
(2)有序的,去重的
(3)元素是字符串类型
(4)每个元素都关联着一个浮点数分值,按照分值从小到大的顺序排列集合中的原色,分值可以相同
(5)最多包含2^32-1集合
可以根据赞的数量排行榜就出来了
Z开头

命令
增加一个或多个元素
ZADD key score member[score member…] 分值,值
例:ZADD fruits 3.2 apple

删除一个或多个元素:
ZREM key member,若元素不存在,自动忽略

显示分值:
ZSCORE key member

增加或减少分值
ZINCRBY key incremnt member
increment是负数就是减少
例子:ZINCREBY fruits 1.5 apple

返回元素的排名
ZRANK key member
例如:
ZRANK fruits apple
逆序排名
ZREVRANK key member

返回指定索引区间的元素:(这里注意是;索引,不是分值)
ZRANGE key start stop[WITHSCORES]
如果score相同,则按字典序排
按照默认score从小到达,如果需要Score从大到小排列,则使用ZREVRANGE
ZRANGE fruits 0 2

返回指定分值区间的元素:
ZRANGEBYSCORE key min max[WITHSCORES] [LIMIT OFFSET COUNT]
返回score 默认属于[min,max]之间,元素按照score升序排列,score相同字典序
limit中offset表示跳过多少元素,count是返回几个,类似mysql
使用小括号,修改区间为开区间
-inf和+inf表示负无穷和正无穷
ZRANGEBYSCORE fruits (4 7
ZRANGEBYSCORE fruits -inf +inf
相反ZREVRANGEBYSCORE降序

移除指定排名范围的元素:
ZREMRANGEBYRANK key start stop
ZREMRANGEBYRANK fruits 0 1
移除指定分值范围的元素:
ZREMRANGEBYSCORE key start stop

返回集合中元素的个数:
ZCARD key(返回的非常快,这部分信息是存在key中的)复杂度 o(1)
返回指定范围中元素的个数:
ZCOUNT key min max
例如:
ZCOUNT fruits 4 7
ZCOUNT fruits (4 7

并集(还要考虑元素和分数的次序)
ZUNIONSTORE destination numkeys key[key…] [WEIGHTS weight] [AGGREGATE] SUM[MIN][MAX]
numkeys 指定key的数量
WEIGHT选项,与前面设定的key相对应,每一个Score都要乘以这个权
AGGREGATE选项,指定并集结果的聚合方式
SUM:将所有集合某一个元素的score值之和作为结果集中该成员的score值
MIN:将所有集合某一个元素的score值中最小值作为结果集中该成员的score值
MAX:将所有集合某一个元素的score值中最大值作为结果集中该成员的score值
如果有相同元素,分值相加,若是aggregate MIN,就是取其中的最小值,weight 1 0.5就是第一个权重占1,第二个占0.5

交集:
ZINTERSTORE destination numkeys key[key…] [WEIGHTS weight] [AGGREGATE] SUM[MIN][MAX]
numkeys 指定key的数量
WEIGHT选项,与前面设定的key相对应,每一个Score都要乘以这个权
AGGREGATE选项,指定并集结果的聚合方式
SUM:将所有集合某一个元素的score值之和作为结果集中该成员的score值
MIN:将所有集合某一个元素的score值中最小值作为结果集中该成员的score值
MAX:将所有集合某一个元素的score值中最大值作为结果集中该成员的score值

例如网易音乐排行榜:、
每首歌的名字作为元素
每首歌的播放次数作为分值
ZREVRANGE来获取播放最多的歌曲

新浪微博翻页,新闻网站,博客,论坛都需要分页
blog这个key中使用时间戳作为score
ZADD blog 1407000000 ‘今天天气不错’
ZADD blog 1507000000 ‘今天心情不错’
ZADD blog 1560000000 ‘使用REdis小案例’
ZREVRANGE blog 10 20
单日版 周版,月版

京东图书畅销榜
ZADD bookboard-001 1000 ‘java’ 1500 ‘redis’ 2000 ‘hadoop
ZADD bookboard-002 1025 ‘java’ 1544 ‘redis’ 2650 ‘hadoop’
ZADD bookboard-003 1620 ‘java’ 1564 ‘redis’ 2800 ‘hadoop’
ZUNIONSTORE bookboard-001:003 3 bookboard-001 bookboard-002 bookboard-003 AGGREGATE MAX
并集 使用max
注意:使用并集的计算的集合较多,会造成Redis服务器阻塞,最好放在空闲时间或者备用计算服务器上进行计算

多走路,多思考,越努力,越幸运!
———————————————YoungerFary

微信打赏

赞赏是不耍流氓的鼓励