Redis可以存储键(key)与5种不同类型值(value)之间的映射,5中不同类型的值分别为字符串(string),列表(list),散列(hash),集合(set)和有序集合(sorted set)等5种数据结构。有一部分Redis命令对于这5种结构是通用的,比如DEL、TYPE、RENAME等,但也有一部分Redis命令只能对特定的一种或者两种结构使用,本文将详细介绍Redis的5种数据结构和Redis提供的命令。
本文的部分截图来自《Redis In Action》,书中对于Redis的讲解非常精妙而且深入,对于想要了解Redis的人来说是一本不可多得的好书。
下表介绍了Redis提供的5种结构,说明了这些结构存储的值,并简单介绍了它们的语义。
结构类型 | 可包含数据类型 | 结构的读写能力 |
STRING | 可以是字符串、整数或者浮点数 | 对整个或部分字符串操作,增减整数和浮点数 |
LIST | 一个链表,链表上的每个节点都包含了一个字符串 | 可从两端弹出或压入数据,基于坐标截取,读取单个或多个元素,按值查找或删除键 |
SET | 无序不重复字符串的集合 | 增加,获取或删除单个元素,检测成员关系,交、并、差操作,获取随机元素 |
HASH | 无序键值对哈希表 | 增加,获取或删除单个键值对,获取所有键值对 |
ZSET(有序集合) | 字符串与浮点数分值之间的有序映射,元素的顺序由分值的大小决定 | 增加,获取或删除单个元素,根据分值范围或者成员来获取元素 |
1.字符串STRING
首先, 我们来了解一下Redis中最简单的结构:字符串STRING。
Redis的字符串和其他编程语言或者其他键值存储提供的字符串非常相似,图中键名为hello,类型为string,值为world。
字符串支持的操作方式和其他键值对存储的操作方式一样。我们可以GET
valeus,SET
values, DEL
values.
命令 | 作用 |
GET | 获取存储在给定键中的值 |
SET | 设置存储在给定键中的值 |
DEL | 删除存储在给定键中的值(适用于所有类型) |
使用示例(图):
在Redis中,字符串可以存储3种类型的值:字节串、整数、浮点数。
我们可以通过给定一个任意的数值,对存储着整数或者浮点数的字符串执行自增或者自减操作,在有需要的时候,Redis还会将整数转化为浮点数。整数的取值范围和系统的长整数的取值范围相同(在32位系统上,整数就是32位有符号整数,在64位系统上,整数就是64位有符号整数),而浮点数的取值范围和精度则IEEE754标准的双精度浮点数相同。Redis明确的区分字节串、整数和浮点数的做法是一种优势,比起只能够存储字节串的做法,Redis的做法在数据表现方面具有更大的灵活性。
命令 | 用法示例和描述 |
---|---|
INCR | INCR key-name —— 使key存储的值加1 |
DECR | DECR key-name —— 使key存储的值减1 |
INCRBY | INCRBY key-name amount —— 使key存储的值增加给定的整数 |
DECRBY | DECRBY key-name amount —— 使key存储的值减少给定的整数 |
INCRBYFLOAT | INCRBYFLOAT key-name amount —— 使key存储的值增加给定的浮点数(Redis 2.6以上可用) |
当我们将一个值存储到Redis字符串里的时候,如果这个值可以被解释为是十进制的整数或者浮点数,那么Redis会察觉到这一点,并允许我们对这个字符串执行各种自增自减操作。如果我们对一个不存在的键或者保存了空串的键执行自增或者自减操作,那么Redis在执行操作的时候会将这个键的值当做0来处理。如果我们尝试对一个值无法被解释成整数或者浮点数的字符串执行自增或者自减操作,那么Redis将向我们返回一个错误。下图展示了一些字符串自增自减的例子。
除了自增自减操作外,Redis还拥有对字符串的其中一部分内容进行读取或者写入的操作(这些操作同样可以用于整数和浮点数,但这种做法并不常见)。
命令 | 用法示例和描述 |
---|---|
APPEND | APPEND key-name value —— 使key存储的字符串追加给定的值 |
GETRANGE | GETRANGE key-name start end —— 获取从start到end的所包含的子字符串 |
SETRANGE | SETRANGE key-name offset value —— 使子字符串从给定位置开始覆盖为给定值 |
GETBIT | GETBIT key-name offset —— 将字节串作为比特串处理,并返回字符串中给定比特偏移量的比特值 |
SETBIT | SETBIT key-name offset value —— 将字节串作为比特串处理,设置指定比特偏移量的值为给定比特 |
BITCOUNT | BITCOUNT key-name [start end] —— 统计字符串中比特值为1的数量,可选参数为起始和结束位 |
BITOP | BITOP operation dest-key key-name [key-name ...] —— 在提供的字符串执行一个位操作运算,AND, OR, XOR,或NOT, 存储结果到目标key |
在使用SETRANGE或者SETBIT命令对字符串进行写入的时候,如果字符串当前的长度不能满足写入的要求,那么Redis会自动的使用空字节(null)来将字符串扩展至所需的长度,然后才执行写入或者更新操作。在使用GETRANGE读取字符串的时候,超出字符串末尾的数据会被视为是空串,而在使用GETBIT读取二进制位串的时候,传出字符串末尾的二进制位会被视为0。下图为字符串处理的使用示例。
2.列表LIST
Redis的列表结构可以有序的存储多个字符串。
Redis列表可以执行的操作和很多编程语言里面的列表操作非常相似。我们可以压入项到队列头或尾使用LPUSH/RPUSH
. 我们可以从头或尾弹出项使用LPOP/RPOP,
我们可以获取给定坐标的项使用LINDEX
,我们可以获取一个范围的项使用LRANGE
。
命令 | 用法示例和描述 |
---|---|
RPUSH | RPUSH key-name value [value ...] —— 将一个或者多个值推入列表的右端 |
LPUSH | LPUSH key-name value [value ...] —— 将一个或者多个值推入列表的左端 |
RPOP | RPOP key-name —— 删除并返回列表最右侧的元素 |
LPOP | LPOP key-name —— 删除并返回列表最左侧的元素 |
LINDEX | LINDEX key-name offset —— 返回指定位置的元素 |
LRANGE | LRANGE key-name start end —— 返回指定起止范围内的元素,包括start和end所在位置的元素 |
LTRIM | LTRIM key-name start end —— 保留指定范围内的元素,包括start和end所在位置的元素 |
下面是列表命令的操作实例
列表的优点
是可以包含多个相同的字符串值。集合是与列表相似的数据结构
,但是集合
中每个元素是唯一的。
3.集合SET
Redis的集合以无序的方式来存储多个各不相同的元素。
因为Redis中集合
类型是无序的,所以我们不能像列表
那样从末尾push和pop项。我们加入和删除元素的值使用SADD
和SREM
命令。我们可以通过SISMEMBER
命令查找是否一个元素在这个集合,也可以使用SMEMBERS
命令获取整个集合(对于大型集合这个操作很慢,请小心操作)。
下图是一些集合的常用命令和使用示例:
命令 | 用法示例描述 |
---|---|
SADD | SADD key-name item [item ...] —— 将一个或多个元素添加到集合里面,并返回被添加元素中原本并不存在与集合里面的元素数量 |
SREM | SREM key-name item [item ...] —— 删除元素并返回被删除的元素的数量 |
SISMEMBER | SISMEMBER key-name item —— 返回一个元素是否在集合 中 |
SCARD | SCARD key-name —— 返回集合 中元素的数量 |
SMEMBERS | SMEMBERS key-name —— 返回集合 中所有的元素 |
SRANDMEMBER | SRANDMEMBER key-name [count] —— 从集合 中返回一个或多个随机的元素。当count是正数时,Redis返回无重复的随机元素,当count是负数时,Redis返回随机元素,可能有重复 |
SPOP | SPOP key-name —— 移除并返回集合 中随机的一个元素 |
SMOV | SMOVE source-key dest-key item —— 如果source中有item,移除该item并加入到destination,如果移动成功则返回该item |
通过上面的命令,我们已经可以将各不相同的元素添加到集合里面,但集合真正厉害的地方在于组合和关联多个集合。
命令 | 用法示例和描述 |
---|---|
SDIFF | SDIFF key-name [key-name ...] —— 返回存在于第一个集合 中,不在其他集合中 的元素(数学中的差集运算) |
SDIFFSTORE | SDIFFSTORE dest-key key-name [key-name ...] —— 将存在于第一个集合中不在其他集合中的元素存储在dest-key中(数学中的差集运算) |
SINTER | SINTER key-name [key-name ...] —— 返回在所有集合中都存在的元素(数学中的交集运算) |
SINTERSTORE | SINTERSTORE dest-key key-name [key-name ...] —— 将所集合中都存在的元素存储在dest-key中(数学中的交集运算) |
SUNION | SUNION key-name [key-name ...] —— 返回至少在一个集合中存在的元素(数学中的并集运算) |
SUNIONSTORE | SUNIONSTORE dest-key key-name [key-name ...] —— 将至在一个集合中存在的元素存储在dest-key中(数学中的并集运算) |
演示图例:
4.散列HASH
Redis的散列可以存储多个键值对之间的映射,我们可以将多个键值对存储到一个Redis键里面。和字符串一样,散列存储的值既可以是字符串,也可以是数字值,并且我们同样可以对散列存储的数字值执行自增或者自减操作。下图展示了一个Redis散列:
接下来介绍一些散列命令,包括增加和删除键值对,获取所有键值对的命令,以及对键值对的自增或者自减命令。
命令 | 用法示例和描述 |
---|---|
HMGET | HMGET key-name key [key ...] —— 获取散列中的一个或者多个键的值 |
HMSET | HMSET key-name key value [key value ...] —— 设置散列中的一个或者多个键的值 |
HDEL | HDEL key-name key [key ...] —— 删除散列中的一个或者多个键值对,返回成功找到并删除的键值对数量 |
HLEN | HLEN key-name —— 返回散列中的键值对数量 |
再介绍一些散列的几个批量操作命令,以及一些和字符串操作类似的散列命令。
命令 | 用法示例和描述 |
---|---|
HEXISTS | HEXISTS key-name key —— 返回给定键是否存在于散列中 |
HKEYS | HKEYS key-name —— 获取散列中的所有键 |
HVALS | HVALS key-name —— 获取散列中的所有值 |
HGETALL | HGETALL key-name —— 获取散列中的所有键值对 |
HINCRBY | HINCRBY key-name key increment —— 使键key中的值增加指定的整数increment |
HINCRBYFLOAT | HINCRBYFLOAT key-name key increment —— 使键key中的值增加指定的浮点数increment |
尽管有HGETALL命令,但是HKEYS和HVALUES也是非常有用的:如果散列包含的值非常大,那么我们可以先使用HKEYS获取散列包含的所有键,然后再使用HGET来获取每个键的值,从而避免因为一次获取多个大体积的值而导致的服务器阻塞。
5.有序集合ZSET
像散列一样,有序集合
同样保存一种键值对类型。keys(称为成员(members))是唯一的,values(称为分值(scores))限定只能是浮点数。
有序集合是Redis中唯一一个既可以根据成员访问元素(和散列一样),有可以根据分值以及分值的排列顺序来访问元素的结构。下图为有序集合的常用命令和操作实例:
命令 | 用法示例和描述 |
---|---|
ZADD | ZADD key-name score member [score member ...] —— 将带有给定分值的成员添加到有序集合里面 |
ZRED | ZREM key-name member [member ...] —— 从有序集合中移除指定成员,返回移除的成员数量 |
ZCARD | ZCARD key-name —— 返回有序集合中包含的成员数量 |
ZINCRBY | ZINCRBY key-name increment member —— 将成员member的分值增加increment |
ZCOUNT | ZCOUNT key-name min max —— 返回分值在最小值和最大值之间的成员数量 |
ZRANK | ZRANK key-name member —— 返回成员member在有序集合中的排名 |
ZSCORE | ZSCORE key-name member —— 返回有序集合中成员member的分值 |
ZRANGE | ZRANGE key-name start stop [WITHSCORES] —— 返回有序集合中排名介于start和stop之前的成员,如果给定了可选的WITHSCORES选项,那么会将成员的分值一并返回 |
接下来介绍一些有序集合的范围型的获取删除命令和并集、交集命令。
命令 | 用法示例和描述 | ||
---|---|---|---|
ZREVRANK | ZREVRANK key-name member —— 返回逆序排序的member的序号 | ||
ZREVRANGE | ZREVRANGE key-name start stop [WITHSCORES] —— 获取给定范围的members,以逆序排列 | ||
ZRANGEBYSCORE | ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count] —— 获取min和max之间的members | ||
ZREVRANGEBYSCORE | ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count] —— 获取逆序排序的min和max之间的members | ||
ZREMRANGEBYRANK | ZREMRANGEBYRANK key-name start stop —— 删除起始范围内的items | ||
ZREMRANGEBYSCORE | ZREMRANGEBYSCORE key-name min max —— 删除在min和max之间的scores的items | ||
ZINTERSTORE | ZINTERSTORE dest-key key-count key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX] —— Performs a SET -like intersection of the provided ZSETs——对给定的有序集合执行类似于集合的交集运算 | ||
ZUNIONSTORE | ZUNIONSTORE dest-key key-count key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX] —— Perform a SET-like union of the provided ZSETs——对给定的有序集合执行类似于集合的并集运算 |
下图展示了ZINTERSTORE命令和ZUNIONSTORE命令的用法:
其中conn.zinterstore('zset-i',['zset-1','zset-2'])作用是使同时存在于zset-1和zset-2里面的元素被添加到zset-里面,由于使用的是默认的聚合函数sum,所有输出的成员的分值都是通过加法计算得出的,下图为执行的过程展示:
而conn.zunionstore('zset-u',['zset-1','zset-2'],aggregate='min')的作用是将存在于zset-1或者zset-2里面的元素通过min函数组合到zset-u里面,下图为执行的过程展示:
最后conn.zunionstore('zset-u2',['zset-1','zset-2','set-1'])命令基于“集合可以作为ZUNIONSTORE和ZINTERSTORE操作的输入”这一事实,将所有存在于zset-1,zset-2或者set-1里面的元素都添加到zset-u2里面。下图为执行过程的展示:
到此为止,Redis的5中数据结构和相应的命令已经全部介绍完了。接下来再介绍几个常用的其他命令。
6.其他命令
1.排序
Redis的排序操作可以根据某种比较规则对一系列元素进行排序。类似于关系型数据库的order bu字句。
命令 | 用法示例和描述 |
---|---|
SORT | SORT source-key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern ...]] [ASC|DESC] [ALPHA] [STORE dest-key] —— 根据给定的选项,对输入的列表、集合或者有序集合进行排序,然后返回或者存储排序的结果 |
演示示例的开始,设置了一些初始数据,然后对这些数据进行了数值排序和字符串排序(使用alpha关键字对元素进行字符串排序),最后的代码演示了如何通过SORT命令的特殊语法来将散列存储的数据作为权重进行排序,以及怎样获取并返回散列存储的数据。
2.键的过期时间
在使用Redis存储数据的时候,有些数据可能再某个时间点过后就不再有用了,我们可以使用DEL命令显示的删除这些无用数据,也可以通过Redis的过期时间特性来让一个键在给定的时限之后自动被删除。
命令 | 用法示例和描述 |
---|---|
PERSIST | PERSIST key-name —— 移除键的过期时间 |
TTL | TTL key-name —— 查看给定键距离过期时间还有多少秒 |
EXPIRE | EXPIRE key-name seconds —— 让给定键在指定的秒数后过期 |
EXPIREAT | EXPIREAT key-name timestamp —— 以指定的Unix时间戳形式设置过期时间 |
PTTL | PTTL key-name —— 查看给定键距离过期时间还有多少毫秒(Redis 2.6以后可用) |
PEXPIRE | PEXPIRE key-name milliseconds —— 让给定键在指定的毫秒数后过期(Redis 2.6以后可用) |
PEXPIREAT | PEXPIREAT key-name timestamp-milliseconds —— 同EXPIREAT,时间戳格式为毫秒(Redis 2.6以后可用) |
下图是对键执行过期时间操作的实例:
Redis为每种结构都提供了大量的处理命令,本文介绍了一部分常用命令,其余的命令可以在http://redis.io/commands看到。
参考:
https://www.gitbook.com/book/abcfy2/redis-in-action-reading-notes
转载请注明出处。