redis基础命令

665 阅读25分钟

说明

我的原文 -> 雀语:www.yuque.com/docs/share/…

redis所有的命令在 redis官方文档 中都有,英语不好的可以到redis的中文官网查看,但是可能会出现访问慢的情况

redis命令参考 这个网站,为我们分类并总结了redis相关的命令,并且有代码示例,对于初学者十分友好

在这篇文章中,我只总结了一些常用的命令,更多的命令请参考上面所说的两个网站

注意:redis 命令不区分大小写

如果觉得本文对你有帮助,欢迎关注、点赞、评论、转发

redis数据类型

五种基本数据类型

  • String
  • List
  • Set
  • Hash
  • Zset

三种特殊数据类型

  • geospatial
  • hyperloglog
  • bitmaps

redis中有每一种数据类型都有其特殊的功能,在 官方文档 Data types 中有详细介绍 这些数据类型足以应对日常需求,接下来我们会边学习命令,边学习这些数据类型,因为每一种数据类型都有其对应的命令

redis数据库

redis默认有16个数据库,这里的数据库的概念和mysql中的数据库类似,这个数据库数量可以在配置文件中修改 image.png 在注释中写的很清楚,默认数据库为0号数据库,可以通过select命令来切换数据库

由于Redis不支持自定义数据库的名字,所以每个数据库都以编号命名。开发者则需要自己记录存储的数据与数据库的对应关系。

database 和 keys 相关命令

select

切换数据库,默认为0号数据库

127.0.0.1:6379> select 1
OK

127.0.0.1:6379[1]> select 15
OK

127.0.0.1:6379[15]> select 16       # 数据库默认0-15,超出后报错,并且切换到最后一个数据库
(error) ERR DB index is out of range

可以看到,切换到其他数据库后,在 127.0.0.1:6379 后多了一个数据库的编号,为了告诉你现在处在什么数据库下,十分的友好

dbsize

查看当前数据库下key的数量

127.0.0.1:6379> dbsize            # 没有值
(integer) 0

127.0.0.1:6379> set hello world   # 存入key,set是string数据类型的命令,在后面会详细说明
OK

127.0.0.1:6379> set nihao shijie  # 存入key
OK

127.0.0.1:6379> dbsize            # 有两个key
(integer) 2

keys

查看当前数据库下的key,遍历整个数据库,若key数量很多会阻塞一段时间,因为redis是单线程的

127.0.0.1:6379> set hello world
OK

127.0.0.1:6379> set nihao shijie
OK

127.0.0.1:6379> keys *    # 查看所有的key
1) "nihao"
2) "hello"

127.0.0.1:6379> keys ni*    # 查看ni开头的key
1) "nihao"

scan

与 keys 命令作用相同,只是scan可以限制扫描的范围

127.0.0.1:6379> keys *
1) "girl2"
2) "boy3"
3) "boy1"
4) "boy2"
5) "girl1"
6) "girl3"

127.0.0.1:6379> scan 0  # 0 表示从头开始扫描,扫描数量没有限制
1) "0"                  # 第一个返回值为0表示整个集合都扫描完毕
2) 1) "girl2"           # 第二个返回值是个数组,表示扫描过的key
   2) "girl1"
   3) "boy3"
   4) "girl3"
   5) "boy1"
   6) "boy2"
   
   
127.0.0.1:6379> scan 0 match girl* count 4   # 从头扫描,匹配前缀为girl的key,扫描4个元素
1) "1"                                       # 第一位返回1,1是一个记录,表示下次从1开始扫描后面的元素
2) 1) "girl2"
   2) "girl1"
   3) "girl3"

下面命令都是类似,只是扫描的地方不同:

  • SCAN 命令用于迭代当前数据库中的数据库键。

  • SSCAN 命令用于迭代集合键中的元素。

  • HSCAN 命令用于迭代哈希键中的键值对。

  • ZSCAN 命令用于迭代有序集合中的元素(包括元素成员和元素分值)。

del

删除一个或多个 key

127.0.0.1:6379> set a 1
OK

127.0.0.1:6379> set b 2
OK

127.0.0.1:6379> set c 3
OK

127.0.0.1:6379> del a b c
(integer) 3

127.0.0.1:6379> keys *
(empty list or set)

flushdb

删除当前数据库下所有的key

127.0.0.1:6379> keys *
1) "nihao"
2) "hello"

127.0.0.1:6379> flushdb
OK

127.0.0.1:6379> keys *
(empty list or set)

flushall

删除所有数据库下的key

127.0.0.1:6379> set hello world
OK

127.0.0.1:6379> keys *
1) "hello"

127.0.0.1:6379> select 1
OK

127.0.0.1:6379[1]> set nihao shijie
OK

127.0.0.1:6379[1]> keys *
1) "nihao"

127.0.0.1:6379[1]> flushall
OK

127.0.0.1:6379[1]> keys *
(empty list or set)

127.0.0.1:6379[1]> select 0
OK

127.0.0.1:6379> keys *
(empty list or set)

exists

检查key是否存在

127.0.0.1:6379> exists hello
(integer) 0

127.0.0.1:6379> set hello world
OK

127.0.0.1:6379> exists hello
(integer) 1

move

移动一个key到另一个数据库

127.0.0.1:6379> keys *
1) "hello"

127.0.0.1:6379> move hello 1
(integer) 1

127.0.0.1:6379> keys *
(empty list or set)

127.0.0.1:6379> select 1
OK

127.0.0.1:6379[1]> keys *
1) "hello"

expire

设置key的过期时间

127.0.0.1:6379> set hello world
OK

127.0.0.1:6379> keys *
1) "hello"

127.0.0.1:6379> expire hello 10
(integer) 1

============  10秒后  ==============

127.0.0.1:6379> keys *        
(empty list or set)

ttl

查看key的剩余时间

127.0.0.1:6379> set hello world
OK

127.0.0.1:6379> ttl hello
(integer) -1

127.0.0.1:6379> expire hello 10
(integer) 1

127.0.0.1:6379> ttl hello
(integer) 6
  • 没有设置过期时间的 key 剩余时间为 -1

type

查看key的数据类型

127.0.0.1:6379> set hello world
OK

127.0.0.1:6379> type hello
string

127.0.0.1:6379> lpush aaa bbb   # list命令,后面会详细说明
(integer) 1

127.0.0.1:6379> type aaa
list

String(字符串)

官方说明

String数据类型是我们开发中最常用的数据类型,它是二进制安全的,这意味着它能够容纳任意类型的数据,比如一张 jpeg 图片或者一个序列化的Ruby对象

一个 String 的 value 最大为 512MB

在 Redis 使用 String 可以做很多有趣的事情,例如

  • 使用 String 作为一个原子类型的计数器通过 INCR 这一家族的命令:INCR,DECR,INCRBY
  • 使用 append 命令在 value 后追加字符串
  • 使用 String 作为一个随机访问的向量通过 getRange 和 setRange 命令
  • 在很小的空间内对大量数据进行编码,或者使用 getBit 和 setBit 创建一个支持 Redis 的 Bloom 过滤器。

set

设置一个string类型的key/value

127.0.0.1:6379> set hello world
OK

get

获取String类型的 key 对应的 value 值

127.0.0.1:6379> set hello world
OK

127.0.0.1:6379> get hello
"world"

getset

获取旧的value值,并更新新的value值

127.0.0.1:6379> set num 1
OK

127.0.0.1:6379> getset num 2
"1"

127.0.0.1:6379> get num
"2"

strlen

查看 key 值对应的 value 值的字符串长度

127.0.0.1:6379> set hello world
OK

127.0.0.1:6379> strlen hello
(integer) 5

append

向value值后追加字符串

127.0.0.1:6379> set hello world
OK

127.0.0.1:6379> append hello 123
(integer) 8

127.0.0.1:6379> get hello
"world123"

incr

对 value 的值加一,并返回最终的值,这与 java 中的 i++不同,redis 中的 incr 是个原子操作

127.0.0.1:6379> set hello world
OK

127.0.0.1:6379> incr hello
(error) ERR value is not an integer or out of range

127.0.0.1:6379> set number 1
OK

127.0.0.1:6379> incr number
(integer) 2

127.0.0.1:6379> get number
"2"

注意:只有当 value 值为 integer 时,才能使用 incr 命令

decr

对 value 值减一,并返回最终的值,它也是原子操作

127.0.0.1:6379> set number 1
OK

127.0.0.1:6379> decr number
(integer) 0

incrby

对 value 加一个指定值,并返回最终的值

127.0.0.1:6379> set number 1
OK

127.0.0.1:6379> incrby number 4
(integer) 5

decrby

对 value 减一个指定值,并返回最终的值

127.0.0.1:6379> set number 1
OK

127.0.0.1:6379> decrby number 20
(integer) -19

getRange

获取 key 存储的字符串的指定部分

127.0.0.1:6379> set num abcdefg
OK

127.0.0.1:6379> getrange num 1 3    # 获取第1位到第3位的字符
"bcd"

127.0.0.1:6379> getrange num 1 1    # 获取第1位上的字符
"b"

127.0.0.1:6379> getrange num 0 -1   # 表示获取整个字符串
"abcdefg"

注意,字符串从第0位开始

setRange

往 key 存储的字符串中的指定位置后插入字符串

127.0.0.1:6379> set num abcdefg
OK

127.0.0.1:6379> setrange num 1 123
(integer) 7

127.0.0.1:6379> get num
"a123efg"

setex

set with expire,将 key 的值设为 value,并设置过期时间

127.0.0.1:6379> setex redis 10 123  # 设置key值为123,过期时间10s
OK

127.0.0.1:6379> ttl redis
(integer) 6

setnx

set no exist,如果key不存在则创建 key / value;如果key存在,则不创建。创建成功返回1,失败返回0

127.0.0.1:6379> setnx nihao shijie
(integer) 1

127.0.0.1:6379> keys *
1) "nihao"

127.0.0.1:6379> setnx nihao redis
(integer) 0

127.0.0.1:6379> get nihao
"shijie"

mset

批量创建 key / value

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

127.0.0.1:6379> keys *
1) "a"
2) "c"
3) "b"

msetnx

批量创建 key / value,如果不存在相同的key,这是个原子操作,要么同时创建成功,要么同时创建失败

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

127.0.0.1:6379> msetnx d 4 e 5     # 所有key都不存在,则创建成功
(integer) 1

127.0.0.1:6379> keys *
1) "d"
2) "b"
3) "a"
4) "c"
5) "e"

127.0.0.1:6379> msetnx e 55 f 6 g 7    # 有一个key存在,则全部创建失败
(integer) 0

127.0.0.1:6379> keys *
1) "d"
2) "b"
3) "a"
4) "c"
5) "e"

rename

对存在的key重命名

127.0.0.1:6379> set hello world
OK

127.0.0.1:6379> keys *
1) "hello"

127.0.0.1:6379> rename hello newkey
OK

127.0.0.1:6379> keys *
1) "newkey"

List(链表)

官方说明

Redis list 数据类型是一个字符串的链表,根据插入元素顺序来排序。Redis list 支持往链表的头部和尾部插入元素

lpush 命令往链表的头部插入元素,rpush 往链表的尾部插入元素,当在一个空的 key 中执行这两个命令其中一个后,一个新的 list 就被创建了。当执行 list 相关命令后使得 key 为空时,这个key就会从数据库中移除。这些是非常好理解的语义,因为对一个是空列表的 key 执行 list 命令和对一个不存在的 key 执行 list 命令是一样的

下面是一些 list 命令和执行的结果

lpush mylist a   # now the list is "a"
lpush mylist b   # now the list is "b","a"
rpush mylist c   # now the list is "b","a","c"

list 最多可以有 2^32 - 1 个元素(4294967295,每个list中可以有超过40亿个元素)

从时间复杂度的角度来看,Redis list 的主要特性是支持在链表的头部和尾部附近的元素进行持续时间的插入和删除操作,即使插入的项目有几百万条。在列表的两端访问元素非常快,但是访问很长的链表的中间部位速度会很慢,因为它是一个O(n)的算法

使用Redis list 你能做很多事情,例如

  • 对 socket 网络中的时间线进行建模,使用 lpush 命令在用户的时间线上添加一个新的元素,使用 lrange 来检索一些最近插入的元素
  • 你可以使用 lpush 和 ltrim 命令来创建一个永远不会超过给定数量的元素,但是只记住最新N个元素的列表
  • list 能被用作消息传送,例如著名的 Resque Ruby 库创建后台作业
  • 有了 list 你能做很多事情,the个数据类型支持很多命令,包括像 blpop 的阻塞命令

lpush

从链表头部插入一个或多个元素,list中元素可重复

127.0.0.1:6379> lpush mylist a
(integer) 1

127.0.0.1:6379> lpush mylist b
(integer) 2

127.0.0.1:6379> lpush mylist c d e f
(integer) 6

lrange

查看list中指定位置的元素,list从第0位开始

127.0.0.1:6379> lrange mylist 0 -1     # 查看列表中所有元素
1) "f"
2) "e"
3) "d"
4) "c"
5) "b"
6) "a"

127.0.0.1:6379> lrange mylist 1 3      # 插入列表中第1号位到第3号位的元素
1) "e"
2) "d"
3) "c"

lpushx

当链表存在时,往表头插入元素,否则什么都不做

127.0.0.1:6379> lpushx mylist g
(integer) 7

127.0.0.1:6379> lrange mylist 0 -1
1) "g"
2) "f"
3) "e"
4) "d"
5) "c"
6) "b"
7) "a"

127.0.0.1:6379> lpushx list aaa  # 没有key为list的链表,则什么都不做
(integer) 0

127.0.0.1:6379> keys *
1) "mylist"

rpush

往链表尾部插入元素

127.0.0.1:6379> rpush mylist 1
(integer) 8

127.0.0.1:6379> lrange mylist 0 -1
1) "g"
2) "f"
3) "e"
4) "d"
5) "c"
6) "b"
7) "a"
8) "1"

127.0.0.1:6379> rpush mylist 2 3
(integer) 10

127.0.0.1:6379> lrange mylist 0 -1
 1) "g"
 2) "f"
 3) "e"
 4) "d"
 5) "c"
 6) "b"
 7) "a"
 8) "1"
 9) "2"
10) "3"

rpushx

与 lpushx 相似,往key存在的链表尾部插入值,若不存在,则什么都不做

127.0.0.1:6379> rpushx mylist 4
(integer) 11

127.0.0.1:6379> lrange mylist 0 -1   # mylist存在,插入数据到链表尾部
 1) "g"
 2) "f"
 3) "e"
 4) "d"
 5) "c"
 6) "b"
 7) "a"
 8) "1"
 9) "2"
10) "3"
11) "4"

127.0.0.1:6379> rpushx list 1     # key为list的链表不存在,什么也不干
(integer) 0

127.0.0.1:6379> keys *
1) "mylist"

lpop

从链表头部弹出一个元素,链表元素数量减一

127.0.0.1:6379> lrange mylist 0 -1
1) "4"
2) "3"
3) "2"
4) "1"

127.0.0.1:6379> lpop mylist
"4"

127.0.0.1:6379> lrange mylist 0 -1
1) "3"
2) "2"
3) "1"

rpop

从链表尾部弹出一个元素,链表元素数量减一

127.0.0.1:6379> lrange mylist 0 -1
1) "3"
2) "2"
3) "1"

127.0.0.1:6379> rpop mylist
"1"

127.0.0.1:6379> lrange mylist 0 -1
1) "3"
2) "2"

rpoplpush

从链表尾部弹出元素加入到新链表头部

127.0.0.1:6379> lrange mylist 0 -1
1) "3"
2) "2"

127.0.0.1:6379> rpoplpush mylist list
"2"

127.0.0.1:6379> lrange mylist 0 -1
1) "3"

127.0.0.1:6379> lrange list 0 -1
1) "2"

lrem

删除链表中指定元素

127.0.0.1:6379> lrange mylist 0 -1
1) "3"
2) "3"
3) "2"
4) "1"

127.0.0.1:6379> lrem mylist 2 3     # 删除两个value为3的元素
(integer) 2

127.0.0.1:6379> lrange mylist 0 -1
1) "2"
2) "1"

127.0.0.1:6379> lrem mylist 1 2     # 删除一个value为2的元素
(integer) 1

127.0.0.1:6379> lrange mylist 0 -1
1) "1"

llen

查看list元素的个数

127.0.0.1:6379> lrange mylist 0 -1
1) "4"
2) "3"
3) "2"
4) "1"

127.0.0.1:6379> llen mylist
(integer) 4

lindex

获取指定索引处的元素,索引从0开始

127.0.0.1:6379> lrange mylist 0 -1
1) "4"
2) "3"
3) "2"
4) "1"

127.0.0.1:6379> lindex mylist 2
"2"

127.0.0.1:6379> lindex mylist 1
"3"

linsert

往指定元素的前或后插入元素

127.0.0.1:6379> lrange mylist 0 -1
1) "d"
2) "c"
3) "b"
4) "a"

127.0.0.1:6379> linsert mylist before a 1   # 往指定value值后插入
(integer) 5

127.0.0.1:6379> lrange mylist 0 -1
1) "d"
2) "c"
3) "b"
4) "1"
5) "a"

127.0.0.1:6379> linsert mylist after c 2   # 往指定value值前插入
(integer) 6

127.0.0.1:6379> lrange mylist 0 -1
1) "d"
2) "c"
3) "2"
4) "b"
5) "1"
6) "a"

lset

更新list指定索引位置的value值

127.0.0.1:6379> lrange mylist 0 -1
1) "d"
2) "c"
3) "2"
4) "b"
5) "1"
6) "a"

127.0.0.1:6379> lset mylist 3 1.5
OK

127.0.0.1:6379> lrange mylist 0 -1
1) "d"
2) "c"
3) "2"
4) "1.5"
5) "1"
6) "a"

ltrim

截取指定索引区间的值,与lrange不同之处是 ltrim 会使list中其他元素移除,

127.0.0.1:6379> lrange mylist 0 -1
1) "d"
2) "c"
3) "2"
4) "1.5"
5) "1"
6) "a"

127.0.0.1:6379> ltrim mylist 2 4
OK

127.0.0.1:6379> lrange mylist 0 -1
1) "2"
2) "1.5"
3) "1"

127.0.0.1:6379> ltrim mylist 0 -1   # 这样指令什么都不会截取,链表不变
OK

127.0.0.1:6379> lrange mylist 0 -1
1) "2"
2) "1.5"
3) "1"

blpop

从链表头部弹出元素,若无元素则阻塞,直到等待超时或发现可弹出元素为止 此命令可传入多个key,且按从前往后的顺序弹出第一个有元素的key的表头元素 返回值是弹出元素的key和弹出的value值

127.0.0.1:6379> lrange mylist 0 -1
1) "2"
2) "1.5"
3) "1"

127.0.0.1:6379> blpop mylist 10   # 弹出mylist的表头元素,若无元素则阻塞,最长10秒
1) "mylist"
2) "2"
127.0.0.1:6379> lrange mylist 0 -1
1) "1.5"
2) "1"
																						 # hello为空链表
127.0.0.1:6379> blpop hello mylist list 10   # 从前往后的顺序弹出第一个有元素的key的表头元素
1) "mylist"
2) "1.5"
127.0.0.1:6379> blpop hello 10     #没有元素,阻塞10s
(nil)
(10.08s)

brpop

与 blpop 元素类似,若链表中有元素,弹出的是链表尾部元素,无元素也是会阻塞

127.0.0.1:6379> lrange mylist 0 -1
1) "2"
2) "1.5"
3) "1"

127.0.0.1:6379> brpop mylist 10   # 弹出mylist的表尾元素,若无元素则阻塞,最长10秒
1) "mylist"
2) "1"
127.0.0.1:6379> lrange mylist 0 -1
1) "2"
2) "1.5"
																						 # hello为空链表
127.0.0.1:6379> brpop hello mylist list 10   # 从前往后的顺序弹出第一个有元素的key的表头元素
1) "mylist"
2) "1.5"
127.0.0.1:6379> brpop hello 10     #没有元素,阻塞10s
(nil)
(10.08s)

brpoplpush

从一个链表的尾部弹出元素插入到其他链表的头部,若尾部无数据,则阻塞

127.0.0.1:6379> lrange mylist 0 -1
1) "1"
2) "2"

127.0.0.1:6379> brpoplpush mylist hello 10
"2"

127.0.0.1:6379> lrange mylist 0 -1
1) "1"

127.0.0.1:6379> lrange hello 0 -1
1) "2"

127.0.0.1:6379> brpoplpush aaa hello 10
(nil)
(10.06s)

Set(集合)

官方说明

Redis Set 数据类型是一个无序的字符串集合,它可以使用O(1)的时间复杂度添加、删除和测试元素是否存在(无论集合中有多少元素都能保持恒定)

Redis Set 数据类型具有元素不重复的属性,多次添加相同得元素得到的结果是集合中只存在一个该元素。实际上,这就意味着添加一个元素时不需要先检查该元素是否存在,然后在添加这些操作

一个非常有趣的事情关于 Redis 集合就是它支持许多服务器的命令来从存在的集合开始计算集合,因此你能在很短时间做并(union)集,交(intersection)集和差(different)集

在集合中可以存放最大的元素数量为 2^32 - 1(4294967295,每个集合超过40亿个元素)

你能做很多有趣的事情使用 Redis 集合,例如:

  • 你可以使用 Redis 集合来追踪独一无二的事情。想要知道所有访问某个博客文章的独立IP?每次你处理一个网页的时候简单的使用 sadd 命令,那么你可以肯定重复的 ip 不会被添加

  • Redis 集合能很好的表示关系。你可以使用 redis 来创建一个标签系统,一个集合代表一个标签。然后你可以使用 sadd 命令添加所有拥有标签的对象的所有 id 到一个集合,这样来表示这个特定的tag。你想要获取所有同时有三个不同标签的所有对象的所有 id 吗?使用 sinter 命令即可

  • 你可以使用集合的 spop 和 srandmember 命令来随机获取元素

sadd

添加一个或多个新的元素到集合

127.0.0.1:6379> sadd myset a
(integer) 1

127.0.0.1:6379> sadd myset b c
(integer) 2

127.0.0.1:6379> sadd myset c
(integer) 0

127.0.0.1:6379> smembers myset
1) "b"
2) "c"
3) "a"

smembers

获取集合中的所有元素

127.0.0.1:6379> sadd myset a b c d
(integer) 4

127.0.0.1:6379> smembers myset
1) "b"
2) "c"
3) "a"
4) "d"

scard

获取集合中元素的数量

127.0.0.1:6379> sadd myset a b c d
(integer) 4

127.0.0.1:6379> smembers myset
1) "b"
2) "c"
3) "a"
4) "d"

127.0.0.1:6379> scard myset
(integer) 4

sdiff

一个集合减去另一个集合,存在的元素相减,不会改变原有集合

127.0.0.1:6379> sadd set1 1 2 3
(integer) 3

127.0.0.1:6379> sadd set2 2 3 4
(integer) 3

127.0.0.1:6379> sdiff set1 set2
1) "1"

127.0.0.1:6379> smembers set1
1) "1"
2) "2"
3) "3"

sdiffstore

一个集合减去另一个集合,结果存在一个第三个集合中

127.0.0.1:6379> sadd set1 1 2 3
(integer) 3

127.0.0.1:6379> sadd set2 2 3 4
(integer) 3

127.0.0.1:6379> sdiffstore set3 set1 set2
(integer) 1

127.0.0.1:6379> smembers set3
1) "1"

sinter

求两个集合的交集

127.0.0.1:6379> sadd set1 1 2 3
(integer) 3

127.0.0.1:6379> sadd set2 2 3 4
(integer) 3

127.0.0.1:6379> sinter set1 set2
1) "2"
2) "3"

sinterstore

取两个集合的交集存入第三个集合中

127.0.0.1:6379> sadd set1 1 2 3
(integer) 3

127.0.0.1:6379> sadd set2 2 3 4
(integer) 3

127.0.0.1:6379> sinterstore set4 set1 set2   # set1和set2的交集存入set4
(integer) 2

127.0.0.1:6379> smembers set4
1) "2"
2) "3"

sunion

取两个集合的并集,不改变原来的集合

127.0.0.1:6379> sadd set1 1 2 3
(integer) 3

127.0.0.1:6379> sadd set2 2 3 4
(integer) 3

127.0.0.1:6379> sunion set1 set2
1) "1"
2) "2"
3) "3"
4) "4"

sunionstore

取两个集合的并集,并存入第3个集合中

127.0.0.1:6379> sadd set1 1 2 3
(integer) 3

127.0.0.1:6379> sadd set2 2 3 4
(integer) 3

127.0.0.1:6379> sunionstore set3 set1 set2   # set1和set2的并集存入set3
(integer) 4

127.0.0.1:6379> smembers set3
1) "1"
2) "2"
3) "3"
4) "4"

sismember

判断一个元素是否存在,返回1表示存在,返回0表示不存在

127.0.0.1:6379> smembers set1
1) "1"
2) "2"
3) "3"

127.0.0.1:6379> sismember set1 3
(integer) 1

127.0.0.1:6379> sismember set1 4
(integer) 0

smove

从一个集合中移动一个元素到另一个集合

127.0.0.1:6379> smembers set1
1) "1"
2) "2"
3) "3"

127.0.0.1:6379> smembers set2
1) "2"
2) "3"
3) "4"

127.0.0.1:6379> smove set1 set2 1
(integer) 1

127.0.0.1:6379> smembers set2
1) "1"
2) "2"
3) "3"
4) "4"

127.0.0.1:6379> smembers set1
1) "2"
2) "3"

spop

随机弹出集合中一个或多个元素,返回弹出的n个元素

127.0.0.1:6379> smembers set2
1) "1"
2) "2"
3) "3"
4) "4"

127.0.0.1:6379> spop set2 2
1) "4"
2) "2"

127.0.0.1:6379> smembers set2
1) "1"
2) "3"

srandmember

随机获取集合中的几个元素

127.0.0.1:6379> smembers set1
1) "1"
2) "2"
3) "3"

127.0.0.1:6379> srandmember set1 2   # 随机弹出两个值,集合不变
1) "3"
2) "1"

127.0.0.1:6379> smembers set1
1) "1"
2) "2"
3) "3"

srem

移除一个或多个值,与 spop 命令的返回值不同,srem 返回移除的数量

127.0.0.1:6379> smembers set1
1) "1"
2) "2"
3) "3"

127.0.0.1:6379> srem set1 1 2
(integer) 2

127.0.0.1:6379> smembers set1
1) "3"

Hashes

官方说明

Redis Hash 数据类型是一种在字符串属性和字符串值之间的映射,所以它是一个可以表示对象的完美的数据类型(例如,一个用户对象有name、surname、age等属性)

HMSET user:1000 username antirez password P1pp0 age 34
HGETALL user:1000
HSET user:1000 password 12345
HGETALL user:1000

一个拥有少量字段的 hash (少量意思是100个字段左右)以一种占用很少空间的方式被存储,因此你可以存储数百万个对象在一个小的 redis 实例中

尽管 hash 被主要用来表示对象,但他们也能存储很多的元素,因此你也能使用 hash 做很多其他的任务

每一个 hash 能存储 2^32 - 1 个 key/value 键值对(超过40亿)

hset

往 hash 中添加一个键值对

127.0.0.1:6379> hset user1 name zhangsan
(integer) 1

127.0.0.1:6379> hset user1 age 22
(integer) 1

hsetnx

如果 hash 中不存在指定的字段,则添加,否则什么都不做

127.0.0.1:6379> hsetnx apple color red
(integer) 1

127.0.0.1:6379> hsetnx apple color greed
(integer) 0

127.0.0.1:6379> hsetnx apple weight 12
(integer) 1

hget

获取 hash 中一个键映射的值

127.0.0.1:6379> hset user1 name zhangsan
(integer) 1

127.0.0.1:6379> hset user1 age 22
(integer) 1

127.0.0.1:6379> hget user1 name
"zhangsan"

127.0.0.1:6379> hget user1 age
"22"

hmset

往 hash 中添加多个键值对

127.0.0.1:6379> hmset user1 name zhangsan age 12 sex boy
OK

hmget

获取 hash 中多个键映射的值

127.0.0.1:6379> hmset user1 name zhangsan age 12 sex boy
OK

127.0.0.1:6379> hmget user1 name age sex
1) "zhangsan"
2) "12"
3) "boy"

hgetall

获取 hash 中所有的键和值

127.0.0.1:6379> hmset user1 name zhangsan age 12 sex boy
OK

127.0.0.1:6379> hgetall user1
1) "name"
2) "zhangsan"
3) "age"
4) "12"
5) "sex"
6) "boy"

hkeys

获取 hash 中所有的 key

127.0.0.1:6379> hmset user1 name zhangsan age 12 sex boy
OK

127.0.0.1:6379> hkeys user1
1) "name"
2) "age"
3) "sex"

hvals

获取 hash 中所有的值

127.0.0.1:6379> hmset user1 name zhangsan age 12 sex boy
OK

127.0.0.1:6379> hvals user1
1) "zhangsan"
2) "12"
3) "boy"

hdel

删除 hash 中的一个或多个字段

127.0.0.1:6379> hmset user1 name zhangsan age 12 sex boy
OK

127.0.0.1:6379> hdel user1 age
(integer) 1

127.0.0.1:6379> hgetall user1
1) "name"
2) "zhangsan"
3) "sex"
4) "boy"

hexists

判断一个字段是否存在

127.0.0.1:6379> hmset user1 name zhangsan age 12 sex boy
OK

127.0.0.1:6379> hexists user1 name
(integer) 1

127.0.0.1:6379> hexists user1 location
(integer) 0

hlen

获取 hash 中字段的个数

127.0.0.1:6379> hmset user1 name zhangsan age 12 sex boy
OK

127.0.0.1:6379> hlen user1
(integer) 3

hstrlen

获取 hash 中字段映射的字符串值的长度

127.0.0.1:6379> hmset user1 name zhangsan age 12 sex boy
OK

127.0.0.1:6379> hstrlen user1 name
(integer) 8

hincrby

对 hash 中的字段映射的数字值加指定整数

127.0.0.1:6379> hmset user1 name zhangsan age 12 sex boy
OK

127.0.0.1:6379> hincrby user1 age 2
(integer) 14

127.0.0.1:6379> hget user1 age
"14"

hincrbyfloat

对 hash 中的字段映射的数字值加指定浮点类型的数字

127.0.0.1:6379> hset user1 chinese 89.5
(integer) 1

127.0.0.1:6379> hincrbyfloat user1 chinese 0.2
"89.7"

127.0.0.1:6379> hget user1 age    # 原本age是个整数
"14"

127.0.0.1:6379> hincrbyfloat user2 age 2.5   # 加上一个浮点数还是整数
"2.5"

127.0.0.1:6379> hget user1 age
"14"

注意,这个如果原来的值是一个整数,那么添加一个浮点数以后还是整数,添加浮点数只对原本value值是浮点数的数有作用

Sorted Set

Redis 有序集合和 Redis 集合很类似,是不包含相同字符串的集合。不同之处是每个有序集合中的每个元素自带有一个评分,这个评分用来给有序集合中元素以分数最小到分数最大排序,虽然元素是唯一的,但评分是可以重复的

你可以用很快的方式(时间复杂度为O(logn))对有序集合中元素进行添加,删除,或者更新。因为元素插入时就排好序的,而不是事后排序的,你可以通过评分的范围来很快的获取元素,访问有序集合的中间部分的元素也是非常快的,因此你可以把有序集合作为一个没有重复元素的小链表,你能很快的访问所有你需要的元素:有序元素、快速判断元素是否存在,快速访问中间元素

总而言之,有了有序集合,你能做很多高性能的任务,这个在很多其他类型的数据库中很难模仿

有了有序集合,你可以:

  • 在大量在线游戏中做一个排行榜,每次有新的分数产生,用 zadd 来更新它。你可以使用 zrange 命令轻松获取得分最高的用户,你可以使用 zrank 命令轻松获取指定用户名的排名。同时使用 zrank 和 zrange 命令,你可以获取与给定用户分数一样的其他用户。一切都很快速

  • 有序集合经常被用来检索存储在 redis 中的数据。例如:如果你有很多的hash来表示用户,那么你可以使用一个有序集合,这个集合的年龄字段用来当作评分,用户ID当作值,这样就可以使用 zrangebyscore 命令来快速检索给定年龄段的用户

zadd

添加一个或多个带有评分的值到有序集合中

127.0.0.1:6379> zadd mysort 1 one
(integer) 1

127.0.0.1:6379> zadd mysort 2 two 3 three
(integer) 2

zrange

获取集合中指定范围的元素

127.0.0.1:6379> zadd mysort 1 one
(integer) 1

127.0.0.1:6379> zadd mysort 2 two 3 three
(integer) 2

127.0.0.1:6379> zrange mysort 0 1       # 获取索引0-1范围内的元素
1) "one"
2) "two"

127.0.0.1:6379> zrange mysort 0 -1      # 获取所有元素
1) "one"
2) "two"
3) "three"

127.0.0.1:6379> zrange mysort 0 -1 withscores   # 带有评分
1) "one"
2) "1"
3) "two"
4) "2"
5) "three"
6) "3"

zrevrange

将元素降序排列后获取集合中指定范围的元素

127.0.0.1:6379> zadd myset 0 a 1 b 2 c 3 d
(integer) 4

127.0.0.1:6379> zrevrange myset 0 2
1) "d"
2) "c"
3) "b"

127.0.0.1:6379> zrevrange myset 0 -1
1) "d"
2) "c"
3) "b"
4) "a"

zrangebyscore

根据评分范围获取元素

127.0.0.1:6379> zadd mset 0 a 1 b 2 c 3 d
(integer) 4

127.0.0.1:6379> zrangebyscore mset 0 3
1) "a"
2) "b"
3) "c"
4) "d"

127.0.0.1:6379> zrangebyscore mset 0 2
1) "a"
2) "b"
3) "c"

zrevrangebyscore

将元素降序排列后,根据评分范围获取元素

127.0.0.1:6379> zrange mset 0 -1 withscores
1) "a"
2) "3"
3) "b"
4) "5"
5) "c"
6) "6"
7) "w"
8) "11"

127.0.0.1:6379> zrevrangebyscore mset 10 5 withscores
1) "c"
2) "6"
3) "b"
4) "5"

zrangebylex

当很多元素评分都相同时,默认这些元素按照字典顺序进行升序排序,然后按照规则获取元素

127.0.0.1:6379> zadd myset 0 a 0 b 0 c
(integer) 3

127.0.0.1:6379> zrangebylex myset - +    # - 表示负无限,+ 表示正无限
1) "a"
2) "b"
3) "c"

127.0.0.1:6379> zrangebylex myset [b +   # [ 表示闭区间
1) "b"
2) "c"

127.0.0.1:6379> zrangebylex myset - (c   # ( 表示开区间
1) "a"
2) "b"

zrevrangebylex

当很多元素评分都相同时,使用这个命令会使元素按照字典顺序进行降序排序,然后按照规则获取元素

127.0.0.1:6379> zadd myset 0 a 0 b 0 c 0 d
(integer) 4

127.0.0.1:6379> zrevrangebylex myset + -
1) "d"
2) "c"
3) "b"
4) "a"

127.0.0.1:6379> zrevrangebylex myset [c -
1) "c"
2) "b"
3) "a"

127.0.0.1:6379> zrevrangebylex myset + [b
1) "d"
2) "c"
3) "b"

zlexcount

当很多元素评分都相同时,默认元素按照字典顺序进行升序排序,然后按照规则获取元素的个数

127.0.0.1:6379> zadd myset 0 a 0 b 0 c
(integer) 3

127.0.0.1:6379> zlexcount myset - +
(integer) 3

127.0.0.1:6379> zlexcount myset [b +
(integer) 2

127.0.0.1:6379> zlexcount myset - (c
(integer) 2

这个命令中的规则和 zrangebylex 中的规则一致,用法也很类似

zcard

获取集合中元素的个数

127.0.0.1:6379> zrange mysort 0 -1
1) "one"
2) "two"
3) "three"

127.0.0.1:6379> zcard mysort
(integer) 3

zcount

获取给定评分范围内元素的数量

127.0.0.1:6379> zrange mysort 0 -1 withscores
 1) "one"
 2) "1"
 3) "two"
 4) "2"
 5) "three"
 6) "3"
 7) "four"
 8) "4"
 9) "five"
10) "5"
11) "six"
12) "6"
13) "seven"
14) "7"
15) "eight"
16) "8"
17) "nine"
18) "9"
19) "ten"
20) "10"
127.0.0.1:6379> zcount mysort 2 5
(integer) 4

zscore

获取指定元素的评分

127.0.0.1:6379> zrange mset 0 -1 withscores
1) "a"
2) "3"
3) "b"
4) "5"
5) "c"
6) "6"
7) "w"
8) "11"

127.0.0.1:6379> zscore mset w
"11"

zrank

获取元素的排名,排名从0开始

127.0.0.1:6379> zadd mset 0 a 1 b 2 c 3 d
(integer) 4

127.0.0.1:6379> zrank mset b
(integer) 1

127.0.0.1:6379> zrank mset c
(integer) 2

127.0.0.1:6379> zrank mset a
(integer) 0

zrevrank

将元素降序排列后获取元素排名

127.0.0.1:6379> zrange mset 0 -1 withscores
1) "a"
2) "3"
3) "b"
4) "5"
5) "c"
6) "6"
7) "w"
8) "11"


127.0.0.1:6379> zrevrank mset w
(integer) 0

127.0.0.1:6379> zrevrank mset c
(integer) 1

127.0.0.1:6379> zrevrank mset b
(integer) 2

127.0.0.1:6379> zrevrank mset a
(integer) 3

zincrby

给 value 值的评分加上一个增量(可以是负数)

127.0.0.1:6379> zrange news 0 -1 withscores
1) "one"
2) "1"
3) "two"
4) "2"

127.0.0.1:6379> zincrby news 2 one  
"3"

127.0.0.1:6379> zrange news 0 -1     # 评分改变,排序也随之改变
1) "two"
2) "one"

127.0.0.1:6379> zincrby news -2 one   # 也可以加上一个负数
"1"

127.0.0.1:6379> zrange news 0 -1 withscores
1) "one"
2) "1"
3) "two"
4) "2"

zinterstore

取多个有序集合的交集,交集存入一个新的有序集合中,交集的评分默认为两者评分之和 注意:该指令需指定要进行相交集合的个数

127.0.0.1:6379> zadd zset1 1 a 2 b 3 c
(integer) 3

127.0.0.1:6379> zadd zset2 3 c 4 d 5 e
(integer) 3

127.0.0.1:6379> zinterstore zset3 2 zset1 zset2  #其中的2表示有两个集合进行相交
(integer) 1

127.0.0.1:6379> zrange zset3 0 -1 withscores
1) "c"
2) "6"    # 评分为两个c的评分之和

zpopmax

弹出评分最高的一个或多个元素

127.0.0.1:6379> zadd myset 0 a 1 b 2 c 3 d
(integer) 4

127.0.0.1:6379> zpopmax myset   # 弹出评分最高的一个元素
1) "d"
2) "3"

127.0.0.1:6379> zpopmax myset 2  # 弹出评分最高的两个元素
1) "c"
2) "2"
3) "b"
4) "1"

zpopmin

弹出评分最低的一个或多个元素

127.0.0.1:6379> zadd mset 0 a 1 b 2 c 3 d
(integer) 4

127.0.0.1:6379> zpopmin mset
1) "a"
2) "0"

127.0.0.1:6379> zpopmin mset 2
1) "b"
2) "1"
3) "c"
4) "2"

zrem

删除指定一个或多个元素

127.0.0.1:6379> zadd mset 0 a 1 b 2 c 3 d
(integer) 4

127.0.0.1:6379> zrem mset a
(integer) 1

127.0.0.1:6379> zrem mset b c
(integer) 2

127.0.0.1:6379> zrange mset 0 -1
1) "d"

zremrangebylex

当很多元素评分都相同时,按照字典规则删除指定范围内的元素

127.0.0.1:6379> zadd mset 0 a 0 b 0 c 0 d
(integer) 4

127.0.0.1:6379> zrange mset 0 -1
1) "a"
2) "b"
3) "c"
4) "d"

127.0.0.1:6379> zremrangebylex mset [b (c
(integer) 1

127.0.0.1:6379> zrange mset 0 -1
1) "a"
2) "c"
3) "d"

127.0.0.1:6379> zremrangebylex mset - +  # 删除所有元素
(integer) 3

127.0.0.1:6379> zrange mset 0 -1
(empty list or set)

这里的规则和 zrangebylex 命令中的一样

zrangebyrank

根据排名范围删除元素,排名从0开始

127.0.0.1:6379> zadd mset 0 a 1 b 2 c 3 d
(integer) 4

127.0.0.1:6379> zrange mset 0 -1
1) "a"
2) "b"
3) "c"
4) "d"

127.0.0.1:6379> zremrangebyrank mset 1 2
(integer) 2

127.0.0.1:6379> zrange mset 0 -1
1) "a"
2) "d"

zrangebyscore

根据评分范围删除

127.0.0.1:6379> zrange mset 0 -1 withscores
1) "a"
2) "3"
3) "b"
4) "6"
5) "c"
6) "9"
7) "w"
8) "11"

127.0.0.1:6379> zremrangebyscore mset 4 10  # 删除评分在4到10直接的值
(integer) 2

127.0.0.1:6379> zrange mset 0 -1 withscores
1) "a"
2) "3"
3) "w"
4) "11"

zunionstore

多个集合做并集,并把结果存放其他集合中,有相同得元素则其评分相加

127.0.0.1:6379> zrange mset 0 -1 withscores
1) "a"
2) "3"
3) "b"
4) "5"
5) "c"
6) "6"
7) "w"
8) "11"

127.0.0.1:6379> zrange myset 0 -1 withscores
1) "a"
2) "0"
3) "b"
4) "1"
5) "c"
6) "2"
7) "d"
8) "3"

127.0.0.1:6379> zunionstore set1 2 mset myset
(integer) 5

127.0.0.1:6379> zrange set1 0 -1 withscores
 1) "a"
 2) "3"
 3) "d"
 4) "3"
 5) "b"
 6) "6"
 7) "c"
 8) "8"
 9) "w"
10) "11"

小结

经过艰苦的奋斗,终于把这些基础的命令都过了一遍。虽然这些命令在视频教程或者官方教程找到,但是只有自己动手敲一遍才是真正的会用,真正的理解每一种数据类型的用处。