首页 > 技术文章 > Redis的数据类型

zydev 2019-10-25 11:50 原文

    Redis不是简单的键值存储,它实际上是一个数据结构服务器,支持不同类型的值。

以下是Redis支持的所有数据结构的列表:

  • Binary-safe strings.
  • Lists:    根据插入顺序排序的字符串元素的集合。它们基本上是链表
  • Sets:     唯一,未排序的字符串元素的集合。
  • Sorted sets  类似于Sets的排序集合,但每个字符串元素都与一个称为score的浮点值相关联
  • Hashes    是由与值关联的字段组成的映射。字段和值都是字符串。
  • Bit arrays    可以使用特殊命令像位数组一样处理字符串值:您可以设置和清除单个位,计数所有设置为1的位,找到第一个设置或未设置的位,等等。
  • HyperLogLogs  这是一个概率数据结构,用于估计集合的基数
  • Streams    提供抽象日志数据类型的类地图项的仅追加集合

 

1. Redis 的字符串

   SETGET命令是我们设置和检索字符串值的方式

127.0.0.1:6379> set mykey somevale
OK
127.0.0.1:6379> get mykey
"somevale"
127.0.0.1:6379> set mykey newval nx       nx:key不存在时才可以set
(nil)
127.0.0.1:6379> set mykey newval xx       xx:已经存在key才可以set      
OK
127.0.0.1:6379> get mykey
"newval"

  即使字符串是Redis的基本值,您也可以使用它们执行一些有趣的操作。例如,一个是原子的增减和减少:

127.0.0.1:6379> set counter 100
OK
127.0.0.1:6379> INCR counter
(integer) 101
127.0.0.1:6379> INCRBY counter 10
(integer) 111
127.0.0.1:6379> get counter
"111"
127.0.0.1:6379> decr counter
(integer) 110
127.0.0.1:6379> DECRBY counter 10
(integer) 100

  在单个命令中设置或检索多个键的值的功能对于减少延迟也很有用。因此,有MSETMGET命令:

127.0.0.1:6379> mset a 1 b 2 c 3
OK
127.0.0.1:6379> MGET a b c
1) "1"
2) "2"
3) "3"

  key的查询和删除,EXISTS命令返回1或0表示数据库中是否存在给定的键,而DEL命令则删除键和关联的值(无论该值是什么)。

127.0.0.1:6379> set mykey hello xx
OK
127.0.0.1:6379> EXISTS mykey
(integer) 1
127.0.0.1:6379> del mykey
(integer) 1
127.0.0.1:6379> EXISTS mykey
(integer) 0

  TYPE命令返回存储在指定key的值的类型:

127.0.0.1:6379> set counter 1
OK
127.0.0.1:6379> type counter 
string
127.0.0.1:6379> del counter 
(integer) 1
127.0.0.1:6379> type counter
none

  Expires可以为密钥设置超时时间,这是有限的生存时间。生存时间过去后,该密钥将自动销毁,就像用户使用该密钥调用DEL命令一样

> set key some-value
OK
> expire key 5
(integer) 1
> get key (immediately)
"some-value"
> get key (after some time)
(nil)

  或者使用set的ex选项

127.0.0.1:6379> set mykey 10 ex 10
OK

  

2. Redis列表

  Redis列表是通过链接列表实现的。这意味着即使您在列表中有数百万个元素,在列表的开头或结尾添加新元素的操作也会在固定时间内执行

  在使用Array实现的列表中,按索引访问元素速度非常快(恒定时间索引访问),

  而在通过链接列表实现的列表中访问速度不是那么快(其中操作需要的工作量与所访问元素的索引成比例)。

 Redis列表是用链接列表实现的,因为对于数据库系统而言,至关重要的是能够以非常快的方式将元素添加到很长的列表中。

 

LPUSH命令将一个新元素到一个列表,在左侧(在头部),而RPUSH命令将一个新元素到一个列表,在右侧(在尾部)。最后, LRANGE命令从列表中提取元素范围:

127.0.0.1:6379> rpush mylist A B
(integer) 2
127.0.0.1:6379> LPUSH mylist first
(integer) 3
127.0.0.1:6379> LRANGE mylist 0 -1
1) "first"
2) "A"
3) "B"

  

在Redis列表上定义的一项重要操作是弹出元素的能力弹出元素是同时从列表中检索元素和从列表中删除元素的操作。您可以从左侧和右侧弹出元素,类似于在列表的两侧推送元素的方式:

nil表示null

127.0.0.1:6379> RPOP mylist 
"B"
127.0.0.1:6379> LPOP mylist
"first"
127.0.0.1:6379> LPOP mylist
"A"
127.0.0.1:6379> LPOP mylist
(nil)

  LTRIM删除指定范围外的元素

127.0.0.1:6379> RPUSH mylist 1 2 3 4 5
(integer) 10
127.0.0.1:6379> LTRIM mylist 0 2
OK
127.0.0.1:6379> LRANGE mylist 0 -1 
1) "1"
2) "2"
3) "3"

  列表具有一项特殊功能,使其适合于实现队列,并且通常用作进程间通信系统的构建块:阻止操作

  Redis的实现称为命令BRPOPBLPOP能够阻止如果列表是空的:他们将只有当新的元素添加到列表中,或者当用户指定超时主叫到达。

127.0.0.1:6379> rpush mylist 1 2 
(integer) 2
127.0.0.1:6379> brpop mylist 5
1) "mylist"
2) "2"
127.0.0.1:6379> brpop mylist 5
1) "mylist"
2) "1"
127.0.0.1:6379> brpop mylist 5    #列表为空,将等待5秒,如果有新元素添加到列表,将返回新元素,否则返回nil
(nil)
(5.10s)

  

3. Redis哈希

HMSET命令设置哈希的多个字段,HGET检索单个字段

127.0.0.1:6379> HSET user:10 username scott
(integer) 1
127.0.0.1:6379> HGET user:10 username
"scott"
127.0.0.1:6379> HMSET user:10 birthyear 1977 verified 1
OK
127.0.0.1:6379> HMGET user:10 birthyear verified
1) "1977"
2) "1"
127.0.0.1:6379> HGETALL user:10
1) "username"
2) "scott"
3) "birthyear"
4) "1977"
5) "verified"
6) "1"

 有些命令也可以对单个字段执行操作,例如HINCRBY

127.0.0.1:6379> hincrby user:10 birthyear 10
(integer) 1987

  

4. Redis集

  Redis集是字符串的无序集合。该 SADD命令添加新的元素,一组。还可以对集合进行许多其他操作,例如测试给定元素是否已存在,执行多个集合之间的交集,并集或差等。

127.0.0.1:6379> SADD myset  1 2 3
(integer) 0
127.0.0.1:6379> SMEMBERS myset
1) "1"
2) "2"
3) "3"

  检查元素是否存在:SISMEMBER

 

127.0.0.1:6379> SISMEMBER myset 1
(integer) 1
127.0.0.1:6379> SISMEMBER myset 30
(integer) 0

 

  

5. Redis排序集

虽然集合内的元素没有排序,但是排序后的集合中的每个元素都与一个称为得分的浮点值相关联

它们根据以下规则排序:

  • 如果A和B是两个具有不同分数的元素,那么如果A.score是> B.score,则A>B。
  • 如果A和B的分数完全相同,那么如果A字符串在字典上大于B字符串,则A>B。A和B字符串不能相等,因为排序集仅具有唯一元素。

ZADDSADD相似,但是使用一个额外的参数(放置在要添加的元素之前)作为得分。

127.0.0.1:6379> zadd hackers 1940 "Alan Kay"
(integer) 1
127.0.0.1:6379> zadd hackers 1957 "Sophie Wilson"
(integer) 1
127.0.0.1:6379> zadd hackers 1969 "Linus Torvalds"
(integer) 1
127.0.0.1:6379> zadd hackers 1912 "Alan Turing"

  当我们要求排序的元素时,Redis根本不需要做任何工作,它已经全部排序了:

127.0.0.1:6379> zrange hackers 0 -1
1) "Alan Turing"
2) "Alan Kay"
3) "Sophie Wilson"
4) "Linus Torvalds"
127.0.0.1:6379> ZREVRANGE hackers 0 -1    #反向展示
1) "Linus Torvalds"
2) "Sophie Wilson"
3) "Alan Kay"
4) "Alan Turing"

  也可以使用以下WITHSCORES参数返回分数

127.0.0.1:6379>  zrange hackers 0 -1 withscores
1) "Alan Turing"
2) "1912"
3) "Alan Kay"
4) "1940"
5) "Sophie Wilson"
6) "1957"
7) "Linus Torvalds"
8) "1969

在范围内操作

排序集比这更强大。它们可以在范围内操作。让我们获取所有出生至1950年(含)的个人。我们使用ZRANGEBYSCORE命令来做到这一点:

127.0.0.1:6379> zrangebyscore hackers -inf 1950
1) "Alan Turing"
2) "Alan Kay"

  也可以删除元素范围,并返回删除元素的个数。让我们从排序集中删除所有1940年至1960年之间出生的黑客:

127.0.0.1:6379> zremrangebyscore hackers 1940 1960
(integer) 2

 为排序的集合元素定义的另一种极其有用的操作是get-rank操作。可以问一个元素在有序元素集中的位置是什么。

127.0.0.1:6379> zrank hackers "Linus Torvalds"
(integer) 1

  

 

 

推荐阅读