【redis】二级索引

简单数字索引

示例:

HMSET user:1 id 1 username antirez ctime 1444809424 age 38
HMSET user:2 id 2 username maria ctime 1444808132 age 42
HMSET user:3 id 3 username jballard ctime 1443246218 age 33

在以上示例中,需要查询每个user中每个key都非常方便,但是,如果我们想查询年龄在33-38岁的用户呢?

二级索引就派上用场了。

添加:

ZADD user.age.index 38 1
ZADD user.age.index 42 2
ZADD user.age.index 33 3

使用:

zrangebyscore user.age.index 33 38

查询到结果 3 1

此刻是不是感觉被耍了?这不就是sorted set吗?

是的,这就是索引实现的原理啊,mysql不也是类似的吗?redis的二级索引也可以加好几个,比如再维护一个 user.no.index来根据号码进行查询。

当然索引不限于使用sorted set,也不是只能检索一个字段,比如官网举例的GEO。

词典索引

有序集合索引的score只可以存数字,但是value可以是字符串,当score相同时,zrangebylex是以score字典顺序排序的,官网对于有序集合使用简单value做索引本人觉得相当鸡肋就不演示了,主要看用value做组合索引。

HMSET user:1 id 1 username antirez grade 2 gender girl
HMSET user:2 id 2 username maria grade 1 gender girl
HMSET user:3 id 3 username jballard grade 2 gender boy
HMSET user:4 id 4 username kaka grade 1 gender boy

需要查询2年级中的女生,添加的索引如下

zadd myindex 0 年级:性别:id

zadd myindex 0 2:girl:1
zadd myindex 0 1:girl:2
zadd myindex 0 2:boy:3
zadd myindex 0 1:boy:4

查询:

zrangebylex myindex [2:girl +

查询结果是2:girl:1,最后一个分段是id。

是不是更像mysql的索引了~redis官方也认为它就是类似B-tree的

一个小提示,字典排序中,是逐字符串比较的,不是按数字大小,当前面都相当时长的比较大。所以即使你的索引字段全是数字,查出来的结果集id是没什么顺序的,比如它认为12<129<76<9,对结果顺序要求严格时候需要注意。

hexastore

redis用它支持对的直接表示,其实还是有序集合的概念,但是它用‘六边形’把所有关系存了起来

它有主(Subject)、谓(Predicate)、(Object)的概念,例如:卡卡(曾)是AC米兰的球员这件事,它花了六条语句多角度去存

zadd myindex 0 spo:kaka:is-member-of:ACmilan
zadd myindex 0 sop:kaka:ACmilan:is-member-of

zadd myindex 0 ops:ACmilan:is-member-of:kaka
zadd myindex 0 osp:ACmilan:kaka:is-member-of

zadd myindex 0 pos:is-member-of:ACmilan:kaka
zadd myindex 0 pso:is-member-of:kaka:ACmilan

需要查询卡卡曾效力的球队时:

zrangebylex myindex "[spo:kaka:is-member-of:" "[spo:kaka:is-member-of:\xff"

#或
zrangebylex myindex "[pso:is-member-of:kaka:" "[pso:is-member-of:kaka:\xff"

需要查询曾效力过AC米兰的球员时,也是类似

在这个例子里好像不必存6次,三次也够了,毕竟也没有涉及方向。其实这是只拿一个简单举例,真正项目中使用中还会有kaka:is-friend-of:CR、kaka:is-citizen-of:Brazil,在查询卡卡的所有信息或者查询所有存在is-member-of、is-friend-of关系的k-v时还是需要都存一遍的。

当然,redis并不仅仅只能用有序集合做索引,hash、list等只要组合得当也可以。比如我们项目中用hash保存了每个用户的基本信息,每个课程用集合存储课程学员id,在每次签到、统计已完成未完成流程的学生时,都是对课程学员集合做操作,再根据id查学生基本信息,这样做的好处是,学生信息更新比如换了头像什么的,我们即使是历史数据也能跟着更新,避免指向错误的地址出现显示错误之类问题。

官方也给出复合索引以检索多维指标,很显然,官方绝不认为自己只能做做简单的缓存之类。

索引更新

所有的索引,以后增删改数据都需要记得维护它,为了保障原子性可以用lua。当然官方也提出,网络分区等各种问题会造成索引不一致,需要定时检查、全量、增量更新索引中的数据。

参考:

https://redis.io/topics/indexes

https://www.zybuluo.com/Rays/note/1079251

https://github.com/antirez/redimension

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值