Redis是互联网技术领域使用最为广泛的存储中间件,它是Remote Dictionary Service(远程字典服务)的缩写。Redis以其超高的性能、完美的文档、简洁易懂的源码和丰富的客户端库支持在开源中间件领域广受好评。
Redis五种基础数据结构:
string(字符串)
list(列表)
hash(字典)
set(集合)
zset(有序集合)
string
字符串string是Redis最简单的数据结构,它的内部表示就是一个字符数组。Redis所有的数据结构都以唯一的key字符串作为名称,然后通过这个唯一 key 值来获取相应的 value 数据。不同类型的数据结 构的差异就在于 value 的结构不一样。
字符串结构使用非常广泛,一个常见的用途就是缓存用户信息。我们将用户信息结构体 使用 JSON 序列化成字符串,然后将序列化后的字符串塞进 Redis 来缓存。同样,取用户 信息会经过一次反序列化的过程。
Redis 的字符串是动态字符串,是可以修改的字符串,内部结构实现上类似于 Java 的 ArrayList,采用预分配冗余空间的方式来减少内存的频繁分配,如图中所示,内部为当前字 符串实际分配的空间 capacity 一般要高于实际字符串长度 len。当字符串长度小于 1M 时, 扩容都是加倍现有的空间,如果超过 1M,扩容时一次只会多扩 1M 的空间。需要注意的是 字符串最大长度为 512M。
启动redis
redis-server /usr/local/redis-4.0.9/redis.conf
打开另一个窗口进入redis界面
redis-cli
实现string的增删改查
127.0.0.1:6379> set name herobin
OK
127.0.0.1:6379> get name
"herobin"
127.0.0.1:6379> exists name
(integer) 1
127.0.0.1:6379> del name
(integer) 1
127.0.0.1:6379> get name
(nil)
对string类型的批量读写
127.0.0.1:6379> set name1 xiaozhang
OK
127.0.0.1:6379> set name2 xiaowang
OK
127.0.0.1:6379> mget name1 name2 name3 # 返回一个列表
1) "xiaozhang"
2) "xiaowang"
3) (nil)
127.0.0.1:6379> mset name1 boy name2 girl name3 unknown
OK
127.0.0.1:6379> mget name1 name2 name3
1) "boy"
2) "girl"
3) "unknown"
可以对key设置过期时间,到时间会被自动删除,这个功能常用来控制缓存的失效时间。
127.0.0.1:6379> set name hero
OK
127.0.0.1:6379> get name
"hero"
127.0.0.1:6379> expire name 5 # 5s 后过期
(integer) 1
127.0.0.1:6379> get name # 等待5s后查询 下面输出nil
(nil)
127.0.0.1:6379> setex name 5 hero # 5s后过期,等价于set+expire
OK
127.0.0.1:6379> get name # 5s内
"hero"
127.0.0.1:6379> get name # 5s后
(nil)
127.0.0.1:6379> setnx name newhero #如果name不存在就执行set创建
(integer) 1
127.0.0.1:6379> setnx name newhero #因为name已经存在,所以set创建不成功
(integer) 0
- 计数
如果value值是一个整数,可以对它进行自增操作。自增是有范围的,它的范围在signed long的最大值和最小值之间,超出了这个范围,Redis会报错。
127.0.0.1:6379> set age 20
OK
127.0.0.1:6379> incr age
(integer) 21
127.0.0.1:6379> incrby age 5
(integer) 26
127.0.0.1:6379> incrby age -5
(integer) 21
127.0.0.1:6379> set ageMax 9223372036854775807
OK
127.0.0.1:6379> incr ageMax
(error) ERR increment or decrement would overflow
127.0.0.1:6379>
string命令
- setnx:Setnx(SET if Not eXists) 命令在指定的 key 不存在时,为 key 设置指定的值。
SETNX KEY_NAME VALUE
redis> EXISTS job # job 不存在
(integer) 0
redis> SETNX job "programmer" # job 设置成功
(integer) 1
redis> SETNX job "code-farmer" # 尝试覆盖 job ,失败
(integer) 0
redis> GET job # 没有被覆盖
"programmer"
- getrange:Getrange 命令用于获取存储在指定 key 中字符串的子字符串。字符串的截取范围由 start 和 end 两个偏移量决定(包括 start 和 end 在内)。
GETRANGE KEY_NAME start end
redis 127.0.0.1:6379> SET mykey "This is my test key"
OK
redis 127.0.0.1:6379> GETRANGE mykey 0 3
"This"
redis 127.0.0.1:6379> GETRANGE mykey 0 -1
"This is my test key"
- mset:Mset 命令用于同时设置一个或多个 key-value 对。
MSET key1 value1 key2 value2 .. keyN valueN
redis 127.0.0.1:6379> MSET key1 "Hello" key2 "World"
OK
redis 127.0.0.1:6379> GET key1
"Hello"
redis 127.0.0.1:6379> GET key2
1) "World"
- setex:Setex 命令为指定的 key 设置值及其过期时间。如果 key 已经存在, SETEX 命令将会替换旧的值。
SETEX KEY_NAME TIMEOUT VALUE
redis 127.0.0.1:6379> SETEX mykey 60 redis
OK
redis 127.0.0.1:6379> TTL mykey # TTL 命令以秒为单位返回 key 的剩余过期时间。
60
redis 127.0.0.1:6379> GET mykey
"redis
- set:SET 命令用于设置给定 key 的值。如果 key 已经存储其他值, SET 就覆写旧值,且无视类型。
SET KEY_NAME VALUE
# 对不存在的键进行设置
redis 127.0.0.1:6379> SET key "value"
OK
redis 127.0.0.1:6379> GET key
"value"
# 对已存在的键进行设置
redis 127.0.0.1:6379> SET key "new-value"
OK
redis 127.0.0.1:6379> GET key
"new-value"
- get:Get 命令用于获取指定 key 的值。如果 key 不存在,返回 nil 。如果key 储存的值不是字符串类型,返回一个错误。
GET KEY_NAME
# 对不存在的 key 或字符串类型 key 进行 GET
redis> GET db
(nil)
redis> SET db redis
OK
redis> GET db
"redis"
# 对不是字符串类型的 key 进行 GET
redis> DEL db
(integer) 1
redis> LPUSH db redis mongodb mysql
(integer) 3
redis> GET db
(error) ERR Operation against a key holding the wrong kind of value
- getbit:Getbit 命令用于对 key 所储存的字符串值,获取指定偏移量上的位(bit)。
GETBIT KEY_NAME OFFSET
# 对不存在的 key 或者不存在的 offset 进行 GETBIT, 返回 0
redis> EXISTS bit
(integer) 0
redis> GETBIT bit 10086
(integer) 0
# 对已存在的 offset 进行 GETBIT
redis> SETBIT bit 10086 1
(integer) 0
redis> GETBIT bit 10086
(integer) 1
- setbit:Setbit 命令用于对 key 所储存的字符串值,设置或清除指定偏移量上的位(bit)。
具体介绍;https://www.cnblogs.com/K-artorias/p/8463286.html
Setbit KEY_NAME OFFSET
redis> SETBIT bit 10086 1
(integer) 0
redis> GETBIT bit 10086
(integer) 1
redis> GETBIT bit 100 # bit 默认被初始化为 0
(integer) 0
- decr:Decr 命令将 key 中储存的数字值减一。
如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 DECR 操作。
如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。
本操作的值限制在 64 位(bit)有符号数字表示之内。DECR KEY_NAME
# 对存在的数字值 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
- decrby:Decrby 命令将 key 所储存的值减去指定的减量值。
如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 DECRBY 操作。
如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。
本操作的值限制在 64 位(bit)有符号数字表示之内。
DECRBY KEY_NAME DECREMENT_AMOUNT
# 对已存在的 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
- strlen:Strlen 命令用于获取指定 key 所储存的字符串值的长度。当 key 储存的不是字符串值时,返回一个错误。
STRLEN KEY_NAME
# 获取字符串的长度
redis> SET mykey "Hello world"
OK
redis> STRLEN mykey
(integer) 11
# 不存在的 key 长度为 0
redis> STRLEN nonexisting
(integer) 0
- msetnx:Msetnx 命令用于所有给定 key 都不存在时,同时设置一个或多个 key-value 对。
MSETNX key1 value1 key2 value2 .. keyN valueN
# 对不存在的 key 进行 MSETNX
redis> MSETNX rmdbs "MySQL" nosql "MongoDB" key-value-store "redis"
(integer) 1
redis> MGET rmdbs nosql key-value-store
1) "MySQL"
2) "MongoDB"
3) "redis"
# MSET 的给定 key 当中有已存在的 key
redis> MSETNX rmdbs "Sqlite" language "python" # rmdbs 键已经存在,操作失败
(integer) 0
redis> EXISTS language # 因为 MSET 是原子性操作,language 没有被设置
(integer) 0
redis> GET rmdbs # rmdbs 也没有被修改
"MySQL"
- incrby:Incrby 命令将 key 中储存的数字加上指定的增量值。
如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCRBY 命令。
如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。
本操作的值限制在 64 位(bit)有符号数字表示之内。
INCRBY KEY_NAME INCR_AMOUNT
# 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
- incrbyfloat:Incrbyfloat 命令为 key 中所储存的值加上指定的浮点数增量值。
如果 key 不存在,那么 INCRBYFLOAT 会先将 key 的值设为 0 ,再执行加法操作。
INCRBYFLOAT KEY_NAME INCR_AMOUNT
# 值和增量都不是指数符号
redis> SET mykey 10.50
OK
redis> INCRBYFLOAT mykey 0.1
"10.6"
# 值和增量都是指数符号
redis> SET mykey 314e-2
OK
redis> GET mykey # 用 SET 设置的值可以是指数符号
"314e-2"
redis> INCRBYFLOAT mykey 0 # 但执行 INCRBYFLOAT 之后格式会被改成非指数符号
"3.14"
# 可以对整数类型执行
redis> SET mykey 3
OK
redis> INCRBYFLOAT mykey 1.1
"4.1"
# 后跟的 0 会被移除
redis> SET mykey 3.0
OK
redis> GET mykey # SET 设置的值小数部分可以是 0
"3.0"
redis> INCRBYFLOAT mykey 1.000000000000000000000 # 但 INCRBYFLOAT 会将无用的 0 忽略掉,有需要的话,将浮点变为整数
"4"
redis> GET mykey
"4"
- setrange:Setrange 命令用指定的字符串覆盖给定 key 所储存的字符串值,覆盖的位置从偏移量 offset 开始。
SETRANGE KEY_NAME OFFSET VALUE
redis 127.0.0.1:6379> SET key1 "Hello World"
OK
redis 127.0.0.1:6379> SETRANGE key1 6 "Redis"
(integer) 11
redis 127.0.0.1:6379> GET key1
"Hello Redis"
- psetex:Psetex 命令以毫秒为单位设置 key 的生存时间。
PSETEX key1 EXPIRY_IN_MILLISECONDS value1
redis 127.0.0.1:6379> PSETEX mykey 1000 "Hello"
OK
redis 127.0.0.1:6379> PTTL mykey # 查看过期时间
999
redis 127.0.0.1:6379> GET mykey
1) "Hello"
- append:Append 命令用于为指定的 key 追加值。
如果 key 已经存在并且是一个字符串, APPEND 命令将 value 追加到 key 原来的值的末尾。
如果 key 不存在, APPEND 就简单地将给定 key 设为 value ,就像执行 SET key value 一样。
APPEND KEY_NAME NEW_VALUE
# 对不存在的 key 执行 APPEND
redis> EXISTS myphone # 确保 myphone 不存在
(integer) 0
redis> APPEND myphone "nokia" # 对不存在的 key 进行 APPEND ,等同于 SET myphone "nokia"
(integer) 5 # 字符长度
# 对已存在的字符串进行 APPEND
redis> APPEND myphone " - 1110" # 长度从 5 个字符增加到 12 个字符
(integer) 12
redis> GET myphone
"nokia - 1110"
- getset:Getset 命令用于设置指定 key 的值,并返回 key 旧的值。
GETSET KEY_NAME VALUE
redis 127.0.0.1:6379> GETSET mynewkey "This is my test key"
(nil)
redis 127.0.0.1:6379> GETSET mynewkey "This is my new value to test getset"
"This is my test key"
- mget:Mget 命令返回所有(一个或多个)给定 key 的值。 如果给定的 key 里面,有某个 key 不存在,那么这个 key 返回特殊值 nil 。
MGET KEY1 KEY2 .. KEYN
redis 127.0.0.1:6379> SET key1 "hello"
OK
redis 127.0.0.1:6379> SET key2 "world"
OK
redis 127.0.0.1:6379> MGET key1 key2 someOtherKey
1) "Hello"
2) "World"
3) (nil)
- incr:Incr 命令将 key 中储存的数字值增一。
如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作。
如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。
本操作的值限制在 64 位(bit)有符号数字表示之内。
INCR KEY_NAME
redis> SET page_view 20
OK
redis> INCR page_view
(integer) 21
redis> GET page_view # 数字值在 Redis 中以字符串的形式保存
"21"
list(列表)
Redis 的列表相当于 Java 语言里面的 LinkedList(双向链表),注意它是链表而不是数组。这意味着 list 的插入和删除操作非常快,时间复杂度为 O(1),但是索引定位很慢,时间复杂度为 O(n)。
当列表弹出了最后一个元素之后,该数据结构自动被删除,内存被回收。
Redis 的列表结构常用来做异步队列使用。将需要延后处理的任务结构体序列化成字符 串塞进 Redis 的列表,另一个线程从这个列表中轮询数据进行处理。
右边进左边出:队列
队列是先进先出的数据结构,常用于消息队列和异步逻辑处理,它会确保元素的访问顺序性。
127.0.0.1:6379> rpush books python java c#
(integer) 3
127.0.0.1:6379> llen books
(integer) 3
127.0.0.1:6379> lpop books
"python"
127.0.0.1:6379> lpop books
"java"
127.0.0.1:6379> lpop books
"c#"
127.0.0.1:6379> lpop books
(nil)
右边进右边出:栈
栈是先进后出的数据结构,跟队列正好相反。拿Redis的列表数据结构做栈使用的业务场景并不多见。
127.0.0.1:6379> rpush books python java c#
(integer) 3
127.0.0.1:6379> rpop books
"c#"
127.0.0.1:6379> rpop books
"java"
127.0.0.1:6379> rpop books
"python"
127.0.0.1:6379> rpop books
(nil)
慢操作
lindex相当于Java链表的get(int index)方法,它需要对链表进行遍历,性能随着参数index增大而变差。
Itrim有两个参数start_index和end_index定义了一个区间,在这个区间内的值,Itrim要保留,区间之外的则通通砍掉,我们可以通过Itrim来实现一个定长的链表。
index可以为负数,index=-1表示倒数第一个元素,同理index=-2表示倒数第二个元素。
127.0.0.1:6379> rpush books python java c#
(integer) 3
127.0.0.1:6379> lindex books 1 # O(n)慎用
"java"
127.0.0.1:6379> lrange books 0 -1 # 获取所有元素,O(n)慎用
1) "python"
2) "java"
3) "c#"
127.0.0.1:6379> ltrim books 1 -1 # O(n)慎用
OK
127.0.0.1:6379> lrange books 0 -1
1) "java"
2) "c#"
127.0.0.1:6379> ltrim books 1 0 # 这其实是清空了整个列表,因为区间范围长度为负
OK
127.0.0.1:6379> llen books
(integer) 0
快速列表
如果再深入一点,你会发现 Redis 底层存储的还不是一个简单的 linkedlist,而是称之为 快速链表 quicklist 的一个结构。
首先在列表元素较少的情况下会使用一块连续的内存存储,这个结构是 ziplist,也即是 压缩列表。它将所有的元素紧挨着一起存储,分配的是一块连续的内存。当数据量比较多的 时候才会改成 quicklist。因为普通的链表需要的附加指针空间太大,会比较浪费空间,而且 会加重内存的碎片化。比如这个列表里存的只是 int 类型的数据,结构上还需要两个额外的 指针 prev 和 next 。所以 Redis 将链表和 ziplist 结合起来组成了 quicklist。也就是将多个 ziplist 使用双向指针串起来使用(如上图)。这样既满足了快速的插入删除性能,又不会出现太大的空间冗余。
关于列表的内部结构实现,我们后面会详细介绍(Redis深度历险的5.3节和5.4节)
列表常用命令
- Lindex:通过索引获取列表中的元素。你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。
redis 127.0.0.1:6379> LPUSH mylist “World”
(integer) 1
redis 127.0.0.1:6379> LPUSH mylist “Hello”
(integer) 2
redis 127.0.0.1:6379> LINDEX mylist 0
“Hello”
redis 127.0.0.1:6379> LINDEX mylist -1
“World”
redis 127.0.0.1:6379> LINDEX mylist 3 # index不在 mylist 的区间范围内
(nil) - Rpush:用于将一个或多个值插入到列表的尾部(最右边)。如果列表不存在,一个空列表会被创建并执行 RPUSH 操作。
redis 127.0.0.1:6379> RPUSH mylist “hello”
(integer) 1
redis 127.0.0.1:6379> RPUSH mylist “foo”
(integer) 2
redis 127.0.0.1:6379> RPUSH mylist “bar”
(integer) 3
redis 127.0.0.1:6379> LRANGE mylist 0 -1
- “hello”
- “foo”
- “bar”
- Lrange:Lrange 返回列表中指定区间内的元素,区间以偏移量 START 和 END 指定。 其中 0 表示列表的第一个元素, 1 表示列表的第二个元素,以此类推。 你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。
redis 127.0.0.1:6379> LPUSH list1 “foo”
(integer) 1
redis 127.0.0.1:6379> LPUSH list1 “bar”
(integer) 2
redis 127.0.0.1:6379> LPUSHX list1 “bar”
(integer) 0
redis 127.0.0.1:6379> LRANGE list1 0 -1
- “foo”
- “bar”
- “bar”
- Rpoplpush:Rpoplpush 命令用于移除列表的最后一个元素,并将该元素添加到另一个列表并返回。
redis 127.0.0.1:6379> RPUSH mylist “hello”
(integer) 1
redis 127.0.0.1:6379> RPUSH mylist “foo”
(integer) 2
redis 127.0.0.1:6379> RPUSH mylist “bar”
(integer) 3
redis 127.0.0.1:6379> RPOPLPUSH mylist myotherlist
“bar”
redis 127.0.0.1:6379> LRANGE mylist 0 -1
- “hello”
- “foo”
- Blpop:Blpop 命令移出并获取列表的第一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。BLPOP LIST1 LIST2 … LISTN TIMEOUT
127.0.0.1:6379> Lrange mylist 0 -1
- “java”
- “redis”
- “MQ”
127.0.0.1:6379> blpop mylist 10 - “mylist”
- “java”
127.0.0.1:6379> blpop mylist 10 - “mylist”
- “redis”
127.0.0.1:6379> blpop mylist 10 - “mylist”
- “MQ”
127.0.0.1:6379> blpop mylist 10
(nil)
(10.01s)
- Brpop:Brpop 命令移出并获取列表的最后一个元素, 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
- Brpoplpush:Brpoplpush 命令从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回它; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。BRPOPLPUSH LIST1 ANOTHER_LIST TIMEOUT
127.0.0.1:6379> Rpush list1 “hello”
(integer) 1
127.0.0.1:6379> Brpoplpush list1 list2 5 # 5是设置的过期时间
“hello”
127.0.0.1:6379> Brpoplpush list1 list2 5
(nil)
(5.05s) - Lrem:Lrem 根据参数 COUNT 的值,移除列表中与参数 VALUE 相等的元素。
COUNT 的值可以是以下几种:
count > 0 : 从表头开始向表尾搜索,移除与 VALUE 相等的元素,数量为 COUNT 。
count < 0 : 从表尾开始向表头搜索,移除与 VALUE 相等的元素,数量为 COUNT 的绝对值。
count = 0 : 移除表中所有与 VALUE 相等的值。
LREM KEY_NAME COUNT VALUE
redis 127.0.0.1:6379> RPUSH mylist “hello”
(integer) 1
redis 127.0.0.1:6379> RPUSH mylist “hello”
(integer) 2
redis 127.0.0.1:6379> RPUSH mylist “foo”
(integer) 3
redis 127.0.0.1:6379> RPUSH mylist “hello”
(integer) 4
redis 127.0.0.1:6379> LREM mylist -2 “hello”
(integer) 2 - Llen:Llen 命令用于返回列表的长度。 如果列表 key 不存在,则 key 被解释为一个空列表,返回 0 。 如果 key 不是列表类型,返回一个错误。
LLEN KEY_NAME
redis 127.0.0.1:6379> RPUSH list1 “foo”
(integer) 1
redis 127.0.0.1:6379> RPUSH list1 “bar”
(integer) 2
redis 127.0.0.1:6379> LLEN list1
(integer) 2 - Ltrim:Ltrim 对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。
LTRIM KEY_NAME START STOP
redis 127.0.0.1:6379> RPUSH mylist “hello”
(integer) 1
redis 127.0.0.1:6379> RPUSH mylist “hello”
(integer) 2
redis 127.0.0.1:6379> RPUSH mylist “foo”
(integer) 3
redis 127.0.0.1:6379> RPUSH mylist “bar”
(integer) 4
redis 127.0.0.1:6379> LTRIM mylist 1 -1
OK
redis 127.0.0.1:6379> LRANGE mylist 0 -1
- “hello”
- “foo”
- “bar”
- Lpop:Lpop 命令用于移除并返回列表的第一个元素。
LLEN KEY_NAME
redis 127.0.0.1:6379> RPUSH list1 “foo”
(integer) 1
redis 127.0.0.1:6379> RPUSH list1 “bar”
(integer) 2
redis 127.0.0.1:6379> LPOP list1
“foo” - Lpushx:Lpushx 将一个或多个值插入到已存在的列表头部,列表不存在时操作无效。返回值是列表的长度。
LPUSHX KEY_NAME VALUE1.. VALUEN
其实就是多了一个list表不存在不创建插入失败功能。
redis 127.0.0.1:6379> LPUSH list1 “foo”
(integer) 1
redis 127.0.0.1:6379> LPUSHX list1 “bar”
(integer) 2
redis 127.0.0.1:6379> LPUSHX list2 “bar”
(integer) 0
redis 127.0.0.1:6379> LRANGE list1 0 -1
- “foo”
- “bar”
- Linsert:Linsert 命令用于在列表的元素前或者后插入元素。 当指定元素不存在于列表中时,不执行任何操作。 当列表不存在时,被视为空列表,不执行任何操作。 如果 key 不是列表类型,返回一个错误。
LINSERT KEY_NAME BEFORE EXISTING_VALUE NEW_VALUE
redis 127.0.0.1:6379> RPUSH list1 “foo”
(integer) 1
redis 127.0.0.1:6379> RPUSH list1 “bar”
(integer) 2
redis 127.0.0.1:6379> LINSERT list1 BEFORE “bar” “Yes”
(integer) 3
redis 127.0.0.1:6379> LRANGE mylist 0 -1
- “foo”
- “Yes”
- “bar”
- Rpop:Rpop 命令用于移除并返回列表的最后一个元素。
RPOP KEY_NAME
redis 127.0.0.1:6379> RPUSH mylist “hello”
(integer) 1
redis 127.0.0.1:6379> RPUSH mylist “hello”
(integer) 2
redis 127.0.0.1:6379> RPUSH mylist “foo”
(integer) 3
redis 127.0.0.1:6379> RPUSH mylist “bar”
(integer) 4
redis 127.0.0.1:6379> RPOP mylist
OK
redis 127.0.0.1:6379> LRANGE mylist 0 -1
- “hello”
- “hello”
- “foo”
- Lset:Lset 通过索引来设置元素的值。
当索引参数超出范围,或对一个空列表进行 LSET 时,返回一个错误。
LSET KEY_NAME INDEX VALUE
redis 127.0.0.1:6379> RPUSH mylist “hello”
(integer) 1
redis 127.0.0.1:6379> RPUSH mylist “hello”
(integer) 2
redis 127.0.0.1:6379> RPUSH mylist “foo”
(integer) 3
redis 127.0.0.1:6379> RPUSH mylist “hello”
(integer) 4
redis 127.0.0.1:6379> LSET mylist 0 “bar”
OK
redis 127.0.0.1:6379> LRANGE mylist 0 -1
1: “bar”
- “hello”
- “foo”
- “hello”
- Lpush:Lpush 命令将一个或多个值插入到列表头部。 如果 key 不存在,一个空列表会被创建并执行 LPUSH 操作。 当 key 存在但不是列表类型时,返回一个错误。在Redis 2.4版本以前的 LPUSH 命令,都只接受单个 value 值。
LPUSH KEY_NAME VALUE1.. VALUEN
redis 127.0.0.1:6379> LPUSH list1 “foo”
(integer) 1
redis 127.0.0.1:6379> LPUSH list1 “bar”
(integer) 2
redis 127.0.0.1:6379> LRANGE list1 0 -1
- “foo”
- "bar
- Rpushx:Rpushx 命令用于将一个或多个值插入到已存在的列表尾部(最右边)。如果列表不存在,操作无效。
RPUSHX KEY_NAME VALUE1..VALUEN
redis 127.0.0.1:6379> RPUSH mylist “hello”
(integer) 1
redis 127.0.0.1:6379> RPUSH mylist “foo”
(integer) 2
redis 127.0.0.1:6379> RPUSHX mylist2 “bar”
(integer) 0
redis 127.0.0.1:6379> LRANGE mylist 0 -1
- “hello”
- “foo”
hash(字典)
Redis 的字典相当于 Java 语言里面的 HashMap,它是无序字典,内部存储了很多键值对。
Redis hash 是一个string类型的field和value的映射表,hash特别适合用于存储对象。
Redis 中每个 hash 可以存储 232 - 1 键值对(40多亿)。
实现结构上同 Java 的 HashMap 也是一致的,同样的数组 + 链表二维结构。第一维 hash 的数组位置碰撞 时,就会将碰撞的元素使用链表串接起来。
不同的是,Redis 的字典的值只能是字符串,另外它们 rehash 的方式不一样,因为 Java 的 HashMap 在字典很大时,rehash 是个耗时的操作,需要一次性全部 rehash。Redis 为了高性能,不能堵塞服务,所以采用了渐进式 rehash 策略。
渐进式 rehash 会在 rehash 的同时,保留新旧两个 hash 结构,查询时会同时查询两个 hash 结构,然后在后续的定时任务中以及 hash 的子指令中,循序渐进地将旧 hash 的内容 一点点迁移到新的 hash 结构中。
当 hash 移除了最后一个元素之后,该数据结构自动被删除,内存被回收。
hash 结构也可以用来存储用户信息,不同于字符串一次性需要全部序列化整个对象, hash 可以对用户结构中的每个字段单独存储。这样当我们需要获取用户信息时可以进行部分 获取。而以整个字符串的形式去保存用户信息的话就只能一次性全部读取,这样就会比较浪 费网络流量。
hash 也有缺点,hash 结构的存储消耗要高于单个字符串,到底该使用 hash 还是字符 串,需要根据实际情况再三权衡。
127.0.0.1:6379> hset books java "thinking in java" # hset为哈希表赋值,如果哈希表不存在,一个新的哈希表被创建并执行,如果已存在且字段也存在,覆盖旧值。命令行的字符串如果包含空格,要用引号括起来
(integer) 1
127.0.0.1:6379> hset books golang "concurrency in go"
(integer) 1
127.0.0.1:6379> hset books python "python cookbook"
(integer) 1
127.0.0.1:6379> hgetall books # hgetall返回哈希表中所有字段和值 key和value间隔出现
1) "java"
2) "thinking in java"
3) "golang"
4) "concurrency in go"
5) "python"
6) "python cookbook"
127.0.0.1:6379> hlen books # hlen获取字段数量
(integer) 3
127.0.0.1:6379> hget books java # hget返回哈希表中指定字段的值
"thinking in java"
127.0.0.1:6379> hset books golang "learning go programming" # 已有执行更新操作,所以返回0
(integer) 0
127.0.0.1:6379> hget books golang
"learning go programming"
127.0.0.1:6379> hmset books java "effective java" python "learning python" golang "modern golang programming" # 批量set
OK
127.0.0.1:6379> hgetall books
1) "java"
2) "effective java"
3) "golang"
4) "modern golang programming"
5) "python"
6) "learning python"
127.0.0.1:6379> hdel books golang # hdel删除key,都删除了books自动消除
(integer) 1
127.0.0.1:6379> hgetall books
1) "java"
2) "effective java"
3) "python"
4) "learning python"
127.0.0.1:6379> hmget books java python # hmget返回一个或多个给定字段的值
1) "effective java"
2) "learning python"
127.0.0.1:6379> hexists books java # hexists 查看哈希表的指定字段是否存在
(integer) 1
127.0.0.1:6379> hexists books c#
(integer) 0
// hincrby 命令用于为哈希表中的字段值加上指定增量值
127.0.0.1:6379> hset herobin age 23
(integer) 1
127.0.0.1:6379> hincrby herobin age 1
(integer) 24
// hvals 命令返回哈希表所有字段的值
127.0.0.1:6379> hvals books
1) "effective java"
2) "learning python"
// hincrbyfloat 命令用于为哈希表中的字段值加上指定浮点数增量值。
127.0.0.1:6379> hset herobin money 20.10
(integer) 0
127.0.0.1:6379> hincrbyfloat herobin money 0.1
"20.2"
// hkeys 命令用于获取哈希表中的所有字段名。
127.0.0.1:6379> hkeys books
1) "java"
2) "python"
// Hsetnx 命令用于为哈希表中不存在的的字段赋值,如果字段已经存在于哈希表中,操作无效。
127.0.0.1:6379> hsetnx herobin name zhangbin
(integer) 1
127.0.0.1:6379> hsetnx herobin name lisi
(integer) 0
set(集合)
Redis的Set是string类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。
Redis 中 集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。
集合中最大的成员数为 2^32 - 1 (4294967295, 每个集合可存储40多亿个成员)。
set里的方法
- sadd:Sadd 命令将一个或多个成员元素加入到集合中,已经存在于集合的成员元素将被忽略。
假如集合 key 不存在,则创建一个只包含添加的元素作成员的集合。
当集合 key 不是集合类型时,返回一个错误。
注意:在Redis2.4版本以前, SADD 只接受单个成员值。
SADD KEY_NAME VALUE1..VALUEN
redis 127.0.0.1:6379> SADD myset "hello"
(integer) 1
redis 127.0.0.1:6379> SADD myset "foo"
(integer) 1
redis 127.0.0.1:6379> SADD myset "hello"
(integer) 0
redis 127.0.0.1:6379> SMEMBERS myset
1) "hello"
2) "foo"
- smembers:Smembers 命令返回集合中的所有的成员。 不存在的集合 key 被视为空集合。
SMEMBERS KEY
redis 127.0.0.1:6379> SADD myset1 "hello"
(integer) 1
redis 127.0.0.1:6379> SADD myset1 "world"
(integer) 1
redis 127.0.0.1:6379> SMEMBERS myset1
1) "World"
2) "Hello"
- sismember:Sismember 命令判断成员元素是否是集合的成员。
SISMEMBER KEY VALUE
redis 127.0.0.1:6379> SADD myset1 "hello"
(integer) 1
redis 127.0.0.1:6379> SISMEMBER myset1 "hello"
(integer) 1
redis 127.0.0.1:6379> SISMEMBER myset1 "world"
(integer) 0
- scard:Scard 命令返回集合中元素的数量。
SCARD KEY_NAME
redis 127.0.0.1:6379> SADD myset "hello"
(integer) 1
redis 127.0.0.1:6379> SADD myset "foo"
(integer) 1
redis 127.0.0.1:6379> SADD myset "hello"
(integer) 0
redis 127.0.0.1:6379> SCARD myset
(integer) 2
- spop:Spop 命令用于移除并返回集合中的一个随机元素。
SPOP KEY
redis 127.0.0.1:6379> SADD myset1 "hello"
(integer) 1
redis 127.0.0.1:6379> SADD myset1 "world"
(integer) 1
redis 127.0.0.1:6379> SADD myset1 "bar"
(integer) 1
redis 127.0.0.1:6379> SPOP myset1
"bar"
redis 127.0.0.1:6379> SMEMBERS myset1
1) "Hello"
2) "world"
- sunion:Sunion 命令返回给定集合的并集。不存在的集合 key 被视为空集。
SUNION KEY KEY1..KEYN
127.0.0.1:6379> sadd set1 "java"
(integer) 1
127.0.0.1:6379> sadd set1 "python"
(integer) 1
127.0.0.1:6379> sadd set1 "js"
(integer) 1
127.0.0.1:6379> sadd set2 "js"
(integer) 1
127.0.0.1:6379> sadd set2 "jquery"
(integer) 1
127.0.0.1:6379> sunion set1 set2
1) "jquery"
2) "java"
3) "python"
4) "js"
- srandmenber:Srandmember 命令用于返回集合中的一个随机元素。
SRANDMEMBER KEY [count]
redis 127.0.0.1:6379> SADD myset1 "hello"
(integer) 1
redis 127.0.0.1:6379> SADD myset1 "world"
(integer) 1
redis 127.0.0.1:6379> SADD myset1 "bar"
(integer) 1
redis 127.0.0.1:6379> SRANDMEMBER myset1
"bar"
redis 127.0.0.1:6379> SRANDMEMBER myset1 2
1) "Hello"
2) "world"
- sinter:Sinter 命令返回给定所有给定集合的交集。 不存在的集合 key 被视为空集。 当给定集合当中有一个空集时,结果也为空集(根据集合运算定律)。
SINTER KEY KEY1..KEYN
redis 127.0.0.1:6379> SADD myset "hello"
(integer) 1
redis 127.0.0.1:6379> SADD myset "foo"
(integer) 1
redis 127.0.0.1:6379> SADD myset "bar"
(integer) 1
redis 127.0.0.1:6379> SADD myset2 "hello"
(integer) 1
redis 127.0.0.1:6379> SADD myset2 "world"
(integer) 1
redis 127.0.0.1:6379> SINTER myset myset2
1) "hello"
- srem:Srem 命令用于移除集合中的一个或多个成员元素,不存在的成员元素会被忽略。
当 key 不是集合类型,返回一个错误。
在 Redis 2.4 版本以前, SREM 只接受单个成员值。
SREM KEY MEMBER1..MEMBERN
redis 127.0.0.1:6379> SADD myset1 "hello"
(integer) 1
redis 127.0.0.1:6379> SADD myset1 "world"
(integer) 1
redis 127.0.0.1:6379> SADD myset1 "bar"
(integer) 1
redis 127.0.0.1:6379> SREM myset1 "hello"
(integer) 1
redis 127.0.0.1:6379> SREM myset1 "foo"
(integer) 0
redis 127.0.0.1:6379> SMEMBERS myset1
1) "bar"
2) "world"
- smove:Smove 命令将指定成员 member 元素从 source 集合移动到 destination 集合。
SMOVE 是原子性操作。
如果 source 集合不存在或不包含指定的 member 元素,则 SMOVE 命令不执行任何操作,仅返回 0 。否则, member 元素从 source 集合中被移除,并添加到 destination 集合中去。
当 destination 集合已经包含 member 元素时, SMOVE 命令只是简单地将 source 集合中的 member 元素删除。
当 source 或 destination 不是集合类型时,返回一个错误。
SMOVE SOURCE DESTINATION MEMBER
redis 127.0.0.1:6379> SADD myset1 "hello"
(integer) 1
redis 127.0.0.1:6379> SADD myset1 "world"
(integer) 1
redis 127.0.0.1:6379> SADD myset1 "bar"
(integer) 1
redis 127.0.0.1:6379> SADD myset2 "foo"
(integer) 1
redis 127.0.0.1:6379> SMOVE myset1 myset2 "bar"
(integer) 1
redis 127.0.0.1:6379> SMEMBERS myset1
1) "World"
2) "Hello"
redis 127.0.0.1:6379> SMEMBERS myset2
1) "foo"
2) "bar"
- sdiffstore:Sdiffstore 命令将给定集合之间的差集存储在指定的集合中。如果指定的集合 key 已存在,则会被覆盖。
SDIFFSTORE DESTINATION_KEY KEY1..KEYN
redis 127.0.0.1:6379> SADD myset "hello"
(integer) 1
redis 127.0.0.1:6379> SADD myset "foo"
(integer) 1
redis 127.0.0.1:6379> SADD myset "bar"
(integer) 1
redis 127.0.0.1:6379> SADD myset2 "hello"
(integer) 1
redis 127.0.0.1:6379> SADD myset2 "world"
(integer) 1
redis 127.0.0.1:6379> SDIFFSTORE destset myset myset2
(integer) 2
redis 127.0.0.1:6379> SMEMBERS destset
1) "foo"
2) "bar"
- sdiff:Sdiff 命令返回给定集合之间的差集。不存在的集合 key 将视为空集。
SDIFF FIRST_KEY OTHER_KEY1..OTHER_KEYN
redis 127.0.0.1:6379> SADD myset "hello"
(integer) 1
redis 127.0.0.1:6379> SADD myset "foo"
(integer) 1
redis 127.0.0.1:6379> SADD myset "bar"
(integer) 1
redis 127.0.0.1:6379> SADD myset2 "hello"
(integer) 1
redis 127.0.0.1:6379> SADD myset2 "world"
(integer) 1
redis 127.0.0.1:6379> SDIFF myset myset2
1) "foo"
2) "bar"
- sscan:Sscan 命令用于迭代集合键中的元素。
SSCAN KEY [MATCH pattern] [COUNT count]
redis 127.0.0.1:6379> SADD myset1 "hello"
(integer) 1
redis 127.0.0.1:6379> SADD myset1 "hi"
(integer) 1
redis 127.0.0.1:6379> SADD myset1 "bar"
(integer) 1
redis 127.0.0.1:6379> sscan myset1 0 match h*
1) "0"
2) 1) "hello"
2) "h1"
- sinterstore:Sinterstore 命令将给定集合之间的交集存储在指定的集合中。如果指定的集合已经存在,则将其覆盖。
SINTERSTORE DESTINATION_KEY KEY KEY1..KEYN
redis 127.0.0.1:6379> SADD myset1 "hello"
(integer) 1
redis 127.0.0.1:6379> SADD myset1 "foo"
(integer) 1
redis 127.0.0.1:6379> SADD myset1 "bar"
(integer) 1
redis 127.0.0.1:6379> SADD myset2 "hello"
(integer) 1
redis 127.0.0.1:6379> SADD myset2 "world"
(integer) 1
redis 127.0.0.1:6379> SINTERSTORE myset myset1 myset2
(integer) 1
redis 127.0.0.1:6379> SMEMBERS myset
1) "hello"
- sunionstore:Sunionstore 命令将给定集合的并集存储在指定的集合 destination 中。
SUNIONSTORE DESTINATION KEY KEY1..KEYN
redis 127.0.0.1:6379> SADD myset1 "hello"
(integer) 1
redis 127.0.0.1:6379> SADD myset1 "world"
(integer) 1
redis 127.0.0.1:6379> SADD myset1 "bar"
(integer) 1
redis 127.0.0.1:6379> SADD myset2 "hello"
(integer) 1
redis 127.0.0.1:6379> SADD myset2 "bar"
(integer) 1
redis 127.0.0.1:6379> SUNIONSTORE myset myset1 myset2
(integer) 1
redis 127.0.0.1:6379> SMEMBERS myset
1) "bar"
2) "world"
3) "hello"
4) "foo"
zset(有序列表)
zset 可能是 Redis 提供的最为特色的数据结构,它也是在面试中面试官最爱问的数据结 构。它类似于 Java 的 SortedSet 和 HashMap 的结合体,一方面它是一个 set,保证了内部 value 的唯一性,另一方面它可以给每个 value 赋予一个 score,代表这个 value 的排序权 重。它的内部实现用的是一种叫着「跳跃列表」的数据结构。
zset 中最后一个 value 被移除后,数据结构自动删除,内存被回收。 zset 可以用来存 粉丝列表,value 值是粉丝的用户 ID,score 是关注时间。我们可以对粉丝列表按关注时间 进行排序。
zset 还可以用来存储学生的成绩,value 值是学生的 ID,score 是他的考试成绩。我们 可以对成绩按分数进行排序就可以得到他的名次。
zset使用方法
- zadd:Zadd 命令用于将一个或多个成员元素及其分数值加入到有序集当中。
如果某个成员已经是有序集的成员,那么更新这个成员的分数值,并通过重新插入这个成员元素,来保证该成员在正确的位置上。
分数值可以是整数值或双精度浮点数。
如果有序集合 key 不存在,则创建一个空的有序集并执行 ZADD 操作。
当 key 存在但不是有序集类型时,返回一个错误。
注意: 在 Redis 2.4 版本以前, ZADD 每次只能添加一个元素。
ZADD KEY_NAME SCORE1 VALUE1.. SCOREN VALUEN
redis 127.0.0.1:6379> ZADD myset 1 "hello"
(integer) 1
redis 127.0.0.1:6379> ZADD myset 1 "foo"
(integer) 1
redis 127.0.0.1:6379> ZADD myset 2 "world" 3 "bar"
(integer) 2
redis 127.0.0.1:6379> ZRANGE myzset 0 -1 WITHSCORES
1) "hello"
2) "1"
3) "foo"
4) "1"
5) "world"
6) "2"
7) "bar"
8) "3"
- zcount:Zcount 命令用于计算有序集合中指定分数区间的成员数量。
ZCOUNT key min max
redis 127.0.0.1:6379> ZADD myzset 1 "hello"
(integer) 1
redis 127.0.0.1:6379> ZADD myzset 1 "foo"
(integer) 1
redis 127.0.0.1:6379> ZADD myzset 2 "world" 3 "bar"
(integer) 2
redis 127.0.0.1:6379> ZCOUNT myzset 1 3
(integer) 4
- zrange:Zrange 返回有序集中,指定区间内的成员。
其中成员的位置按分数值递增(从小到大)来排序。
具有相同分数值的成员按字典序(lexicographical order )来排列。
如果你需要成员按
值递减(从大到小)来排列,请使用 ZREVRANGE 命令。
下标参数 start 和 stop 都以 0 为底,也就是说,以 0 表示有序集第一个成员,以 1 表示有序集第二个成员,以此类推。
你也可以使用负数下标,以 -1 表示最后一个成员, -2 表示倒数第二个成员,以此类推。
使用withscores输出分值,不使用只输出value值
ZRANGE key start stop [WITHSCORES]
redis 127.0.0.1:6379> ZRANGE salary 0 -1 WITHSCORES # 显示整个有序集成员
1) "jack"
2) "3500"
3) "tom"
4) "5000"
5) "boss"
6) "10086"
redis 127.0.0.1:6379> ZRANGE salary 1 2 WITHSCORES # 显示有序集下标区间 1 至 2 的成员
1) "tom"
2) "5000"
3) "boss"
4) "10086"
redis 127.0.0.1:6379> ZRANGE salary 0 200000 WITHSCORES # 测试 end 下标超出最大下标时的情况
1) "jack"
2) "3500"
3) "tom"
4) "5000"
5) "boss"
6) "10086"
redis > ZRANGE salary 200000 3000000 WITHSCORES # 测试当给定区间不存在于有序集时的情况
(empty list or set)
- zrevrange:Zrevrange 命令返回有序集中,指定区间内的成员。
ZREVRANGE key start stop [WITHSCORES]
redis 127.0.0.1:6379> ZRANGE salary 0 -1 WITHSCORES # 递增排列
1) "peter"
2) "3500"
3) "tom"
4) "4000"
5) "jack"
6) "5000"
redis 127.0.0.1:6379> ZREVRANGE salary 0 -1 WITHSCORES # 递减排列
1) "jack"
2) "5000"
3) "tom"
4) "4000"
5) "peter"
6) "3500"
- zrangebylex:Zrangebylex 通过字典区间返回有序集合的成员。
ZRANGEBYLEX key min max [LIMIT offset count]
redis 127.0.0.1:6379> ZADD myzset 0 a 0 b 0 c 0 d 0 e 0 f 0 g
(integer) 7
redis 127.0.0.1:6379> ZRANGEBYLEX myzset - [c # 从开始到c包含c
1) "a"
2) "b"
3) "c"
redis 127.0.0.1:6379> ZRANGEBYLEX myzset - (c # 从开始到c不包含c
1) "a"
2) "b"
redis 127.0.0.1:6379> ZRANGEBYLEX myzset [aaa (g # 左开右闭
1) "b"
2) "c"
3) "d"
4) "e"
5) "f"
- zremrangebylex:Zremrangebylex 命令用于移除有序集合中给定的字典区间的所有成员。
ZREMRANGEBYLEX key min max
redis 127.0.0.1:6379> ZADD myzset 0 aaaa 0 b 0 c 0 d 0 e
(integer) 5
redis 127.0.0.1:6379> ZADD myzset 0 foo 0 zap 0 zip 0 ALPHA 0 alpha
(integer) 5
redis 127.0.0.1:6379> ZRANGE myzset 0 -1
1) "ALPHA"
2) "aaaa"
3) "alpha"
4) "b"
5) "c"
6) "d"
7) "e"
8) "foo"
9) "zap"
10) "zip"
redis 127.0.0.1:6379> ZREMRANGEBYLEX myzset [alpha [foo
(integer) 6
redis 127.0.0.1:6379> ZRANGE myzset 0 -1
1) "ALPHA"
2) "aaaa"
3) "zap"
4) "zip"
- zrangebyscore:返回有序集合中指定分数区间的成员列表。有序集成员按分数值递增(从小到大)次序排列。
具有相同分数值的成员按字典序来排列(该属性是有序集提供的,不需要额外的计算)。
默认情况下,区间的取值使用闭区间 (小于等于或大于等于),你也可以通过给参数前增加 ( 符号来使用可选的开区间 (小于或大于)。
举个例子:
ZRANGEBYSCORE zset (1 5
返回所有符合条件 1 < score <= 5 的成员,而
ZRANGEBYSCORE zset (5 (10
则返回所有符合条件 5 < score < 10 的成员。
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
redis 127.0.0.1:6379> ZADD salary 2500 jack # 测试数据
(integer) 0
redis 127.0.0.1:6379> ZADD salary 5000 tom
(integer) 0
redis 127.0.0.1:6379> ZADD salary 12000 peter
(integer) 0
redis 127.0.0.1:6379> ZRANGEBYSCORE salary -inf +inf # 显示整个有序集
1) "jack"
2) "tom"
3) "peter"
redis 127.0.0.1:6379> ZRANGEBYSCORE salary -inf +inf WITHSCORES # 显示整个有序集及成员的 score 值
1) "jack"
2) "2500"
3) "tom"
4) "5000"
5) "peter"
6) "12000"
redis 127.0.0.1:6379> ZRANGEBYSCORE salary -inf 5000 WITHSCORES # 显示工资 <=5000 的所有成员
1) "jack"
2) "2500"
3) "tom"
4) "5000"
redis 127.0.0.1:6379> ZRANGEBYSCORE salary (5000 400000 # 显示工资大于 5000 小于等于 400000 的成员
1) "peter"
- zrevrangebyscore:zrangebyscore(从大到小)的次序排列.
ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]
redis 127.0.0.1:6379> ZADD salary 10086 jack
(integer) 1
redis 127.0.0.1:6379> ZADD salary 5000 tom
(integer) 1
redis 127.0.0.1:6379> ZADD salary 7500 peter
(integer) 1
redis 127.0.0.1:6379> ZADD salary 3500 joe
(integer) 1
redis 127.0.0.1:6379> ZREVRANGEBYSCORE salary +inf -inf # 逆序排列所有成员
1) "jack"
2) "peter"
3) "tom"
4) "joe"
redis 127.0.0.1:6379> ZREVRANGEBYSCORE salary 10000 2000 # 逆序排列薪水介于 10000 和 2000 之间的成员
1) "peter"
2) "tom"
3) "joe"
- zscan:Zscan 命令用于迭代有序集合中的元素(包括元素成员和元素分值)
ZSCAN key cursor [MATCH pattern] [COUNT count]
127.0.0.1:6379> zscan salary 0 match p*
1) "0"
2) 1) "peter"
2) "12000"
- zremrangebyscore:Zremrangebyscore 命令用于移除有序集中,指定分数(score)区间内的所有成员。
ZREMRANGEBYSCORE key min max
redis 127.0.0.1:6379> ZRANGE salary 0 -1 WITHSCORES # 显示有序集内所有成员及其 score 值
1) "tom"
2) "2000"
3) "peter"
4) "3500"
5) "jack"
6) "5000"
redis 127.0.0.1:6379> ZREMRANGEBYSCORE salary 1500 3500 # 移除所有薪水在 1500 到 3500 内的员工
(integer) 2
redis> ZRANGE salary 0 -1 WITHSCORES # 剩下的有序集成员
1) "jack"
2) "5000"
- zscore:Zscore 命令返回有序集中,成员的分数值。 如果成员元素不是有序集 key 的成员,或 key 不存在,返回 nil 。
ZSCORE key member
redis 127.0.0.1:6379> ZRANGE salary 0 -1 WITHSCORES # 测试数据
1) "tom"
2) "2000"
3) "peter"
4) "3500"
5) "jack"
6) "5000"
redis 127.0.0.1:6379> ZSCORE salary peter # 注意返回值是字符串
"3500"
- zincrby:Zincrby 命令对有序集合中指定成员的分数加上增量 increment
可以通过传递一个负数值 increment ,让分数减去相应的值,比如 ZINCRBY key -5 member ,就是让 member 的 score 值减去 5 。
当 key 不存在,或分数不是 key 的成员时, ZINCRBY key increment member 等同于 ZADD key increment member 。
当 key 不是有序集类型时,返回一个错误。
分数值可以是整数值或双精度浮点数。
ZINCRBY key increment member
redis 127.0.0.1:6379> ZADD myzset 1 "hello"
(integer) 1
redis 127.0.0.1:6379> ZADD myzset 1 "foo"
(integer) 1
redis 127.0.0.1:6379> ZINCRBY myzset 2 "hello"
(integer) 3
redis 127.0.0.1:6379> ZRANGE myzset 0 -1 WITHSCORES
1) "foo"
2) "2"
3) "hello"
4) "3"
- zrank:Zrank 返回有序集中指定成员的排名。其中有序集成员按分数值递增(从小到大)顺序排列。
ZRANK key member
redis 127.0.0.1:6379> ZRANGE salary 0 -1 WITHSCORES # 显示所有成员及其 score 值
1) "peter"
2) "3500"
3) "tom"
4) "4000"
5) "jack"
6) "5000"
redis 127.0.0.1:6379> ZRANK salary tom # 显示 tom 的薪水排名,第二
(integer) 1
- zinterstore:Zinterstore 命令计算给定的一个或多个有序集的交集,其中给定 key 的数量必须以 numkeys 参数指定,并将该交集(结果集)储存到 destination 。
默认情况下,结果集中某个成员的分数值是所有给定集下该成员分数值之和。
ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]
返回值是保存到目标结果集的的成员数量。
# 有序集 mid_test
redis 127.0.0.1:6379> ZADD mid_test 70 "Li Lei"
(integer) 1
redis 127.0.0.1:6379> ZADD mid_test 70 "Han Meimei"
(integer) 1
redis 127.0.0.1:6379> ZADD mid_test 99.5 "Tom"
(integer) 1
# 另一个有序集 fin_test
redis 127.0.0.1:6379> ZADD fin_test 88 "Li Lei"
(integer) 1
redis 127.0.0.1:6379> ZADD fin_test 75 "Han Meimei"
(integer) 1
redis 127.0.0.1:6379> ZADD fin_test 99.5 "Tom"
(integer) 1
# 交集
redis 127.0.0.1:6379> ZINTERSTORE sum_point 2 mid_test fin_test
(integer) 3
# 显示有序集内所有成员及其分数值
redis 127.0.0.1:6379> ZRANGE sum_point 0 -1 WITHSCORES
1) "Han Meimei"
2) "145"
3) "Li Lei"
4) "158"
5) "Tom"
6) "199"
- zrem:Zrem 命令用于移除有序集中的一个或多个成员,不存在的成员将被忽略。
ZRANK key member
# 测试数据
redis 127.0.0.1:6379> ZRANGE page_rank 0 -1 WITHSCORES
1) "bing.com"
2) "8"
3) "baidu.com"
4) "9"
5) "google.com"
6) "10"
# 移除单个元素
redis 127.0.0.1:6379> ZREM page_rank google.com
(integer) 1
redis 127.0.0.1:6379> ZRANGE page_rank 0 -1 WITHSCORES
1) "bing.com"
2) "8"
3) "baidu.com"
4) "9"
# 移除多个元素
redis 127.0.0.1:6379> ZREM page_rank baidu.com bing.com
(integer) 2
redis 127.0.0.1:6379> ZRANGE page_rank 0 -1 WITHSCORES
(empty list or set)
# 移除不存在元素
redis 127.0.0.1:6379> ZREM page_rank non-exists-element
(integer) 0
- zcard:Zcard 命令用于计算集合中元素的数量。
ZCARD KEY_NAME
redis 127.0.0.1:6379> ZADD myset 1 "hello"
(integer) 1
redis 127.0.0.1:6379> ZADD myset 1 "foo"
(integer) 1
redis 127.0.0.1:6379> ZADD myset 2 "world" 3 "bar"
(integer) 2
redis 127.0.0.1:6379> ZCARD myzset
(integer) 4
- zremrangebyrank:Zremrangebyrank 命令用于移除有序集中,指定排名(rank)区间内的所有成员。
ZREMRANGEBYRANK key start stop
redis 127.0.0.1:6379> ZADD salary 2000 jack
(integer) 1
redis 127.0.0.1:6379> ZADD salary 5000 tom
(integer) 1
redis 127.0.0.1:6379> ZADD salary 3500 peter
(integer) 1
redis 127.0.0.1:6379> ZREMRANGEBYRANK salary 0 1 # 移除下标 0 至 1 区间内的成员
(integer) 2
redis 127.0.0.1:6379> ZRANGE salary 0 -1 WITHSCORES # 有序集只剩下一个成员
1) "tom"
2) "5000"
- zunionstore:Zunionstore 命令计算给定的一个或多个有序集的并集,其中给定 key 的数量必须以 numkeys 参数指定,并将该并集(结果集)储存到 destination 。
默认情况下,结果集中某个成员的分数值是所有给定集下该成员分数值之和 。
ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]
使用WEIGHTS选项,可以为每个输入有序集合指定一个乘积因子。这意味着每个输入有序集合中每个元素的分数在传给聚合函数之前要先乘以这个因子。当没有指定WEIGHTS时,乘积因子的默认值是1。
使用AGGREGATE选项,可以指定并集的结果如何被聚合。这个选项的默认值是SUM,元素的分数是所有它存在的有序集合的分数之和。当这个选项设置为MIN或MAX时,结果集合将包含元素的最小或最大分数。
redis 127.0.0.1:6379> ZRANGE programmer 0 -1 WITHSCORES
1) "peter"
2) "2000"
3) "jack"
4) "3500"
5) "tom"
6) "5000"
redis 127.0.0.1:6379> ZRANGE manager 0 -1 WITHSCORES
1) "herry"
2) "2000"
3) "mary"
4) "3500"
5) "bob"
6) "4000"
redis 127.0.0.1:6379> ZUNIONSTORE salary 2 programmer manager WEIGHTS 1 3 # 公司决定加薪。。。除了程序员。。。 1 是指程序员的工资乘1 3是指管理层的工资乘3
(integer) 6
redis 127.0.0.1:6379> ZRANGE salary 0 -1 WITHSCORES
1) "peter"
2) "2000"
3) "jack"
4) "3500"
5) "tom"
6) "5000"
7) "herry"
8) "6000"
9) "mary"
10) "10500"
11) "bob"
12) "12000"
- zlexcount:Zlexcount 命令在计算有序集合中指定字典区间内成员数量。
ZLEXCOUNT KEY MIN MAX
redis 127.0.0.1:6379> ZADD myzset 0 a 0 b 0 c 0 d 0 e
(integer) 5
redis 127.0.0.1:6379> ZADD myzset 0 f 0 g
(integer) 2
redis 127.0.0.1:6379> ZLEXCOUNT myzset - +
(integer) 7
redis 127.0.0.1:6379> ZLEXCOUNT myzset [b [f
(integer) 5
- zrevrank:Zrevrank 命令返回有序集中成员的排名。其中有序集成员按分数值递减(从大到小)排序。
排名以 0 为底,也就是说, 分数值最大的成员排名为 0 。
使用 ZRANK 命令可以获得成员按分数值递增(从小到大)排列的排名。
ZREVRANK key member
redis 127.0.0.1:6379> ZRANGE salary 0 -1 WITHSCORES # 测试数据
1) "jack"
2) "2000"
3) "peter"
4) "3500"
5) "tom"
6) "5000"
redis 127.0.0.1:6379> ZREVRANK salary peter # peter 的工资排第二
(integer) 1
redis 127.0.0.1:6379> ZREVRANK salary tom # tom 的工资最高
(integer) 0
redis键(key)
- Keys:Keys 命令用于查找所有符合给定模式 pattern 的 key 。
KEYS PATTERN
首先创建一些 key,并赋上对应值:
redis 127.0.0.1:6379> SET w3c1 redis
OK
redis 127.0.0.1:6379> SET w3c2 mysql
OK
redis 127.0.0.1:6379> SET w3c3 mongodb
OK
查找以 w3c 为开头的 key:
redis 127.0.0.1:6379> KEYS w3c*
1) "w3c3"
2) "w3c1"
3) "w3c2"
获取 redis 中所有的 key 可用使用 *。
redis 127.0.0.1:6379> KEYS *
1) "w3c3"
2) "w3c1"
3) "w3c2"
- EXISTS:EXISTS 命令用于检查给定 key 是否存在。
EXISTS KEY_NAME
返回值
若 key 存在返回 1 ,否则返回 0 。
实例
redis 127.0.0.1:6379> EXISTS w3cschoolcc-new-key
(integer) 0
现在我们创建一个名为 w3cschoolcc-new-key 的键并赋值,再使用 EXISTS 命令。
redis 127.0.0.1:6379> set w3cschoolcc-new-key newkey
OK
redis 127.0.0.1:6379> EXISTS w3cschoolcc-new-key
(integer) 1
redis 127.0.0.1:6379>
- DEL:DEL 命令用于删除已存在的键。不存在的 key 会被忽略。
DEL KEY_NAME
返回值
被删除 key 的数量。
实例
首先,我们在 redis 中创建一个 key 并设置值。
redis 127.0.0.1:6379> SET w3ckey redis
OK
现在我们删除已创建的 key。
redis 127.0.0.1:6379> DEL w3ckey
(integer) 1
- TTL:TTL 命令以秒为单位返回 key 的剩余过期时间。
TTL KEY_NAME
返回值
当 key 不存在时,返回 -2 。 当 key 存在但没有设置剩余生存时间时,返回 -1 。 否则,以毫秒为单位,返回 key 的剩余生存时间。
注意:在 Redis 2.8 以前,当 key 不存在,或者 key 没有设置剩余生存时间时,命令都返回 -1 。
实例
# 不存在的 key
redis> FLUSHDB
OK
redis> TTL key
(integer) -2
# key 存在,但没有设置剩余生存时间
redis> SET key value
OK
redis> TTL key
(integer) -1
# 有剩余生存时间的 key
redis> EXPIRE key 10086
(integer) 1
redis> TTL key
(integer) 10084
- Pttl:Pttl 命令以毫秒为单位返回 key 的剩余过期时间。
PTTL KEY_NAME
返回值
当 key 不存在时,返回 -2 。 当 key 存在但没有设置剩余生存时间时,返回 -1 。 否则,以毫秒为单位,返回 key 的剩余生存时间。
注意:在 Redis 2.8 以前,当 key 不存在,或者 key 没有设置剩余生存时间时,命令都返回 -1 。
实例
# 不存在的 key
redis> FLUSHDB
OK
redis> PTTL key
(integer) -2
# key 存在,但没有设置剩余生存时间
redis> SET key value
OK
redis> PTTL key
(integer) -1
# 有剩余生存时间的 key
redis> PEXPIRE key 10086
(integer) 1
redis> PTTL key
(integer) 6179
- Move:MOVE 命令用于将当前数据库的 key 移动到给定的数据库 db 当中。
MOVE KEY_NAME DESTINATION_DATABASE
返回值
移动成功返回 1 ,失败则返回 0 。
实例
# 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"
- Type:Type 命令用于返回 key 所储存的值的类型。
TYPE KEY_NAME
返回值
返回 key 的数据类型,数据类型有:
none (key不存在)
string (字符串)
list (列表)
set (集合)
zset (有序集)
hash (哈希表)
实例
# 字符串
redis> SET weather "sunny"
OK
redis> TYPE weather
string
# 列表
redis> LPUSH book_list "programming in scala"
(integer) 1
redis> TYPE book_list
list
# 集合
redis> SADD pat "dog"
(integer) 1
redis> TYPE pat
set
- Expire:Expire 命令用于设置 key 的过期时间。key 过期后将不再可用。
Expire KEY_NAME TIME_IN_SECONDS
返回值
设置成功返回 1 。 当 key 不存在或者不能为 key 设置过期时间时(比如在低于 2.1.3 版本的 Redis 中你尝试更新 key 的过期时间)返回 0 。
实例
首先创建一个 key 并赋值:
redis 127.0.0.1:6379> SET w3ckey redis
OK
为 key 设置过期时间:
redis 127.0.0.1:6379> EXPIRE w3ckey 60
(integer) 1
以上实例中我们为键 w3ckey 设置了过期时间为 1 分钟,1分钟后该键会自动删除。
- Dump:DUMP 命令用于序列化给定 key ,并返回被序列化的值。
DUMP KEY_NAME
返回值
如果 key 不存在,那么返回 nil 。 否则,返回序列化之后的值。
实例
首先,我们在 redis 中创建一个 key 并设置值。
redis> SET greeting "hello, dumping world!"
OK
现在使用 DUMP 序列化键值。
redis> DUMP greeting
"\x00\x15hello, dumping world!\x06\x00E\xa0Z\x82\xd8r\xc1\xde"
redis> DUMP not-exists-key
(nil)
- Expireat:Expireat 命令用于以 UNIX 时间戳(unix timestamp)格式设置 key 的过期时间。key 过期后将不再可用。
Expireat KEY_NAME TIME_IN_UNIX_TIMESTAMP
返回值
设置成功返回 1 。 当 key 不存在或者不能为 key 设置过期时间时(比如在低于 2.1.3 版本的 Redis 中你尝试更新 key 的过期时间)返回 0 。
实例
首先创建一个 key 并赋值:
redis 127.0.0.1:6379> SET w3ckey redis
OK
为 key 设置过期时间:
redis 127.0.0.1:6379> EXPIREAT w3ckey 1293840000
(integer) 1
EXISTS w3ckey
(integer) 0
- Rename:Rename 命令用于修改 key 的名称 。
RENAME OLD_KEY_NAME NEW_KEY_NAME
返回值
改名成功时提示 OK ,失败时候返回一个错误。
当 OLD_KEY_NAME 和 NEW_KEY_NAME 相同,或者 OLD_KEY_NAME 不存在时,返回一个错误。 当 NEW_KEY_NAME 已经存在时, RENAME 命令将覆盖旧值。
实例
# key 存在且 newkey 不存在
redis> SET message "hello world"
OK
redis> RENAME message greeting
OK
redis> EXISTS message # message 不复存在
(integer) 0
redis> EXISTS greeting # greeting 取而代之
(integer) 1
# 当 key 不存在时,返回错误
redis> RENAME fake_key never_exists
(error) ERR no such key
# newkey 已存在时, RENAME 会覆盖旧 newkey
redis> SET pc "lenovo"
OK
redis> SET personal_computer "dell"
OK
redis> RENAME pc personal_computer
OK
redis> GET pc
(nil)
redis:1> GET personal_computer # 原来的值 dell 被覆盖了
"lenovo"
- Renamenx:Renamenx 命令用于在新的 key 不存在时修改 key 的名称 。
RENAMENX OLD_KEY_NAME NEW_KEY_NAME
返回值
修改成功时,返回 1 。 如果 NEW_KEY_NAME 已经存在,返回 0 。
实例
# newkey 不存在,改名成功
redis> SET player "MPlyaer"
OK
redis> EXISTS best_player
(integer) 0
redis> RENAMENX player best_player
(integer) 1
# newkey存在时,失败
redis> SET animal "bear"
OK
redis> SET favorite_animal "butterfly"
OK
redis> RENAMENX animal favorite_animal
(integer) 0
redis> get animal
"bear"
redis> get favorite_animal
"butterfly"
- RANDOMKEY:RANDOMKEY 命令从当前数据库中随机返回一个 key 。
RANDOMKEY
返回值
当数据库不为空时,返回一个 key 。 当数据库为空时,返回 nil 。
实例
# 数据库不为空
redis> MSET fruit "apple" drink "beer" food "cookies" # 设置多个 key
OK
redis> RANDOMKEY
"fruit"
redis> RANDOMKEY
"food"
redis> KEYS * # 查看数据库内所有key,证明 RANDOMKEY 并不删除 key
1) "food"
2) "drink"
3) "fruit"
# 数据库为空
redis> FLUSHDB # 删除当前数据库所有 key
OK
redis> RANDOMKEY
(nil)
- PERSIST:PERSIST 命令用于移除给定 key 的过期时间,使得 key 永不过期。
PERSIST KEY_NAME
返回值
当过期时间移除成功时,返回 1 。 如果 key 不存在或 key 没有设置过期时间,返回 0 。
实例
redis> SET mykey "Hello"
OK
redis> EXPIRE mykey 10 # 为 key 设置生存时间
(integer) 1
redis> TTL mykey
(integer) 10
redis> PERSIST mykey # 移除 key 的生存时间
(integer) 1
redis> TTL mykey
(integer) -1
- PEXPIREAT:PEXPIREAT 命令用于设置 key 的过期时间,已毫秒技。key 过期后将不再可用。
PEXPIREAT KEY_NAME TIME_IN_MILLISECONDS_IN_UNIX_TIMESTAMP
返回值
设置成功返回 1 。 当 key 不存在或者不能为 key 设置过期时间时(比如在低于 2.1.3 版本的 Redis 中你尝试更新 key 的过期时间)返回 0 。
实例
首先创建一个 key 并赋值:
redis 127.0.0.1:6379> SET w3ckey redis
OK
为 key 设置过期时间:
redis 127.0.0.1:6379> PEXPIREAT tutorialspoint 1555555555005
(integer) 1