【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等只要组合得当也可以。

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

索引更新

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

参考:

https://redis.io/topics/indexes

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

https://github.com/antirez/redimension

本文链接http://metronic.net.cn/metronic/show-22196.html