redis常用数据结构之命令

/ 默认分类 / 没有评论 / 78浏览
hash
hset user:1 name lover age 18 sex male

批量获取指定字段的数据

hmget user:1 name age sex
1) "lover"
2) "20"
3) "male"

批量获取所有值

www.slivercommander.cn:6379> hvals user:1
1) "male"
2) "lover"
3) "20"

批量获取所有键值

www.slivercommander.cn:6379> hgetall user:1
1) "sex"
2) "male"
3) "name"
4) "ygp"
5) "age"
6) "20"

查看数据编码格式

www.slivercommander.cn:6379> object encoding hashkey
"ziplist"
hash内部编码
  1. ziplist(压缩列表):当哈希类型元素个数小于hash-max-ziplist-entries配置(默认512个)、同时所有值都小于hash-max-ziplist-value配置(默认64字节)时,Redis会使用ziplist作为哈希的内部实现,ziplist使用更加紧凑的结构实现多个元素的连续存储,所以在节省内存方面比hashtable更加优秀。
  2. hashtable(哈希表):当哈希类型无法满足ziplist的条件时,Redis会使用hashtable作为哈希的内部实现,因为此时ziplist的读写效率会下降,而hashtable的读写时间复杂度为O(1)。
编码详情

list

image

添加操作

(1)从右往左插入元素

www.slivercommander.cn:6379> rpush listkey  c b a 
(integer) 3

从右往左获取列表所有元素

www.slivercommander.cn:6379> lrange listkey 0 -1
1) "c"
2) "b"
3) "a"

(2)向某个元素前或后插入元素

linsert key before|after pivot value
www.slivercommander.cn:6379> linsert listkey before b java
(integer) 4
www.slivercommander.cn:6379> lrange listkey 0 -1
1) "c"
2) "java"
3) "b"
4) "a"

查找

(1)获取指定范围的元素列表

lrange key start end
www.slivercommander.cn:6379> lrange listkey 1 3
1) "java"
2) "b"
3) "a"

(2)获取列表指定索引的元素

www.slivercommander.cn:6379> lindex listkey -2
"b"

(3)获取列表长度

www.slivercommander.cn:6379> llen listkey
(integer) 4

删除

(1)列表左侧弹出元素

www.slivercommander.cn:6379> lpop listkey
"c"

(2)删除指定元素

lrem命令会从列表中找到等于value的元素进行删除

lrem key count value
www.slivercommander.cn:6379> rpush remove  a a a a a java b a
(integer) 8
www.slivercommander.cn:6379> lrem remove 4 a
(integer) 4
www.slivercommander.cn:6379> lrange remove 0 -1
1) "a"
2) "java"
3) "b"
4) "a"
www.slivercommander.cn:6379> lrem remove 0 a
(integer) 2
www.slivercommander.cn:6379> lrange remove 0 -1
1) "java"
2) "b"

内部编码
list的使用场景

如图所示,Redis的lpush+brpop命令组合即可实现阻塞队列,生产者客户端使用lrpush从列表左侧插入元素,多个消费者客户端使用brpop命令阻塞式的“抢”列表尾部的元素,多个客户端保证了消费的负载均衡和高可用性。

image

每个用户有属于自己的文章列表,现需要分页展示文章列表。此时可以考虑使用列表,因为列表不但是有序的,同时支持按照索引范围获取元素。

1)每篇文章使用哈希结构存储,例如每篇文章有3个属性title、timestamp、content:

hmset acticle:1 title xx timestamp 1476536196 content xxxx
...
hmset acticle:k title yy timestamp 1476512536 content yyyy
...

2)向用户文章列表添加文章,user:{id}:articles作为用户文章列表的键:

lpush user:1:acticles article:1 article3
...
lpush user:k:acticles article:5
...

3)分页获取用户文章列表,例如下面伪代码获取用户id=1的前10篇文章:

articles = lrange user:1:articles 0 9
for article in {articles}
hgetall {article}

实际上列表的使用场景很多,在选择时可以参考以下口诀:

lpush+lpop=Stack(栈)

lpush+rpop=Queue(队列)

lpsh+ltrim=Capped Collection(有限集合)

lpush+brpop=Message Queue(消息队列)

集合
www.slivercommander.cn:6379> sadd walkure  freya Mikumo Kaname Reina Makina
(integer) 5
www.slivercommander.cn:6379> srem walkure freya
(integer) 1

www.slivercommander.cn:6379> scard walkure
(integer) 4

www.slivercommander.cn:6379> sismember walkure Mikumo
(integer) 1
www.slivercommander.cn:6379> sismember walkure freya
(integer) 0

www.slivercommander.cn:6379> srandmember walkure 2
1) "Mikumo"
2) "Reina"
www.slivercommander.cn:6379> srandmember walkure 2
1) "Mikumo"
2) "Kaname"

www.slivercommander.cn:6379> spop walkure 
"Kaname"

www.slivercommander.cn:6379> smembers walkure
1) "Makina"
2) "Mikumo"
3) "Reina"