Redis中的数据类型与操作可以总结为"5+1"操作-----五种数据类型以及key的操作。这里的数据类型指的是值类型,如String、HASH、Set、Zset以及list。从宏观来看,Redis是K-V模式。只是V类型不同,称之为不同数据类型。
Redis官网地址:https://redis.io/
【1】Key的常见操作
① KEYS pattern
查找所有符合给定模式 pattern 的 key 。
KEYS * 匹配数据库中所有 key 。
KEYS h?llo 匹配 hello , hallo 和 hxllo 等。
KEYS h*llo 匹配 hllo 和 heeeeello 等。
KEYS h[ae]llo 匹配 hello 和 hallo ,但不匹配 hillo 。
特殊符号用 \ 隔开。
示例如下:
redis> KEYS *o*
1) "four"
2) "two"
3) "one"
redis> KEYS t??
1) "two"
redis> KEYS t[w]*
1) "two"
redis> KEYS * # 匹配数据库内所有 key
1) "four"
2) "three"
3) "two"
4) "one"
② exists key
判断某个key是否存在。
返回值:若 key 存在,返回 1 ,否则返回 0 。
③ move key db
将当前数据库的 key 移动到给定的数据库 db 当中(当前库就没有了,被移除了)。
如果当前数据库(源数据库)和给定数据库(目标数据库)有相同名字的给定 key ,或者 key 不存在于当前数据库,那么 MOVE 没有任何效果。
因此,也可以利用这一特性,将 MOVE 当作锁(locking)原语(primitive)。
示例如下:
# key 存在于当前数据库
redis> SELECT 0 # redis默认使用数据库 0,为了清晰起见,这里再显式指定一次。
OK
redis> SET song "secret base - Zone"
OK
redis> MOVE song 1 # 将 song 移动到数据库 1
(integer) 1
redis> EXISTS song # song 已经被移走
(integer) 0
redis> SELECT 1 # 使用数据库 1
OK
redis:1> EXISTS song # 证实 song 被移到了数据库 1 (注意命令提示符变成了"redis:1",表明正在使用数据库 1)
(integer) 1
# 当 key 不存在的时候
redis:1> EXISTS fake_key
(integer) 0
redis:1> MOVE fake_key 0 # 试图从数据库 1 移动一个不存在的 key 到数据库 0,失败
(integer) 0
redis:1> select 0 # 使用数据库0
OK
redis> EXISTS fake_key # 证实 fake_key 不存在
(integer) 0
# 当源数据库和目标数据库有相同的 key 时
redis> SELECT 0 # 使用数据库0
OK
redis> SET favorite_fruit "banana"
OK
redis> SELECT 1 # 使用数据库1
OK
redis:1> SET favorite_fruit "apple"
OK
redis:1> SELECT 0 # 使用数据库0,并试图将 favorite_fruit 移动到数据库 1
OK
redis> MOVE favorite_fruit 1 # 因为两个数据库有相同的 key,MOVE 失败
(integer) 0
redis> GET favorite_fruit # 数据库 0 的 favorite_fruit 没变
"banana"
redis> SELECT 1
OK
redis:1> GET favorite_fruit # 数据库 1 的 favorite_fruit 也是
"apple"
④ persist key
移除给定 key 的生存时间,将这个 key 从『易失的』(带生存时间 key )转换成『持久的』(一个不带生存时间、永不过期的 key )。
⑤ expire key seconds
为给定 key 设置生存时间,当 key 过期时(生存时间为 0 ),它会被自动删除。
在 Redis 中,带有生存时间的 key 被称为『易失的』(volatile)。
生存时间可以通过使用 DEL 命令来删除整个 key 来移除,或者被 SET 和 GETSET 命令覆写(overwrite),这意味着,如果一个命令只是修改(alter)一个带生存时间的 key 的值而不是用一个新的 key 值来代替(replace)它的话,那么生存时间不会被改变。
比如说,对一个 key 执行 INCR 命令,对一个列表进行 LPUSH 命令,或者对一个哈希表执行 HSET 命令,这类操作都不会修改 key 本身的生存时间。
另一方面,如果使用 RENAME 对一个 key 进行改名,那么改名后的 key 的生存时间和改名前一样。
RENAME 命令的另一种可能是,尝试将一个带生存时间的 key 改名成另一个带生存时间的 another_key ,这时旧的 another_key (以及它的生存时间)会被删除,然后旧的 key 会改名为 another_key ,因此,新的 another_key 的生存时间也和原本的 key 一样。
使用 PERSIST 命令可以在不删除 key 的情况下,移除 key 的生存时间,让 key 重新成为一个『持久的』(persistent) key 。
- 更新生存时间
可以对一个已经带有生存时间的 key 执行 EXPIRE 命令,新指定的生存时间会取代旧的生存时间。
- 过期时间的精确度
在 Redis 2.4 版本中,过期时间的延迟在 1 秒钟之内 —— 也即是,就算 key 已经过期,但它还是可能在过期之后一秒钟之内被访问到,而在新的 Redis 2.6 版本中,延迟被降低到 1 毫秒之内。
示例如下:
redis> SET cache_page "www.google.com"
OK
redis> EXPIRE cache_page 30 # 设置过期时间为 30 秒
(integer) 1
redis> TTL cache_page # 查看剩余生存时间
(integer) 23
redis> EXPIRE cache_page 30000 # 更新过期时间
(integer) 1
redis> TTL cache_page
(integer) 29996
⑥ EXPIREAT key timestamp
EXPIREAT 的作用和 EXPIRE 类似,都用于为 key 设置生存时间。不同在于 EXPIREAT 命令接受的时间参数是 UNIX 时间戳(unix timestamp)。
示例如下:
redis> SET cache www.google.com
OK
redis> EXPIREAT cache 1355292000 # 这个 key 将在 2012.12.12 过期
(integer) 1
redis> TTL cache
(integer) 45081860
⑦ PEXPIRE key milliseconds
这个命令和 EXPIRE 命令的作用类似,但是它以毫秒为单位设置 key 的生存时间,而不像 EXPIRE 命令那样,以秒为单位。
示例如下:
redis> SET mykey "Hello"
OK
redis> PEXPIRE mykey 1500
(integer) 1
redis> TTL mykey # TTL 的返回值以秒为单位
(integer) 2
redis> PTTL mykey # PTTL 可以给出准确的毫秒数
(integer) 1499
⑧ PEXPIREAT key milliseconds-timestamp
这个命令和 EXPIREAT 命令类似,但它以毫秒为单位设置 key 的过期 unix 时间戳,而不是像 EXPIREAT 那样,以秒为单位。
示例如下:
redis> SET mykey "Hello"
OK
redis> PEXPIREAT mykey 1555555555005
(integer) 1
redis> TTL mykey # TTL 返回秒
(integer) 223157079
redis> PTTL mykey # PTTL 返回毫秒
(integer) 223157079318
⑨ ttl key
以秒为单位,返回给定 key 的剩余生存时间(TTL, time to live)。
返回值:
当 key 不存在时,返回 -2 。
当 key 存在但没有设置剩余生存时间时,返回 -1 。
否则,以秒为单位,返回 key 的剩余生存时间。
ttl keyName
⑩ pttl key
这个命令类似于 ttl命令,但它以毫秒为单位返回 key 的剩余生存时间,而不是像 ttl命令那样,以秒为单位。
返回值:
当 key 不存在时,返回 -2 。
当 key 存在但没有设置剩余生存时间时,返回 -1 。
否则,以毫秒为单位,返回 key 的剩余生存时间。
(11)type key
返回 key 所储存的值的类型。
返回值:
none (key不存在)
string (字符串)
list (列表)
set (集合)
zset (有序集)
hash (哈希表)
(12)dump key
序列化给定 key ,并返回被序列化的值,使用 RESTORE 命令可以将这个值反序列化为 Redis 键。
序列化生成的值有以下几个特点:
- 它带有 64 位的校验和,用于检测错误, RESTORE 在进行反序列化之前会先检查校验和。
- 值的编码格式和 RDB 文件保持一致。
- RDB 版本会被编码在序列化值当中,如果因为 Redis 的版本不同造成 RDB 格式不兼容,那么 Redis 会拒绝对这个值进行反序列化操作。
序列化的值不包括任何生存时间信息。
示例如下:
redis> SET greeting "hello, dumping world!"
OK
redis> DUMP greeting
"\x00\x15hello, dumping world!\x06\x00E\xa0Z\x82\xd8r\xc1\xde"
redis> DUMP not-exists-key
(nil)
(13)DEL key [key …]
删除给定的一个或多个 key 。
不存在的 key 会被忽略。
实例如下:
# 删除单个 key
redis> SET name huangz
OK
redis> DEL name
(integer) 1
# 删除一个不存在的 key
redis> EXISTS phone
(integer) 0
redis> DEL phone # 失败,没有 key 被删除
(integer) 0
# 同时删除多个 key
redis> SET name "redis"
OK
redis> SET type "key-value store"
OK
redis> SET website "redis.com"
OK
redis> DEL name type website
(integer) 3
【2】String
string是redis中最基本的数据类型,你可以理解成与memcached一模一样的类型,一个key对应一个value。一个redis中字符串value最多可以是512M。
string类型是二进制安全的。意思是redis的string是可以包含任何数据的,比如jpg图片或者序列化的对象。
(1)GET key
返回 key 所关联的字符串值。如果 key 不存在那么返回特殊值 nil 。
假如 key 储存的值不是字符串类型,返回一个错误,因为 GET 只能用于处理字符串值。
(2)SET key value [EX seconds] [PX milliseconds] [NX|XX]
将字符串值 value 关联到 key 。如果 key 已经持有其他值, SET 就覆写旧值,无视类型。
对于某个原本带有生存时间(TTL)的键来说, 当 SET 命令成功在这个键上执行时, 这个键原有的 TTL 将被清除。
EX second :设置键的过期时间为 second 秒。 SET key value EX second 效果等同于 SETEX key second value 。
PX millisecond :设置键的过期时间为 millisecond 毫秒。 SET key value PX millisecond 效果等同于 PSETEX key millisecond value 。
NX :只在键不存在时,才对键进行设置操作。 SET key value NX 效果等同于 SETNX key value 。
XX :只在键已经存在时,才对键进行设置操作。
因为 SET 命令可以通过参数来实现和 SETNX 、 SETEX 和 PSETEX 三个命令的效果,所以将来的 Redis 版本可能会废弃并最终移除 SETNX 、 SETEX 和 PSETEX 这三个命令。
返回值:
在 Redis 2.6.12 版本以前, SET 命令总是返回 OK 。
从 Redis 2.6.12 版本开始, SET 在设置操作成功完成时,才返回 OK 。
如果设置了 NX 或者 XX ,但因为条件没达到而造成设置操作未执行,那么命令返回空批量回复(NULL Bulk Reply)。
(3)SETEX key second value
将值 value 关联到 key ,并将 key 的生存时间设为 seconds (以秒为单位)。
如果 key 已经存在, SETEX 命令将覆写旧值。
这个命令类似于以下两个命令:
SET key value
EXPIRE key seconds # 设置生存时间
不同之处是, SETEX 是一个原子性(atomic)操作,关联值和设置生存时间两个动作会在同一时间内完成,该命令在 Redis 用作缓存时,非常实用。
返回值:
设置成功时返回 OK 。
当 seconds 参数不合法时,返回一个错误。
(4)SETNX key value
将 key 的值设为 value ,当且仅当 key 不存在。
若给定的 key 已经存在,则 SETNX 不做任何动作。
SETNX 是『SET if Not eXists』(如果不存在,则 SET)的简写。
返回值:
设置成功,返回 1 。
设置失败,返回 0 。
(5)APPEND key value
如果 key 已经存在并且是一个字符串, APPEND 命令将 value 追加到 key 原来的值的末尾。
如果 key 不存在, APPEND 就简单地将给定 key 设为 value ,就像执行 SET key value 一样。
返回值:
追加 value 之后, key 中字符串的长度。
(6)GETSET key value
将给定 key 的值设为 value ,并返回 key 的旧值(old value)。
当 key 存在但不是字符串类型时,返回一个错误。当 key 没有旧值时,也即是, key 不存在时,返回 nil 。
简单一句话,先get然后立即set。
(7)MSET key value [key value …]
同时设置一个或多个 key-value 对。
如果某个给定 key 已经存在,那么 MSET 会用新值覆盖原来的旧值,如果这不是你所希望的效果,请考虑使用 MSETNX 命令:它只会在所有给定 key 都不存在的情况下进行设置操作。
MSET 是一个原子性(atomic)操作,所有给定 key 都会在同一时间内被设置,某些给定 key 被更新而另一些给定 key 没有改变的情况,不可能发生。
实例如下:
redis> MSET date "2012.3.30" time "11:00 a.m." weather "sunny"
OK
redis> MGET date time weather
1) "2012.3.30"
2) "11:00 a.m."
3) "sunny"
# MSET 覆盖旧值例子
redis> SET google "google.hk"
OK
redis> MSET google "google.com"
OK
redis> GET google
"google.com"
返回值:
总是返回 OK (因为 MSET 不可能失败)
(8)GETRANGE key start end
返回 key 中字符串值的子字符串,字符串的截取范围由 start 和 end 两个偏移量决定(包括 start 和 end 在内)。
负数偏移量表示从字符串最后开始计数, -1 表示最后一个字符, -2 表示倒数第二个,以此类推。
GETRANGE 通过保证子字符串的值域(range)不超过实际字符串的值域来处理超出范围的值域请求。
在 <= 2.0 的版本里,GETRANGE 被叫作 SUBSTR。
实例如下:
redis> SET greeting "hello, my friend"
OK
redis> GETRANGE greeting 0 4 # 返回索引0-4的字符,包括4。
"hello"
redis> GETRANGE greeting -1 -5 # 不支持回绕操作
""
redis> GETRANGE greeting -3 -1 # 负数索引
"end"
redis> GETRANGE greeting 0 -1 # 从第一个到最后一个
"hello, my friend"
redis> GETRANGE greeting 0 1008611 # 值域范围不超过实际字符串,超过部分自动被忽略
"hello, my friend"
(9)SETRANGE key offset value
用 value 参数覆写(overwrite)给定 key 所储存的字符串值,从偏移量 offset 开始。
不存在的 key 当作空白字符串处理。
SETRANGE 命令会确保字符串足够长以便将 value 设置在指定的偏移量上,如果给定 key 原来储存的字符串长度比偏移量小(比如字符串只有 5 个字符长,但你设置的 offset 是 10 ),那么原字符和偏移量之间的空白将用零字节(zerobytes, “\x00” )来填充。
注意你能使用的最大偏移量是 2^29-1(536870911) ,因为 Redis 字符串的大小被限制在 512 兆(megabytes)以内。如果你需要使用比这更大的空间,你可以使用多个 key 。
当生成一个很长的字符串时,Redis 需要分配内存空间,该操作有时候可能会造成服务器阻塞(block)。在2010年的Macbook Pro上,设置偏移量为 536870911(512MB 内存分配),耗费约 300 毫秒, 设置偏移量为 134217728(128MB 内存分配),耗费约 80 毫秒,设置偏移量 33554432(32MB 内存分配),耗费约 30 毫秒,设置偏移量为 8388608(8MB 内存分配),耗费约 8 毫秒。 注意若首次内存分配成功之后,再对同一个 key 调用 SETRANGE 操作,无须再重新内存。
实例如下:
# 对非空字符串进行 SETRANGE
redis> SET greeting "hello world"
OK
redis> SETRANGE greeting 6 "Redis"
(integer) 11
redis> GET greeting
"hello Redis"
# 对空字符串/不存在的 key 进行 SETRANGE
redis> EXISTS empty_string
(integer) 0
redis> SETRANGE empty_string 5 "Redis!" # 对不存在的 key 使用 SETRANGE
(integer) 11
redis> GET empty_string # 空白处被"\x00"填充
"\x00\x00\x00\x00\x00Redis!"
返回值:被 SETRANGE 修改之后,字符串的长度。
一个很重要的作用是,如果某个key-value已经设置了生存时间,该方法不会重置key-value的生存时间!!!
(10)INCR key
原子性地将 key 中储存的数字值增一,注意是原子操作。
如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作。
如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。
本操作的值限制在 64 位(bit)有符号数字表示之内。
这是一个针对字符串的操作,因为 Redis 没有专用的整数类型,所以 key 内储存的字符串被解释为十进制 64 位有符号整数来执行 INCR 操作。
实例如下:
redis> SET page_view 20
OK
redis> INCR page_view
(integer) 21
redis> GET page_view # 数字值在 Redis 中以字符串的形式保存
"21"
返回值:
执行 INCR 命令之后 key对应的value 的值。
(11)DECR key
原子性地将 key 中储存的数字值减一,注意是原子操作。
如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 DECR 操作。
如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。
本操作的值限制在 64 位(bit)有符号数字表示之内。
关于递增(increment) / 递减(decrement)操作的更多信息,请参见 INCR 命令。
实例如下:
# 对存在的数字值 key 进行 DECR
redis> SET failure_times 10
OK
redis> DECR failure_times
(integer) 9
# 对不存在的 key 值进行 DECR
redis> EXISTS count
(integer) 0
redis> DECR count
(integer) -1
# 对存在但不是数值的 key 进行 DECR
redis> SET company YOUR_CODE_SUCKS.LLC
OK
redis> DECR company
(error) ERR value is not an integer or out of range
返回值:
执行 DECR 命令之后 key 的值。
(12)INCRBY key increment
原子性地将 key 所储存的值加上增量 increment 。
如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCRBY 命令。
如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。
本操作的值限制在 64 位(bit)有符号数字表示之内。
关于递增(increment) / 递减(decrement)操作的更多信息,参见 INCR 命令。
实例如下:
# key 存在且是数字值
redis> SET rank 50
OK
redis> INCRBY rank 20
(integer) 70
redis> GET rank
"70"
# key 不存在时
redis> EXISTS counter
(integer) 0
redis> INCRBY counter 30
(integer) 30
redis> GET counter
"30"
# key 不是数字值时
redis> SET book "long long ago..."
OK
redis> INCRBY book 200
(error) ERR value is not an integer or out of range
返回值:
加上 increment 之后, key对应value 的值。
(13)DECRBY key decrement
原子性地将 key 所储存的值减去减量 decrement 。
如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 DECRBY 操作。
如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。
本操作的值限制在 64 位(bit)有符号数字表示之内。
实例如下:
# 对已存在的 key 进行 DECRBY
redis> SET count 100
OK
redis> DECRBY count 20
(integer) 80
# 对不存在的 key 进行DECRBY
redis> EXISTS pages
(integer) 0
redis> DECRBY pages 10
(integer) -10
返回值:
减去 decrement 之后, key 对应value的值。
redis中incr、incrby、decr、decrby属于string数据结构,它们是原子性递增或递减操作。
- incr递增1并返回递增后的结果;
- incrby根据指定值做递增或递减操作并返回递增或递减后的结果(incrby递增或递减取决于传入值的正负);
- decr递减1并返回递减后的结果;
- decrby根据指定值做递增或递减操作并返回递增或递减后的结果(decrby递增或递减取决于传入值的正负);
在设计秒杀方案时,可能会用到这一特性。
【3】Hash
Redis hash是一个键值对集合,是一个string类型的field和value的映射表。hash特别适合用于存储对象,类似java 里面的Map<String,Object>
。
简而言之,KV模式不变,但V是一个键值对(field – value)。
(1)HSET key field value
将哈希表 key 中的域 field 的值设为 value 。
如果 key 不存在,一个新的哈希表被创建并进行 HSET 操作。
如果域 field 已经存在于哈希表中,旧值将被覆盖。
返回值:
如果 field 是哈希表中的一个新建域,并且值设置成功,返回 1 。
如果哈希表中域 field 已经存在且旧值已被新值覆盖,返回 0 。
实例如下:
redis> HSET website google "www.g.cn" # 设置一个新域
(integer) 1
redis> HSET website google "www.google.com" # 覆盖一个旧域
(integer) 0
(2)HGET key field
返回哈希表 key 中给定域 field 的值。
返回值:
给定域的值。当给定域不存在或是给定 key 不存在时,返回 nil 。
127.0.0.1:6379> hget website google
"www.g.cn"
127.0.0.1:6379> hget google website
(nil)
(3)HEXISTS key field
查看哈希表 key 中,给定域 field 是否存在。
返回值:
如果哈希表含有给定域,返回 1 。
如果哈希表不含有给定域,或 key 不存在,返回 0 。
实例如下:
127.0.0.1:6379> HEXISTS google website
(integer) 0
127.0.0.1:6379> HEXISTS website google
(integer) 1
(4)HMSET key field value [field value …]
同时将多个 field-value (域-值)对设置到哈希表 key 中。
此命令会覆盖哈希表中已存在的域。
如果 key 不存在,一个空哈希表被创建并执行 HMSET 操作。
返回值:
如果命令执行成功,返回 OK 。当 key 不是哈希表(hash)类型时,返回一个错误。
实例如下:
redis> HMSET website baidu "www.baidu.com" taobao "www.taobao.com"
OK
(5)HMGET key field [field …]
返回哈希表 key 中,一个或多个给定域的值。
如果给定的域不存在于哈希表,那么返回一个 nil 值。
因为不存在的 key 被当作一个空哈希表来处理,所以对一个不存在的 key 进行 HMGET 操作将返回一个只带有 nil 值的表。
返回值:
一个包含多个给定域的关联值的表,表值的排列顺序和给定域参数的请求顺序一样。
127.0.0.1:6379> hmget website baidu taobao google
1) "www.baidu.com"
2) "www.taobao.com"
3) "www.g.cn"
(6)HGETALL key
返回哈希表 key 中,所有的域和值。
在返回值里,紧跟每个域名(field name)之后是域的值(value),所以返回值的长度是哈希表大小的两倍。
返回值:
以列表形式返回哈希表的域和域的值。若 key 不存在,返回空列表。
实例如下:
127.0.0.1:6379> HGETALL website
1) "google"
2) "www.g.cn"
3) "baidu"
4) "www.baidu.com"
5) "taobao"
6) "www.taobao.com"
(7)HINCRBY key field increment
为哈希表 key 中的域 field 的值加上增量 increment 。
增量也可以为负数,相当于对给定域进行减法操作。
如果 key 不存在,一个新的哈希表被创建并执行 HINCRBY 命令。
如果域 field 不存在,那么在执行命令前,域的值被初始化为 0 。
对一个储存字符串值的域 field 执行 HINCRBY 命令将造成一个错误。
本操作的值被限制在 64 位(bit)有符号数字表示之内。
返回值:
执行 HINCRBY 命令之后,哈希表 key 中域 field 的值。
实例如下:
# increment 为正数
redis> HEXISTS counter page_view # 对空域进行设置
(integer) 0
redis> HINCRBY counter page_view 200
(integer) 200
redis> HGET counter page_view
"200"
# increment 为负数
redis> HGET counter page_view
"200"
redis> HINCRBY counter page_view -50
(integer) 150
redis> HGET counter page_view
"150"
# 尝试对字符串值的域执行HINCRBY命令
redis> HSET myhash string hello,world # 设定一个字符串值
(integer) 1
redis> HGET myhash string
"hello,world"
redis> HINCRBY myhash string 1 # 命令执行失败,错误。
(error) ERR hash value is not an integer
redis> HGET myhash string # 原值不变
"hello,world"
(8)HINCRBYFLOAT key field increment
为哈希表 key 中的域 field 加上浮点数增量 increment 。
如果哈希表中没有域 field ,那么 HINCRBYFLOAT 会先将域 field 的值设为 0 ,然后再执行加法操作。
如果键 key 不存在,那么 HINCRBYFLOAT 会先创建一个哈希表,再创建域 field ,最后再执行加法操作。
当以下任意一个条件发生时,返回一个错误:
- 域 field 的值不是字符串类型(因为 redis 中的数字和浮点数都以字符串的形式保存,所以它们都属于字符串类型)
- 域 field 当前的值或给定的增量 increment 不能解释(parse)为双精度浮点数(double precision floating point number)
返回值:
执行加法操作之后 field 域的值。
实例如下:
# 值和增量都是普通小数
redis> HSET mykey field 10.50
(integer) 1
redis> HINCRBYFLOAT mykey field 0.1
"10.6"
# 值和增量都是指数符号
redis> HSET mykey field 5.0e3
(integer) 0
redis> HINCRBYFLOAT mykey field 2.0e2
"5200"
# 对不存在的键执行 HINCRBYFLOAT
redis> EXISTS price
(integer) 0
redis> HINCRBYFLOAT price milk 3.5
"3.5"
redis> HGETALL price
1) "milk"
2) "3.5"
# 对不存在的域进行 HINCRBYFLOAT
redis> HGETALL price
1) "milk"
2) "3.5"
redis> HINCRBYFLOAT price coffee 4.5 # 新增 coffee 域
"4.5"
redis> HGETALL price
1) "milk"
2) "3.5"
3) "coffee"
4) "4.5"
(9)HKEYS key
返回哈希表 key 中的所有域。
返回值:
一个包含哈希表中所有域的表。
当 key 不存在时,返回一个空表。
实例如下:
127.0.0.1:6379> HKEYS website
1) "google"
2) "baidu"
3) "taobao"
# 空哈希表/key不存在
127.0.0.1:6379> EXISTS fake_key
(integer) 0
127.0.0.1:6379> HKEYS fake_key
(empty list or set)
(10)HLEN key
返回哈希表 key 中域的数量。
实例如下:
127.0.0.1:6379> hlen website
(integer) 3
(11)HSETNX key field value
将哈希表 key 中的域 field 的值设置为 value ,当且仅当域 field 不存在。
若域 field 已经存在,该操作无效。
如果 key 不存在,一个新哈希表被创建并执行 HSETNX 命令。
返回值:
设置成功,返回 1 。
如果给定域已经存在且没有操作被执行,返回 0 。
实例如下:
redis> HSETNX nosql key-value-store redis
(integer) 1
# 操作无效,域 key-value-store 已存在
redis> HSETNX nosql key-value-store redis
(integer) 0
(12)HVALS key
返回哈希表 key 中所有域的值。
返回值:
一个包含哈希表中所有值的表。
当 key 不存在时,返回一个空表。
实例如下:
127.0.0.1:6379> HVALS website
1) "www.g.cn"
2) "www.baidu.com"
3) "www.taobao.com"
(13)HDEL key field [field …]
删除哈希表 key 中的一个或多个指定域,不存在的域将被忽略。
在Redis2.4以下的版本里, HDEL 每次只能删除单个域,如果你需要在一个原子时间内删除多个域,请将命令包含在 MULTI / EXEC 块内。
返回值:
被成功移除的域的数量,不包括被忽略的域。
实例如下:
# 测试数据
redis> HGETALL abbr
1) "a"
2) "apple"
3) "b"
4) "banana"
5) "c"
6) "cat"
7) "d"
8) "dog"
# 删除单个域
redis> HDEL abbr a
(integer) 1
# 删除不存在的域
redis> HDEL abbr not-exists-field
(integer) 0
# 删除多个域
redis> HDEL abbr b c
(integer) 2
redis> HGETALL abbr
1) "d"
2) "dog"
【4】List
Redis list 是简单的字符串列表 ,安装插入顺序排序。底层实际是个链表,你可以在列表的头部(左边)或者尾部(右边)添加一个元素。
它是一个字符串链表,left、right都可以插入添加。如果键不存在,创建新的链表;如果键已存在,新增内容;如果值全移除,对应的键也就消失了。
链表的操作无论是头和尾效率都极高,但假如是对中间元素进行操作,效率就很惨淡了。
(1)LPUSH key value [value …]
将一个或多个值 value 插入到列表 key 的表头.
如果有多个 value 值,那么各个 value 值按从左到右的顺序依次插入到表头: 比如说,对空列表 mylist 执行命令 LPUSH mylist a b c ,列表的值将是 c b a ,这等同于原子性地执行 LPUSH mylist a 、 LPUSH mylist b 和 LPUSH mylist c 三个命令。
如果 key 不存在,一个空列表会被创建并执行 LPUSH 操作。
当 key 存在但不是列表类型时,返回一个错误。
返回值:
执行 LPUSH 命令后,列表的长度。
实例如下:
127.0.0.1:6379> LPUSH mylist 1 2 3
(integer) 3
(2)LRANGE key start stop
返回列表 key 中指定区间内的元素,区间以偏移量 start 和 stop 指定。
下标(index)参数 start 和 stop 都以 0 为底,也就是说,以 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。
你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。
- 注意LRANGE命令和编程语言区间函数的区别。
假如你有一个包含一百个元素的列表,对该列表执行 LRANGE list 0 10 ,结果是一个包含11个元素的列表,这表明 stop 下标也在 LRANGE 命令的取值范围之内(闭区间),这和某些语言的区间函数可能不一致,比如Ruby的 Range.new 、 Array#slice 和Python的 range() 函数。
- 超出范围的下标
超出范围的下标值不会引起错误。
如果 start 下标比列表的最大下标 end ( LLEN list 减去 1 )还要大,那么 LRANGE 返回一个空列表。
如果 stop 下标比 end 下标还要大,Redis将 stop 的值设置为 end 。
- 返回值:
一个列表,包含指定区间内的元素。
实例如下:
127.0.0.1:6379> LRANGE mylist 0 -1
1) "3"
2) "2"
3) "1"
127.0.0.1:6379> LRANGE mylist 0 0
1) "3"
(3)LPOP key
移除并返回列表 key 的头元素。当 key 不存在时,返回 nil 。
实例如下:
127.0.0.1:6379> LPOP mylist
"3"
127.0.0.1:6379> LRANGE mylist 0 -1
1) "2"
2) "1"
(4)RPOP key
移除并返回列表 key 的尾元素。当 key 不存在时,返回 nil 。
实例如下:
127.0.0.1:6379> RPOP mylist
"1"
127.0.0.1:6379> LRANGE mylist 0 -1
1) "2"
(5)LINDEX key index
返回列表 key 中,下标为 index 的元素。
下标(index)参数 start 和 stop 都以 0 为底,也就是说,以 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。
你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。
如果 key 不是列表类型,返回一个错误。
返回值:
列表中下标为 index 的元素。
如果 index 参数的值不在列表的区间范围内(out of range),返回 nil 。
实例如下:
127.0.0.1:6379> LRANGE mylist 0 -1
1) "2"
127.0.0.1:6379> RPUSH mylist 1 2 3 4
(integer) 5
127.0.0.1:6379> LRANGE mylist 0 -1
1) "2"
2) "1"
3) "2"
4) "3"
5) "4"
127.0.0.1:6379> LINDEX mylist 0
"2"
127.0.0.1:6379> LINDEX mylist 5
(nil)
127.0.0.1:6379> LINDEX mylist 4
"4"
(6)RPUSH key value [value …]
将一个或多个值 value 插入到列表 key 的表尾(最右边)。
如果有多个 value 值,那么各个 value 值按从左到右的顺序依次插入到表尾:比如对一个空列表 mylist 执行 RPUSH mylist a b c ,得出的结果列表为 a b c ,等同于执行命令 RPUSH mylist a 、 RPUSH mylist b 、 RPUSH mylist c 。
如果 key 不存在,一个空列表会被创建并执行 RPUSH 操作。
当 key 存在但不是列表类型时,返回一个错误。
返回值:
执行 RPUSH 操作后,表的长度。
实例如下:
127.0.0.1:6379> LRANGE mylist 0 -1
1) "2"
2) "1"
3) "2"
4) "3"
5) "4"
# 列头插入
127.0.0.1:6379> LPUSH mylist 5
(integer) 6
127.0.0.1:6379> LRANGE mylist 0 -1
1) "5"
2) "2"
3) "1"
4) "2"
5) "3"
6) "4"
# 列尾插入
127.0.0.1:6379> RPUSH mylist 6 7
(integer) 8
127.0.0.1:6379> LRANGE mylist 0 -1
1) "5"
2) "2"
3) "1"
4) "2"
5) "3"
6) "4"
7) "6"
8) "7"
(7)LLEN key
返回列表 key 的长度。
如果 key 不存在,则 key 被解释为一个空列表,返回 0 .
如果 key 不是列表类型,返回一个错误。
# 非空列表
127.0.0.1:6379> LLEN mylist
(integer) 8
# 空列表/key不存在
127.0.0.1:6379> LLEN mylist2
(integer) 0
(8)LINSERT key BEFORE|AFTER pivot value
将值 value 插入到列表 key 当中,位于值 pivot 之前或之后。
当 pivot 不存在于列表 key 时,不执行任何操作,返回 -1。
当 key 不存在时, key 被视为空列表,不执行任何操作。
如果 key 不是列表类型,返回一个错误。
实例如下:
127.0.0.1:6379> LINSERT mylist before 3 8
(integer) 9
127.0.0.1:6379> LRANGE mylist 0 -1
1) "5"
2) "2"
3) "1"
4) "2"
5) "8"
6) "3"
7) "4"
8) "6"
9) "7"
(9)LREM key count value
根据参数 count 的值,移除列表中与参数 value 相等的元素。
count 的值可以是以下几种:
- count > 0 : 从表头开始向表尾搜索,移除与 value 相等的元素,数量为 count 。
- count < 0 : 从表尾开始向表头搜索,移除与 value 相等的元素,数量为 count 的绝对值。
- count = 0 : 移除表中所有与 value 相等的值。
实例如下:
127.0.0.1:6379> LRANGE mylist 0 -1
1) "5"
2) "2"
3) "1"
4) "2"
5) "8"
6) "3"
7) "4"
8) "6"
9) "7"
127.0.0.1:6379> LREM mylist 2 2
(integer) 2
127.0.0.1:6379> LRANGE mylist 0 -1
1) "5"
2) "1"
3) "8"
4) "3"
5) "4"
6) "6"
7) "7"
(10)LSET key index value
将列表 key 下标为 index 的元素的值设置为 value 。
当 index 参数超出范围,或对一个空列表( key 不存在)进行 LSET 时,返回一个错误。
返回值:
操作成功返回 ok ,否则返回错误信息。
实例如下:
127.0.0.1:6379> LRANGE mylist 0 -1
1) "5"
2) "1"
3) "8"
4) "3"
5) "4"
6) "6"
7) "7"
127.0.0.1:6379> LSET mylist 0 0
OK
127.0.0.1:6379> LRANGE mylist 0 -1
1) "0"
2) "1"
3) "8"
4) "3"
5) "4"
6) "6"
7) "7"
(11)LTRIM key start stop
对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。
举个例子,执行命令 LTRIM list 0 2 ,表示只保留列表 list 的前三个元素,其余元素全部删除。
下标(index)参数 start 和 stop 都以 0 为底,也就是说,以 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。
你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。
当 key 不是列表类型时,返回一个错误。
LTRIM 命令通常和 LPUSH 命令或 RPUSH 命令配合使用,举个例子:
LPUSH log newest_log
LTRIM log 0 99
这个例子模拟了一个日志程序,每次将最新日志 newest_log 放到 log 列表中,并且只保留最新的 100 项。注意当这样使用 LTRIM 命令时,时间复杂度是O(1),因为平均情况下,每次只有一个元素被移除。
- 注意LTRIM命令和编程语言区间函数的区别
假如你有一个包含一百个元素的列表 list ,对该列表执行 LTRIM list 0 10 ,结果是一个包含11个元素的列表,这表明 stop 下标也在 LTRIM 命令的取值范围之内(闭区间),这和某些语言的区间函数可能不一致,比如Ruby的 Range.new 、 Array#slice 和Python的 range() 函数。
- 超出范围的下标
超出范围的下标值不会引起错误。
如果 start 下标比列表的最大下标 end ( LLEN list 减去 1 )还要大,或者 start > stop , LTRIM 返回一个空列表(因为 LTRIM 已经将整个列表清空)。
如果 stop 下标比 end 下标还要大,Redis将 stop 的值设置为 end 。
# 情况 1: 常见情况, start 和 stop 都在列表的索引范围之内
redis> LRANGE alpha 0 -1 # alpha 是一个包含 5 个字符串的列表
1) "h"
2) "e"
3) "l"
4) "l"
5) "o"
redis> LTRIM alpha 1 -1 # 删除 alpha 列表索引为 0 的元素
OK
redis> LRANGE alpha 0 -1 # "h" 被删除了
1) "e"
2) "l"
3) "l"
4) "o"
# 情况 2: stop 比列表的最大下标还要大
redis> LTRIM alpha 1 10086 # 保留 alpha 列表索引 1 至索引 10086 上的元素
OK
redis> LRANGE alpha 0 -1 # 只有索引 0 上的元素 "e" 被删除了,其他元素还在
1) "l"
2) "l"
3) "o"
# 情况 3: start 和 stop 都比列表的最大下标要大,并且 start < stop
redis> LTRIM alpha 10086 123321
OK
redis> LRANGE alpha 0 -1 # 列表被清空
(empty list or set)
# 情况 4: start 和 stop 都比列表的最大下标要大,并且 start > stop
redis> RPUSH new-alpha "h" "e" "l" "l" "o" # 重新建立一个新列表
(integer) 5
redis> LRANGE new-alpha 0 -1
1) "h"
2) "e"
3) "l"
4) "l"
5) "o"
redis> LTRIM new-alpha 123321 10086 # 执行 LTRIM
OK
redis> LRANGE new-alpha 0 -1 # 同样被清空
(empty list or set)
(12)RPOPLPUSH source destination
命令 RPOPLPUSH 在一个原子时间内,执行以下两个动作:
- 将列表 source 中的最后一个元素(尾元素)弹出,并返回给客户端。
- 将 source 弹出的元素插入到列表 destination ,作为 destination 列表的的头元素。
举个例子,你有两个列表 source 和 destination , source 列表有元素 a, b, c , destination 列表有元素 x, y, z ,执行 RPOPLPUSH source destination 之后, source 列表包含元素 a, b , destination 列表包含元素 c, x, y, z ,并且元素 c 会被返回给客户端。
如果 source 不存在,值 nil 被返回,并且不执行其他动作。
如果 source 和 destination 相同,则列表中的表尾元素被移动到表头,并返回该元素,可以把这种特殊情况视作列表的旋转(rotation)操作。
实例如下:
# source 和 destination 不同
redis> LRANGE alpha 0 -1 # 查看所有元素
1) "a"
2) "b"
3) "c"
4) "d"
redis> RPOPLPUSH alpha reciver # 执行一次 RPOPLPUSH 看看
"d"
redis> LRANGE alpha 0 -1
1) "a"
2) "b"
3) "c"
redis> LRANGE reciver 0 -1
1) "d"
redis> RPOPLPUSH alpha reciver # 再执行一次,证实 RPOP 和 LPUSH 的位置正确
"c"
redis> LRANGE alpha 0 -1
1) "a"
2) "b"
redis> LRANGE reciver 0 -1
1) "c"
2) "d"
# source 和 destination 相同
redis> LRANGE number 0 -1
1) "1"
2) "2"
3) "3"
4) "4"
redis> RPOPLPUSH number number
"4"
redis> LRANGE number 0 -1 # 4 被旋转到了表头
1) "4"
2) "1"
3) "2"
4) "3"
redis> RPOPLPUSH number number
"3"
redis> LRANGE number 0 -1 # 这次是 3 被旋转到了表头
1) "3"
2) "4"
3) "1"
4) "2"
【5】Set
Redis 的Set是string类型的无序集合,它是通过HashTable实现的。
(1)SADD key member [member …]
将一个或多个 member 元素加入到集合 key 当中,已经存在于集合的 member 元素将被忽略。
假如 key 不存在,则创建一个只包含 member 元素作成员的集合。
当 key 不是集合类型时,返回一个错误。
实例如下:
# 添加多个元素
127.0.0.1:6379> SADD myset 1 2
(integer) 2
# 添加重复元素
127.0.0.1:6379> SADD myset 1
(integer) 0
(2)SMEMBERS key
返回集合 key 中的所有成员。
不存在的 key 被视为空集合。
实例如下:
127.0.0.1:6379> SMEMBERS myset
1) "1"
2) "2"
(3)SISMEMBER key member
判断 member 元素是否集合 key 的成员。
返回值:
如果 member 元素是集合的成员,返回 1 。
如果 member 元素不是集合的成员,或 key 不存在,返回 0 。
实例如下:
127.0.0.1:6379> SISMEMBER myset 1
(integer) 1
127.0.0.1:6379> SISMEMBER myset 3
(integer) 0
(4)SCARD key
返回集合 key 的基数(集合中元素的数量)。
返回值:
集合的基数。
当 key 不存在时,返回 0 。
实例如下:
127.0.0.1:6379> SCARD myset
(integer) 2
(5)SREM key member [member …]
移除集合 key 中的一个或多个 member 元素,不存在的 member 元素会被忽略。
当 key 不是集合类型,返回一个错误。
返回值:
被成功移除的元素的数量,不包括被忽略的元素。
实例如下:
# 移除集合元素中的1
127.0.0.1:6379> SREM myset 1
(integer) 1
#查看剩余集合元素
127.0.0.1:6379> SMEMBERS myset
1) "2"
(6)SRANDMEMBER key [count]
如果命令执行时,只提供了 key 参数,那么返回集合中的一个随机元素。
从 Redis 2.6 版本开始, SRANDMEMBER 命令接受可选的 count 参数:
- 如果 count 为正数,且小于集合基数,那么命令返回一个包含 count 个元素的数组,数组中的元素各不相同。如果 count 大于等于集合基数,那么返回整个集合。
- 如果 count 为负数,那么命令返回一个数组,数组中的元素可能会重复出现多次,而数组的长度为 count 的绝对值。
该操作和 SPOP 相似,但 SPOP 将随机元素从集合中移除并返回,而 SRANDMEMBER 则仅仅返回随机元素,而不对集合进行任何改动。
实例如下:
127.0.0.1:6379> SADD myset 1 3
(integer) 2
# 返回两个随机元素
127.0.0.1:6379> SRANDMEMBER myset 2
1) "2"
2) "1"
# 只给定参数key
127.0.0.1:6379> SRANDMEMBER myset
"2"
# count设置为负数,元素可能会重复出现多次
127.0.0.1:6379> SRANDMEMBER myset -3
1) "2"
2) "2"
3) "1"
(7)SPOP key
移除并返回集合中的一个随机元素。
如果只想获取一个随机元素,但不想该元素从集合中被移除的话,可以使用 SRANDMEMBER 命令。
实例如下:
127.0.0.1:6379> SPOP myset
"3"
127.0.0.1:6379> SMEMBERS myset
1) "1"
2) "2"
(8)SMOVE source destination member
将 member 元素从 source 集合移动到 destination 集合。
SMOVE 是原子性操作。
如果 source 集合不存在或不包含指定的 member 元素,则 SMOVE 命令不执行任何操作,仅返回 0 。否则, member 元素从 source 集合中被移除,并添加到 destination 集合中去。
当 destination 集合已经包含 member 元素时, SMOVE 命令只是简单地将 source 集合中的 member 元素删除。
当 source 或 destination 不是集合类型时,返回一个错误。
实例如下:
127.0.0.1:6379> SMEMBERS myset
1) "1"
2) "2"
# 从源集合myset 移动 元素1 到目标集合 myset2
127.0.0.1:6379> SMOVE myset myset2 1
(integer) 1
127.0.0.1:6379> SMEMBERS myset
1) "2"
127.0.0.1:6379> SMEMBERS myset2
1) "1"
(9)SDIFF key [key …]
返回一个集合的全部成员,该集合是所有给定集合之间的差集。
不存在的 key 被视为空集。
实例如下:
# 查看第一个集合元素
127.0.0.1:6379> SMEMBERS myset
1) "2"
# 查看第二个集合元素
127.0.0.1:6379> SMEMBERS myset2
1) "1"
# 第一个集合与第二个集合差集
127.0.0.1:6379> sdiff myset myset2
1) "2"
# 第一个集合添加元素3
127.0.0.1:6379> SADD myset 3 3
(integer) 1
# 第三个集合添加元素4
127.0.0.1:6379> SADD myset3 4
(integer) 1
# 三个集合差集
127.0.0.1:6379> SDIFF myset myset2 myset3
1) "2"
2) "3"
(10)SDIFFSTORE destination key [key …]
这个命令的作用和 SDIFF 类似,但它将结果保存到 destination 集合,而不是简单地返回结果集。
如果 destination 集合已经存在,则将其覆盖。
destination 可以是 key 本身。
返回值:结果集中的元素数量。
实例如下:
127.0.0.1:6379> SDIFFSTORE myset3 myset myset2
(integer) 2
# 将myset3集合完全覆盖(原myset3中元素将全部丢失)
127.0.0.1:6379> SMEMBERS myset3
1) "2"
2) "3"
(11)SINTER key [key …]
返回一个集合的全部成员,该集合是所有给定集合的交集。
不存在的 key 被视为空集。
当给定集合当中有一个空集时,结果也为空集(根据集合运算定律)。
实例如下:
127.0.0.1:6379> SINTER myset myset2
(empty list or set)
127.0.0.1:6379> SINTER myset myset3
1) "2"
2) "3"
(12)SINTERSTORE destination key [key …]
这个命令类似于 SINTER 命令,但它将结果保存到 destination 集合,而不是简单地返回结果集。
如果 destination 集合已经存在,则将其覆盖。
destination 可以是 key 本身。
实例如下:
127.0.0.1:6379> SINTERSTORE myset1 myset myset3
(integer) 2
127.0.0.1:6379> SMEMBERS myset1
1) "2"
2) "3"
(13)SUNION key [key …]
返回一个集合的全部成员,该集合是所有给定集合的并集。
不存在的 key 被视为空集。
实例如下:
127.0.0.1:6379> SMEMBERS myset1
1) "2"
2) "3"
127.0.0.1:6379> SMEMBERS myset
1) "2"
2) "3"
127.0.0.1:6379> SUNION myset myset1
1) "2"
2) "3"
127.0.0.1:6379> SUNION myset myset2
1) "1"
2) "2"
3) "3"
(14)SUNIONSTORE destination key [key …]
这个命令类似于 SUNION 命令,但它将结果保存到 destination 集合,而不是简单地返回结果集。
如果 destination 已经存在,则将其覆盖。
destination 可以是 key 本身。
实例如下:
127.0.0.1:6379> SUNIONSTORE myset4 myset1 myset2 myset3
(integer) 3
127.0.0.1:6379> SMEMBERS myset4
1) "1"
2) "2"
3) "3"
【6】Zset(sorted set)
Redis 的Zset和Set一样也是string类型元素的集合,且不允许重复的成员。
不同的是Zset的每个元素都会关联一个double类型的分数。
Redis正是通过分数来为集合中的成员进行从小到大的排序。
Zset的成员是唯一的,但是分数是可以重复的。
(1)ZADD key score member [[score member] [score member] …]
将一个或多个 member 元素及其 score 值加入到有序集 key 当中。
如果某个 member 已经是有序集的成员,那么更新这个 member 的 score 值,并通过重新插入这个 member 元素,来保证该 member 在正确的位置上。
score 值可以是整数值或双精度浮点数。
如果 key 不存在,则创建一个空的有序集并执行 ZADD 操作。
当 key 存在但不是有序集类型时,返回一个错误。
实例如下:
127.0.0.1:6379> ZADD myzset 1.0 1 2.0 2
(integer) 2
(2)ZRANGE key start stop [WITHSCORES]
返回有序集 key 中,指定区间内的成员。
其中成员的位置按 score 值递增(从小到大)来排序。
具有相同 score 值的成员按字典序(lexicographical order )来排列。
如果你需要成员按 score 值递减(从大到小)来排列,请使用 ZREVRANGE 命令。
下标参数 start 和 stop 都以 0 为底,也就是说,以 0 表示有序集第一个成员,以 1 表示有序集第二个成员,以此类推。
你也可以使用负数下标,以 -1 表示最后一个成员, -2 表示倒数第二个成员,以此类推。
超出范围的下标并不会引起错误。
比如说,当 start 的值比有序集的最大下标还要大,或是 start > stop 时, ZRANGE 命令只是简单地返回一个空列表。
另一方面,假如 stop 参数的值比有序集的最大下标还要大,那么 Redis 将 stop 当作最大下标来处理。
可以通过使用 WITHSCORES 选项,来让成员和它的 score 值一并返回,返回列表以 value1,score1, …, valueN,scoreN 的格式表示。
客户端库可能会返回一些更复杂的数据类型,比如数组、元组等。
实例如下:
127.0.0.1:6379> ZRANGE myzset 0 -1
1) "1"
2) "2"
127.0.0.1:6379> ZRANGE myzset 0 -1 withscores
1) "1"
2) "1"
3) "2"
4) "2"
(3)ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
返回有序集 key 中,所有 score 值介于 min 和 max 之间(包括等于 min 或 max )的成员。
有序集成员按 score 值递增(从小到大)次序排列。
具有相同 score 值的成员按字典序(lexicographical order)来排列(该属性是有序集提供的,不需要额外的计算)。
可选的 LIMIT 参数指定返回结果的数量及区间(就像SQL中的 SELECT LIMIT offset, count ),注意当 offset 很大时,定位 offset 的操作可能需要遍历整个有序集,此过程最坏复杂度为 O(N) 时间。
可选的 WITHSCORES 参数决定结果集是单单返回有序集的成员,还是将有序集成员及其 score 值一起返回。
- 区间及无限
min 和 max 可以是 -inf 和 +inf ,这样一来,你就可以在不知道有序集的最低和最高 score 值的情况下,使用 ZRANGEBYSCORE 这类命令。
默认情况下,区间的取值使用闭区间 (小于等于或大于等于),你也可以通过给参数前增加 ( 符号来使用可选的开区间 (小于或大于)。
举个例子:
ZRANGEBYSCORE zset (1 5
返回所有符合条件 1 < score <= 5 的成员,而
ZRANGEBYSCORE zset (5 (10
则返回所有符合条件 5 < score < 10 的成员。
实例如下:
redis> ZADD salary 2500 jack # 测试数据
(integer) 0
redis> ZADD salary 5000 tom
(integer) 0
redis> ZADD salary 12000 peter
(integer) 0
redis> ZRANGEBYSCORE salary -inf +inf # 显示整个有序集
1) "jack"
2) "tom"
3) "peter"
redis> ZRANGEBYSCORE salary -inf +inf WITHSCORES # 显示整个有序集及成员的 score 值
1) "jack"
2) "2500"
3) "tom"
4) "5000"
5) "peter"
6) "12000"
redis> ZRANGEBYSCORE salary -inf 5000 WITHSCORES # 显示工资 <=5000 的所有成员
1) "jack"
2) "2500"
3) "tom"
4) "5000"
redis> ZRANGEBYSCORE salary (5000 400000 # 显示工资大于 5000 小于等于 400000 的成员
1) "peter"
(4)ZREM key member [member …]
移除有序集 key 中的一个或多个成员,不存在的成员将被忽略。
当 key 存在但不是有序集类型时,返回一个错误。
实例如下:
127.0.0.1:6379> ZRANGE myzset 0 -1
1) "1"
2) "2"
127.0.0.1:6379> ZREM myzset 1
(integer) 1
127.0.0.1:6379> ZRANGE myzset 0 -1
1) "2"
(5)ZCARD key
返回有序集 key 的基数。
实例如下:
127.0.0.1:6379> ZCARD myzset
(integer) 1
127.0.0.1:6379> ZADD myzset 3.0 3 4.0 4
(integer) 2
127.0.0.1:6379> ZCARD myzset
(integer) 3
(6)ZCOUNT key min max
返回有序集 key 中, score 值在 min 和 max 之间(默认包括 score 值等于 min 或 max )的成员的数量。
实例如下:
127.0.0.1:6379> ZCOUNT myzset 1 3
(integer) 2
127.0.0.1:6379> ZRANGE myzset 0 -1 withscores
1) "2"
2) "2"
3) "3"
4) "3"
5) "4"
6) "4"
(7)ZRANK key member
返回有序集 key 中成员 member 的排名。其中有序集成员按 score 值递增(从小到大)顺序排列。
排名以 0 为底,也就是说, score 值最小的成员排名为 0 。
实例如下:
127.0.0.1:6379> ZRANGE myzset 0 -1 withscores
1) "2"
2) "2"
3) "3"
4) "3"
5) "4"
6) "4"
127.0.0.1:6379> ZRANK myzset 1
(nil)
127.0.0.1:6379> ZRANK myzset 2
(integer) 0
127.0.0.1:6379> ZRANK myzset 3
(integer) 1
(8)ZSCORE key member
返回有序集 key 中,成员 member 的 score 值。
如果 member 元素不是有序集 key 的成员,或 key 不存在,返回 nil 。
实例如下:
127.0.0.1:6379> ZSCORE myzset 3
"3"
(9)ZREVRANK key member
返回有序集 key 中成员 member 的排名。其中有序集成员按 score 值递减(从大到小)排序。
排名以 0 为底,也就是说, score 值最大的成员排名为 0 。
实例如下:
127.0.0.1:6379> ZRANK myzset 2
(integer) 0
127.0.0.1:6379> ZREVRANK myzset 2
(integer) 2
(10)ZREVRANGE key start stop [WITHSCORES]
返回有序集 key 中,指定区间内的成员。
其中成员的位置按 score 值递减(从大到小)来排列。
具有相同 score 值的成员按字典序的逆序(reverse lexicographical order)排列。
除了成员按 score 值递减的次序排列这一点外, ZREVRANGE 命令的其他方面和 ZRANGE 命令一样。
实例如下:
127.0.0.1:6379> ZRANGE myzset 0 -1 withscores
1) "2"
2) "2"
3) "3"
4) "3"
5) "4"
6) "4"
127.0.0.1:6379> ZREVRANGE myzset 0 -1 withscores
1) "4"
2) "4"
3) "3"
4) "3"
5) "2"
6) "2"
(11)ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]
返回有序集 key 中, score 值介于 max 和 min 之间(默认包括等于 max 或 min )的所有的成员。有序集成员按 score 值递减(从大到小)的次序排列。
具有相同 score 值的成员按字典序的逆序(reverse lexicographical order )排列。
除了成员按 score 值递减的次序排列这一点外, ZREVRANGEBYSCORE 命令的其他方面和 ZRANGEBYSCORE 命令一样。
实例如下:
127.0.0.1:6379> ZADD myzset 0.5 1
(integer) 1
127.0.0.1:6379> ZRANGE myzset 0 -1 withscores
1) "1"
2) "0.5"
3) "2"
4) "2"
5) "3"
6) "3"
7) "4"
8) "4"
127.0.0.1:6379> ZRANGE myzset 0 -1
1) "1"
2) "2"
3) "3"
4) "4"
127.0.0.1:6379> ZRANGEBYSCORE myzset 0 5 withscores
1) "1"
2) "0.5"
3) "2"
4) "2"
5) "3"
6) "3"
7) "4"
8) "4"
127.0.0.1:6379> ZREVRANGE myzset 0 -1 withscores
1) "4"
2) "4"
3) "3"
4) "3"
5) "2"
6) "2"
7) "1"
8) "0.5"
127.0.0.1:6379> ZREVRANGEBYSCORE myzset 5 0 withscores
1) "4"
2) "4"
3) "3"
4) "3"
5) "2"
6) "2"
7) "1"
8) "0.5"
Redis 的命令参考与其他 文档可以参考:
http://redisdoc.com/
【7】使用Java测试数据操作
源码简单示例如下:
public class TestAPI {
public static void main(String[] args)
{
Jedis jedis = new Jedis("127.0.0.1",6379);
jedis.set("k1","v1");
jedis.set("k2","v2");
jedis.set("k3","v3");
System.out.println(jedis.get("k3"));
Set<String> sets = jedis.keys("*");
System.out.println(sets.size());
//key
Set<String> keys = jedis.keys("*");
for (Iterator iterator = keys.iterator(); iterator.hasNext();) {
String key = (String) iterator.next();
System.out.println(key);
}
System.out.println("jedis.exists====>"+jedis.exists("k2"));
System.out.println(jedis.ttl("k1"));
//String
//jedis.append("k1","myreids");
System.out.println(jedis.get("k1"));
jedis.set("k4","k4_redis");
System.out.println("----------------------------------------");
jedis.mset("str1","v1","str2","v2","str3","v3");
System.out.println(jedis.mget("str1","str2","str3"));
//list
System.out.println("----------------------------------------");
//jedis.lpush("mylist","v1","v2","v3","v4","v5");
List<String> list = jedis.lrange("mylist",0,-1);
for (String element : list) {
System.out.println(element);
}
//set
jedis.sadd("orders","jd001");
jedis.sadd("orders","jd002");
jedis.sadd("orders","jd003");
Set<String> set1 = jedis.smembers("orders");
for (Iterator iterator = set1.iterator(); iterator.hasNext();) {
String string = (String) iterator.next();
System.out.println(string);
}
jedis.srem("orders","jd002");
System.out.println(jedis.smembers("orders").size());
//hash
jedis.hset("hash1","userName","lisi");
System.out.println(jedis.hget("hash1","userName"));
Map<String,String> map = new HashMap<String,String>();
map.put("telphone","1245786875");
map.put("address","jane");
map.put("email","abc@163.com");
jedis.hmset("hash2",map);
List<String> result = jedis.hmget("hash2", "telphone","email");
for (String element : result) {
System.out.println(element);
}
//zset
jedis.zadd("zset01",60d,"v1");
jedis.zadd("zset01",70d,"v2");
jedis.zadd("zset01",80d,"v3");
jedis.zadd("zset01",90d,"v4");
Set<String> s1 = jedis.zrange("zset01",0,-1);
for (Iterator iterator = s1.iterator(); iterator.hasNext();) {
String string = (String) iterator.next();
System.out.println(string);
}
}
}