本文记录了Redis一些常用的命令和说明,并附上简单例子,当做命令手册,以备后面查阅。
目录
10,获得指定分数范围内的升序元素 zrangebyscore
11,获得指定分数范围内的降序元素 zrevrangebyscore
13,删除指定排名范围的元素 zremrangebyrank
14,删除指定分数范围内的元素 zremrangebyscore
一,server端命令
server启动
redis的server的启动有三种方式:
1,直接启动
在redis安装目录的bin目录下有redis-server文件,这是和redis服务相关的文件,可以在bin目录下执行:
./redis-server start
或
./redis-server start &
&的作用是把redis作为后台程序启动
2,指定配置文件启动
如果我们自己写一个redis的配置文件,比如/etc/redis/6379.conf,那么可以执行:
./redis-server /etc/redis/6379.conf
3,开机自启动
需要写脚本并在服务器中设置自启动,网上教程一大堆。
server停止
执行:
./redis-server stop
或用redis-cli客户端登录,然后执行:
shutdown
或
shutdown save
或
shutdown nosave
save和nosave表示redis服务停止时是否生成持久化文件
server重启
执行:
./redis-server restart
二,client端命令
用客户端连接redis服务
在redis安装目录的bin目录下有redis-cli文件,这是和客户端相关的文件,可以执行:
./redis-cli
或
./redis-cli –p 7339
-p参数代表更改客户端连接的端口号,因为redis服务启动时不一定用的是redis默认端口号(默认端口号是6379)
三,Redis的key
redis采用key-value的形式保存数据,key都是字符串,对key的操作有:
1,查找key
keys pattern
pattern除了使用具体的字符串之外还可以使用通配符:
- ?,任意一个字符
- *,任意数量字符,包括0个
- [],括号中的任意字符,可以用“-”代表范围
- \x,转义字符,比如\?代表?
比如查找abc开头的key:
keys abc*
查找所有key:
keys *
2,查看某个key是否存在
exists temp
3,删除key
del temp
4,设置某个key的过期时间
expire temp 10
单位是秒
5,查看某个key的过期时间
ttl temp
返回值是秒数,返回-1则表示没有过期时间,key将一直存在,返回-2表示key不存在
四,Redis的value
Redis定义了redisObject结构体来描述Redis的数据,定义在redis.h文件中,结构体内容如下:
typedef struct redisObject {
unsigned type:4;
unsigned encoding:4;
unsigned lru:REDIS_LRU_BITS; /* lru time (relative to server.lruclock) */
int refcount;
void *ptr;
} robj;
其中encoding是编码方式,我们可以用:
object encoding key
来查看某个key下value的编码方式:
127.0.0.1:7379> get temp
"1"
127.0.0.1:7379> object encoding temp
"int"
redisObject的type是数据类型,也就是value的数据类型,有5种形式,分别是:
- 字符串(String)
- 哈希(Hash)
- 列表(List)
- 集合(Set)
- 有序集合(Sorted Set)
下面分别看一下这几种数据在redis中怎么玩
字符串类型
字符串类型在Redis中最大保存512M
1,设置值 set
set key value [EX seconds] [PX milliseconds] [NX|XX]
- EX seconds,过期时间,单位秒
- PX milliseconds,过期时间,单位毫秒
- NX,key不存在时才能成功,也就是必须是新增
- XX,可以必须存在时才能成功,也就是必须是更新
说明:
1,不设置过期时间的情况下,key将一直存在,查看这个key的过期时间时将返回-1:
set temp abc
2,设置过期时间,EX可以大写也可以小写:
set temp abc ex 10
代表temp这个key在10秒后失效
3,一条命令中EX和PX可以都写,以后面的为准
set temp abc PX 2000 EX 5
最终这个key的过期时间是5秒而不是2秒
4,NX和XX参数的使用:
当使用NX或XX时,操作成功返回OK,操作失败返回(nil)
127.0.0.1:7379> set temp abc ex 20 nx
OK
1秒后:
127.0.0.1:7379> set temp abcd ex 20 nx
(nil)
127.0.0.1:7379> get temp
"abc"
5,Redis有setnx和setxx命令,可以实现set+NX和set+XX的效果,返回操作成功的条数,但是这俩命令不能设置过期时间,即key都是永久存在。想设置过期时间就再用expire命令设置。
127.0.0.1:7379> setnx temp abc ex 20
(error) ERR wrong number of arguments for 'setnx' command
127.0.0.1:7379> setnx temp abc
(integer) 1
127.0.0.1:7379> setnx temp abc
(integer) 0
127.0.0.1:7379> get temp
"abc"
6,NX和XX可以用作同步锁。
7,时间复杂度:O(1)
2,获取值 get
get key
这个命令比较简单,获得key对应的value,要是没有这个key则返回(nil)
127.0.0.1:7379> get temp
"abc"
127.0.0.1:7379> get tempaaa
(nil)
时间复杂度:O(1)
3,批量设置值 mset
mset key1 value1 key2 value2 ….
key后面跟着value,成对出现,对数不限
127.0.0.1:7379> mset temp1 111 temp2 222 temp3 333
OK
时间复杂度:O(n),n是key-value的个数
4,批量获取值 mget
mget key1 key2 …
把key排在一起,个数不限,返回信息的排序和命令中key的排序相同
127.0.0.1:7379> mget temp1 temp2 temp3 temp4
1) "111"
2) "222"
3) "333"
4) (nil)
时间复杂度:O(n),n是key的个数
5,自增 incr
incr key
说明:
1,如果key存在,且不是整数类型,返回错误。
2,如果key不存在,则创建这个key,并从0开始自增,返回1。
3,如果key存在,而且是整数类型,则+1并返回加一后的结果。
127.0.0.1:7379> get temp
"abc"
127.0.0.1:7379> incr temp
(error) ERR value is not an integer or out of range
127.0.0.1:7379> del temp
(integer) 1
127.0.0.1:7379> incr temp
(integer) 1
127.0.0.1:7379> incr temp
(integer) 2
4,按人工设置的数字自增:
incrby key num
num是每次自增的数值,该命令和incr的区别就在于incr每次+1,incrby需要自己设置自增数值
127.0.0.1:7379> incr temp
(integer) 2
127.0.0.1:7379> incrby temp 3
(integer) 5
127.0.0.1:7379> incr temp
(integer) 6
5,按人工设置的浮点数自增:
incrbyfloat key num
这里的num可以是小数可以是整数
127.0.0.1:7379> get temp
"6"
127.0.0.1:7379> incrbyfloat temp 1.1
"7.1"
6,时间复杂度:O(1)
6,自减 decr
decr key
和自增相似的是:需要key是整数,key不存在时从0开始减,返回-1,提供了decrby命令设置自减数值。
和自增不同的是:没有decrbyfloat命令减少一定的浮点数值
时间复杂度:O(1)
7,追加 append
append key value
用于往指定key的value后面加上某个字符串,返回最终字符串的长度
127.0.0.1:7379> get temp
"-4"
127.0.0.1:7379> append temp abc
(integer) 5
127.0.0.1:7379> get temp
"-4abc"
时间复杂度:O(1)
8,字符串长度 strlen
strlen key
返回value字符串的长度,英文一个字母长度是1,中文一个汉字长度是2。
127.0.0.1:7379> set temp -abcde
OK
127.0.0.1:7379> get temp
"-abcde"
127.0.0.1:7379> strlen temp
(integer) 6
时间复杂度:O(1)
9,设置并返回原值 getset
getset key value
设置值并返回原值
127.0.0.1:7379> get temp
"-abcde"
127.0.0.1:7379> getset temp abc
"-abcde"
127.0.0.1:7379> get temp
"abc"
时间复杂度:O(1)
10,替换指定位置的字符 setrange
setrange key offset value
类似word中的改写模式,实际上是从指定位置覆盖字符串,从offset的位置开始,也就是从第offset+1个字符开始,后面的的字符依次替换为指定字符,返回字符串长度。
比如字符串abcde,offset为3,替换为字符串pp,则从字符d开始,de字符将被替换为pp字符
127.0.0.1:7379> set temp abcde
OK
127.0.0.1:7379> setrange temp 3 pp
(integer) 5
127.0.0.1:7379> get temp
"abcpp"
时间复杂度:O(1)
11,获得部分字符串 getrange
getrange key start end
获得从指定位置开始,到指定位置结束的字符串,这里的start和end可以理解为字符在字符串中的位置坐标,第一个字符坐标是0,并且起止两端都是闭包的,比如:
127.0.0.1:7379> get temp
"abcde"
127.0.0.1:7379> getrange temp 2 3
"cd"
127.0.0.1:7379> getrange temp 2 4
"cde"
127.0.0.1:7379> getrange temp 2 -2
"cd"
127.0.0.1:7379> getrange temp 2 -1
"cde"
127.0.0.1:7379> getrange temp 2 1
""
可以看到,坐标可以是负的,负数代表从字符串末尾往前数,最后一个字符坐标是-1
时间复杂度:O(n),n是字符串长度
12,字符串类型的内部编码
在3.0版本之前的编码规则:
- int:数字类型的整数
- raw,字符串类型,或者大于39字节的数字
3.0版本之后的编码规则:
- int,数字类型,8字节
- embstr,小于等于39字节的字符串类型
- raw,大于等于39字节的字符串或数字
哈希类型
哈希类型和字符串类型的区别,就是哈希类型的value不是一个单纯的字符串,而且是多个field-value的组合,注意这里的field不是redis的key,而是属于value中的,类似下面这种结构:
key:student1,value:{field1:liang,field2:20}
下面看一下哈希类型相关的命令
1,设置值 hset
hset key field value
也就是设置某个key下的某个field的值
返回值:如果设置成功,且此field为新增,则返回1,不是新增(修改field的值)则返回0,设置失败返回0。
时间复杂度:O(1)
有和字符串类型相似的hsetnx,只有当数值不存在时才能设置成功
但是没有hsetxx命令
127.0.0.1:7379> hset temp name jim
(integer) 1
127.0.0.1:7379> hsetnx temp name tom
(integer) 0
127.0.0.1:7379> hget temp name
"jim"
127.0.0.1:7379> hset temp name tom
(integer) 0
127.0.0.1:7379> hget temp name
"tom"
2,获取值 hget
hget key field
当key或者field不存在时,返回nil
时间复杂度:O(1)
127.0.0.1:7379> hget temp name
"jim"
127.0.0.1:7379> hget tempabc name
(nil)
3,删除field hdel
hdel key field1 field2 …
可以同时删除多个field,返回值是删除成功的field个数
时间复杂度:O(n),n是field个数
127.0.0.1:7379> hset temp name1 jim
(integer) 1
127.0.0.1:7379> hset temp name2 tom
(integer) 1
127.0.0.1:7379> hdel temp name3
(integer) 0
127.0.0.1:7379> hdel temp name1 name2 name3
(integer) 2
4,批量设置field hmset
hmset key field1 value1 field2 value2 …
field和对应的value放在一起,设置成功则返回OK
时间复杂度:O(n),n是field个数
127.0.0.1:7379> hmset temp name1 jim name2 tom
OK
5,批量获得field hmget
hmget key field1 field2 …
返回值按照命令中field的顺序排列,如果某个field不存在,对应的返回值就是nil
时间复杂度:O(n),n是field个数
127.0.0.1:7379> hmset temp name1 jim name2 tom
OK
127.0.0.1:7379> hmget temp name1 name2 name3
1) "jim"
2) "tom"
3) (nil)
6,判断某个field是否存在 hexists
hexists key field
存在返回1,不存在返回0
时间复杂度:O(1)
127.0.0.1:7379> exists temp
(integer) 1
127.0.0.1:7379> hexists temp name1
(integer) 1
127.0.0.1:7379> hexists temp name3
(integer) 0
7,获得field个数 hlen
hlen key
如果key不存在,则返回0
时间复杂度:O(1)
127.0.0.1:7379> hlen temp
(integer) 2
8,获得所有field hkeys
hkeys key
得到某个key对应的value中所有field的名字
时间复杂度:O(n),n是field总个数
127.0.0.1:7379> hkeys temp
1) "name1"
2) "name2"
127.0.0.1:7379> hkeys temp2
(empty list or set)
9,获得所有field的value值 hvals
hvals key
得到某个key对应的value中所有field对应的value
时间复杂度:O(n),n是field总个数
127.0.0.1:7379> hvals temp
1) "jim"
2) "tom"
10,获得所有的field-value hgetall
hgetall key
返回值中field和value分行显示,每两行代表一对field和value
时间复杂度:O(n),n是field总个数
127.0.0.1:7379> hgetall temp
1) "name1"
2) "jim"
3) "name2"
4) "tom"
11,自增 hincrby
hincrby key field increment
和字符串的自增命令incrby差不多,只不过这里是针对field的value的数值增加
如果field不存在,则从0开始自增
返回增加后的数值
同时有hincrbyfloat命令,用法和hincrby相同,用于增加小数
时间复杂度:O(1)
127.0.0.1:7379> hincrby temp age 2
(integer) 2
127.0.0.1:7379> hincrby temp age 3
(integer) 5
127.0.0.1:7379> hincrbyfloat temp age 2.3
"7.3"
12,获得value字符串长度 hstrlen
hstrlen key field
从版本3.2开始出现的命令,和字符串中的strlen命令差不多,只不过这里是针对field的value的。
时间复杂度:O(1)
13,哈希类型的内部编码
- ziplist:压缩列表。元素个数少于 hash-max-ziplist-entries,且每个元素的大小都小于hash-max-ziplist-value时,使用ziplist。
- hashtable:哈希表。除ziplist之外的情况使用hashtable,比如元素个数大于hash-max-ziplist-entries,或者有元素大小大于hash-max-ziplist-value时。
注: hash-max-ziplist-entries和hash-max-ziplist-value都是可配置的,hash-max-ziplist-entries默认512,hash-max-ziplist-value默认64字节。
列表类型
列表类型是存储有序字符串的一种类型,redis提供了从列表头部或尾部添加、获得、删除元素的命令,也有按照索引序号(从0开始计数)获得元素的命令。
所以列表类型的特点:有序,元素可重复。
列表有左右的概念,左边是列表的头部,索引序号从0开始,右边是列表的尾部,索引序号从-1开始。
1,从右边插入元素 rpush
rpush key value1 value2 …
可以同时插入多个元素
返回值是列表中所有元素个数,注意不是命令中的元素个数
如果key不存在,则会新建空列表并依次插入元素。
时间复杂度:O(n),n是value的个数。
127.0.0.1:7379> rpush temp a b c
(integer) 3
127.0.0.1:7379> lrange temp 0 -1
1) "a"
2) "b"
3) "c"
于是列表元素列表就是a,b,c
lrange是查看列表元素的命令。
2,从左边插入元素 lpush
lpush key value1 value2 …
和rpush规则基本相同,在左侧依次插入元素,这会导致列表中元素的顺序和命令中的顺序相反。
返回值是列表中所有元素个数,注意不是命令中的元素个数。
时间复杂度:O(n),n是value的个数。
127.0.0.1:7379> lpush temp a b c
(integer) 3
127.0.0.1:7379> lrange temp 0 -1
1) "c"
2) "b"
3) "a"
可以看到,因为是从左侧(头部)依次插入元素,所以最终列表的元素顺序和命令中的元素顺序是相反的。
3,向指定元素前后插入元素 linsert
linsert key before|after pivot value
其中pivot参数就是在列表中指定的元素的值,注意,不是下标,而是值本身,所以当这个值在列表中有重复时,只会在第一个目标元素前后进行插入。
返回值是列表中所有元素个数。
时间复杂度:O(n),n是pivot元素距离列表开头或末尾的距离。
127.0.0.1:7379> lrange temp 0 -1
1) "d"
2) "b"
3) "c"
4) "b"
5) "a"
127.0.0.1:7379> linsert temp after b aaa
(integer) 6
127.0.0.1:7379> lrange temp 0 -1
1) "d"
2) "b"
3) "aaa"
4) "c"
5) "b"
6) "a"
4,获得指定范围内的元素列表 lrange
lrange key start end
start和end是索引序号,从左到右是0到N-1,从右到左是-1到-N
start和end左右都是闭包的
时间复杂度:O(s+n),s是start的偏移量,n是start到stop的距离。
127.0.0.1:7379> rpush temp a b c d e f
(integer) 6
127.0.0.1:7379> lrange temp 1 3
1) "b"
2) "c"
3) "d"
5,获得指定索引坐标的元素 lindex
lindex key index
其中index就是索引坐标
时间复杂度:O(n),n是index的偏移量。
127.0.0.1:7379> rpush temp a b c d e f
(integer) 6
127.0.0.1:7379> lindex temp 2
"c"
6,获得列表长度 llen
llen key
获得列表长度,也就是元素个数。注意命令里有两个l字母。
时间复杂度:O(1)。
127.0.0.1:7379> rpush temp a b c d e f
(integer) 6
127.0.0.1:7379> llen temp
(integer) 6
7,从列表左侧删除元素 lpop
lpop key
返回值是被删除的元素。
时间复杂度:O(1)。
127.0.0.1:7379> lrange temp 0 -1
1) "a"
2) "b"
3) "c"
4) "d"
5) "e"
6) "f"
127.0.0.1:7379> lpop temp
"a"
127.0.0.1:7379> lrange temp 0 -1
1) "b"
2) "c"
3) "d"
4) "e"
5) "f"
8,从列表右侧删除元素 rpop
rpop key
返回值是被删除的元素。
时间复杂度:O(1)。
127.0.0.1:7379> lrange temp 0 -1
1) "b"
2) "c"
3) "d"
4) "e"
5) "f"
127.0.0.1:7379> rpop temp
"f"
127.0.0.1:7379> lrange temp 0 -1
1) "b"
2) "c"
3) "d"
4) "e"
9,删除指定元素 lrem
lrem key count value
删除元素值等于value的元素,count代表最多删除的个数
返回值是实际被删除的元素个数
时间复杂度:O(n),n是列表长度。
当count>0时,从左到右删除最多count个元素:
127.0.0.1:7379> rpush temp a b aaa c d aaa e f aaa g
(integer) 10
127.0.0.1:7379> lrem temp 2 aaa
(integer) 2
127.0.0.1:7379> lrange temp 0 -1
1) "a"
2) "b"
3) "c"
4) "d"
5) "e"
6) "f"
7) "aaa"
8) "g"
可见删掉了从左边起的两个aaa元素。
当count<0时,从右向左删除最多count个元素:
127.0.0.1:7379> lrange temp 0 -1
1) "a"
2) "b"
3) "aaa"
4) "c"
5) "d"
6) "aaa"
7) "e"
8) "f"
9) "aaa"
10) "g"
127.0.0.1:7379> lrem temp -2 aaa
(integer) 2
127.0.0.1:7379> lrange temp 0 -1
1) "a"
2) "b"
3) "aaa"
4) "c"
5) "d"
6) "e"
7) "f"
8) "g"
可以看到删除了后面的两个aaa元素。
当count=0时,删除所有对应元素:
127.0.0.1:7379> lrange temp 0 -1
1) "a"
2) "b"
3) "aaa"
4) "c"
5) "d"
6) "aaa"
7) "e"
8) "f"
9) "aaa"
10) "g"
127.0.0.1:7379> lrem temp 0 aaa
(integer) 3
127.0.0.1:7379> lrange temp 0 -1
1) "a"
2) "b"
3) "c"
4) "d"
5) "e"
6) "f"
7) "g"
可以看到删除了所有的aaa元素。
10,按照索引坐标修剪列表 ltrim
ltrim key start stop
start和stop都是索引坐标,命令执行后列表只保存开始和结束坐标之间的部分,其他元素全部删除。
start和stop两端都是闭包的。
命令执行成功则返回ok。
时间复杂度:O(n),n是要删除的元素个数。
127.0.0.1:7379> lrange temp 0 -1
1) "a"
2) "b"
3) "c"
4) "d"
5) "e"
6) "f"
7) "g"
127.0.0.1:7379> ltrim temp 3 5
OK
127.0.0.1:7379> lrange temp 0 -1
1) "d"
2) "e"
3) "f"
11,修改指定索引坐标的元素 lset
lset key index value
index是索引坐标。
执行成功则返回OK。
索引坐标无效则会返回错误。
时间复杂度:O(n),n是index的偏移量。
127.0.0.1:7379> lrange temp 0 -1
1) "a"
2) "b"
3) "c"
127.0.0.1:7379> lset temp 3 aaa
(error) ERR index out of range
127.0.0.1:7379> lset temp 2 aaa
OK
127.0.0.1:7379> lrange temp 0 -1
1) "a"
2) "b"
3) "aaa"
12,阻塞删除 blpop/brpop
blpop key1 key2 …. timeout
brpop key1 key2 …. timeout
blpop和brpop是lpop和rpop的阻塞版本,功能也是从列表的左侧或右侧删除元素。
可以指定多个列表的key。
timeout是最长阻塞时间,单位是秒,不一定设置了最长阻塞时间就一定会阻塞这么长时间。
时间复杂度:O(1)。
返回值:
- 如果列表不为空,返回删除元素的key和这个key下被删除的元素,不返回时间。
- 如果列表为空,超时返回,则返回nil和阻塞时间。
- 如果列表为空,且超时时间到达前往列表里添加了元素,则返回key和删除的元素,另外显示阻塞时间。
说明:
1,blpop和brpop是lpop和rpop的阻塞版本,首先他们的功能是从列表的左侧或右侧删除元素,另外这个命令设置了超时时间,这个超时时间代表了命令的最长阻塞时间。
2,当列表不为空时,命令会立即返回,无视阻塞时间。
3,当列表为空且timeout>0时,命令会阻塞,并在timeout时间到达后返回。
4,当列表为空且timeout=0时,命令会一直阻塞,直到有列表添加了元素为止。
5,多个客户端都对同一个key执行blpop或brpop命令时,第一个开始执行该命令的客户端可以返回结果(也就是按开始执行的顺序)。
6,当在一个命令中指定了多个key并阻塞时(也就是这些列表中都没有元素),只要往其中任意一个列表添加了元素,这个命令就会返回,返回值就是添加元素的那个列表和被删除的元素,还有阻塞时间。
举一个超时返回的例子:
127.0.0.1:7379> lrange temp 0 -1
1) "a"
127.0.0.1:7379> blpop temp 3
1) "temp"
2) "a"
127.0.0.1:7379> blpop temp 3
(nil)
(3.72s)
第一个blpop命令执行时,列表中有一个元素a,这个命令会立即返回(即使设置了3秒的阻塞时间)。
第二个blpop命令执行时,列表中没有元素,那么blpop命令是在3秒后返回。
一个超时时间内添加元素并返回的例子:
打开两个客户端,在第一个客户端执行命令:
127.0.0.1:7379> llen temp
(integer) 0
127.0.0.1:7379> blpop temp 10
此时该命令会阻塞
在第二个客户端中执行命令:
127.0.0.1:7379> llen temp
(integer) 0
127.0.0.1:7379> rpush temp a
(integer) 1
执行完rpush命令后,第一个客户端立刻返回结果:
127.0.0.1:7379> llen temp
(integer) 0
127.0.0.1:7379> blpop temp 10
1) "temp"
2) "a"
(1.65s)
可以看到第一个客户端的blpop命令删除了temp的a元素,阻塞时间是1.65秒。
一个指定多个元素并返回的例子:
打开两个客户端,在第一个客户端执行命令:
127.0.0.1:7379> llen temp
(integer) 0
127.0.0.1:7379> llen temp2
(integer) 0
127.0.0.1:7379> blpop temp temp2 10
temp和temp2这个两个列表都为空,所以命令阻塞。
在第二个客户端中执行命令:
127.0.0.1:7379> rpush temp2 a
(integer) 1
这时第一个客户端立刻返回结果:
127.0.0.1:7379> llen temp2
(integer) 0
127.0.0.1:7379> blpop temp temp2 10
1) "temp2"
2) "a"
(2.34s)
可见当temp2中添加了元素后,blpop命令立刻返回了结果,返回的是列表temp2的名字和在temp2中删除的元素a,还有命令的阻塞时间2.34秒。
13,列表类型的内部编码
- ziplist:压缩列表。元素个数少于 hash-max-ziplist-entries,且每个元素的大小都小于hash-max-ziplist-value时,使用ziplist。
- linkedlist:链表。除ziplist之外的情况使用linkedlist,比如元素个数大于hash-max-ziplist-entries,或者有元素大小大于hash-max-ziplist-value时。
注: hash-max-ziplist-entries和hash-max-ziplist-value都是可配置的,hash-max-ziplist-entries默认512,hash-max-ziplist-value默认64字节。
集合类型
集合类型set,也是Redis用来存储多个字符串用的类型
和列表list的不同:
1,set中的元素是不能重复的。
2,set是无序的,也就是没有索引坐标。
另外,作为集合,Redis提供了取交集,并集,差集等操作。
1,添加元素 sadd
sadd key member1 member2 ….
可以同时添加多个元素
返回值是添加成功的元素个数,也就是说,和现有元素重复的元素不会被添加,也不会反映到返回值中。
时间复杂度:O(n),n是添加的元素个数。
127.0.0.1:7379> sadd temp a b c
(integer) 3
127.0.0.1:7379> sadd temp a b c d
(integer) 1
2,删除元素 srem
srem key member1 member2 …
可以同时删除多个元素
返回值是删除元素的个数
时间复杂度:O(n),n是删除的元素个数。
127.0.0.1:7379> sadd temp a b c d
(integer) 4
127.0.0.1:7379> srem temp c d e
(integer) 2
元素e不存在,所以只删除了元素c和d,返回值是2
3,计算元素个数 scard
scard key
时间复杂度:O(1),不会遍历所有元素,这个数字是直接读取的。
127.0.0.1:7379> sadd temp a b c
(integer) 3
127.0.0.1:7379> scard temp
(integer) 3
4,元素是否在集合中 sismember
sismember key member
包含则返回1,不包含则返回0
时间复杂度:O(1)。
127.0.0.1:7379> sadd temp a b c
(integer) 3
127.0.0.1:7379> sismember temp a
(integer) 1
127.0.0.1:7379> sismember temp d
(integer) 0
5,从集合中随机返回元素 srandmember
srandmember key [count]
count参数指的是随机返回元素的个数
- 如果没写count参数,则随机返回集合中的一个元素
- 如果count=0,则不会返回元素(返回空集合)
- 如果count大于集合元素总数,则返回所有元素
- 如果count<0,则返回去掉负号的count个元素。
时间复杂度:O(count)。
127.0.0.1:7379> sadd temp a b c d e
(integer) 5
127.0.0.1:7379> srandmember temp 0
(empty list or set)
127.0.0.1:7379> srandmember temp 9
1) "d"
2) "a"
3) "b"
4) "c"
5) "e"
127.0.0.1:7379> srandmember temp 2
1) "e"
2) "a"
127.0.0.1:7379> srandmember temp 2
1) "d"
2) "a"
127.0.0.1:7379> srandmember temp -2
1) "b"
2) "a"
127.0.0.1:7379> srandmember temp -2
1) "b"
2) "a"
6,从集合中随机删除元素 spop
spop key [count]
在Redis 3.0版本以及更早的版本中,count参数不可用。
在Redis 3.0以后的版本中,count是可选参数,和srandmember中的count规则基本相同。
返回值是被删除的元素。
时间复杂度:O(1)。
127.0.0.1:7379> sadd temp a b c d e
(integer) 5
127.0.0.1:7379> spop temp
"b"
7,获得集合所有元素 smemebers
smembers key
集合是无序的,所以这个命令得到的元素顺序和元素的添加顺序也不同。
时间复杂度:O(n),n是元素总数。
127.0.0.1:7379> sadd temp a b c d e
(integer) 5
127.0.0.1:7379> smembers temp
1) "d"
2) "a"
3) "c"
4) "b"
5) "e"
8,获得交集 sinter
sinter key1 key2 …
可以获得多个集合的交集。
时间复杂度:O(m*k),m是元素最少的集合的元素数,k是元素个数。
127.0.0.1:7379> smembers temp
1) "d"
2) "a"
3) "c"
4) "b"
5) "e"
127.0.0.1:7379> smembers temp2
1) "e"
2) "d"
3) "f"
4) "c"
5) "g"
127.0.0.1:7379> smembers temp3
1) "e"
2) "d"
3) "h"
127.0.0.1:7379> sinter temp temp2 temp3
1) "e"
2) "d"
最后获得了交集d和e
9,获得并集 sunion
sunion key1 key2 …
可以获得多个集合的并集。
时间复杂度:O(n),n是所有集合的元素总数。
127.0.0.1:7379> smembers temp
1) "d"
2) "a"
3) "c"
4) "b"
5) "e"
127.0.0.1:7379> smembers temp2
1) "e"
2) "d"
3) "f"
4) "c"
5) "g"
127.0.0.1:7379> sunion temp temp2
1) "d"
2) "e"
3) "c"
4) "f"
5) "a"
6) "g"
7) "b"
10,获得差集 sdiff
sdiff key1 key2 …
可以获得多个集合的差集。
时间复杂度:O(n),n是所有集合的元素总数。
127.0.0.1:7379> smembers temp
1) "d"
2) "a"
3) "c"
4) "b"
5) "e"
127.0.0.1:7379> smembers temp2
1) "e"
2) "d"
3) "f"
4) "c"
5) "g"
127.0.0.1:7379> sdiff temp temp2
1) "a"
2) "b"
11,把交集的结果保存成新的集合 sinterstore
sinterstore destination key1 key2 …
destination就是新集合的名字,后面的参数可以是多个key
返回值是新集合的元素个数。
时间复杂度:O(m*k),m是元素最少的集合的元素数,k是元素个数。
127.0.0.1:7379> smembers temp
1) "d"
2) "e"
3) "c"
4) "a"
5) "b"
127.0.0.1:7379> smembers temp2
1) "d"
2) "e"
3) "c"
4) "f"
5) "g"
127.0.0.1:7379> sinterstore intertemp temp temp2
(integer) 3
127.0.0.1:7379> smembers intertemp
1) "e"
2) "d"
3) "c"
12,把并集的结果保存成新的集合 sunionstore
sunionstore destination key1 key2 …
destination就是新集合的名字,后面的参数可以是多个key
返回值是新集合的元素个数。
时间复杂度:O(n),n是所有集合的元素总数。
127.0.0.1:7379> smembers temp
1) "d"
2) "e"
3) "c"
4) "a"
5) "b"
127.0.0.1:7379> smembers temp2
1) "d"
2) "e"
3) "c"
4) "f"
5) "g"
127.0.0.1:7379> sunionstore uniontemp temp temp2
(integer) 7
127.0.0.1:7379> smembers uniontemp
1) "d"
2) "e"
3) "c"
4) "f"
5) "a"
6) "g"
7) "b"
12,把差集的结果保存成新的集合 sdiffstore
sdiffstore destination key1 key2 …
destination就是新集合的名字,后面的参数可以是多个key
返回值是新集合的元素个数。
时间复杂度:O(n),n是所有集合的元素总数。
127.0.0.1:7379> smembers temp
1) "d"
2) "e"
3) "c"
4) "a"
5) "b"
127.0.0.1:7379> smembers temp2
1) "d"
2) "e"
3) "c"
4) "f"
5) "g"
127.0.0.1:7379> sdiffstore difftemp temp temp2
(integer) 2
127.0.0.1:7379> smembers difftemp
1) "a"
2) "b"
13,集合类型的内部编码
- intset:整数集合。元素个数少于 set-max-intset-entries,且每个元素都是整数时,使用intset。
- hashtable:哈希表。除intset之外的情况使用hashtable。
注: set-max-intset-entries是可配置的,默认512。
有序集合类型
有序集合类型的特点:
1,有序集合是集合的一种,所以里面的元素不能重复。
2,有序。给每个元素设置一个分数(score),按照分数排序。不同元素的分数可以相同。需要注意的是有序集合的排序方式和列表不同,列表是按照插入顺序,但有序集合是按照分数排序。
1,添加元素 zadd
zadd key [NX|XX] [CH] [INCR] score1 member1 score2 member2 ….
NX和XX参数,Redis3.0.2版本开始使用,和set命令中的相同,分别是在元素不存在和存在时才能添加。
CH参数,Redis3.0.2版本开始使用,表示返回有序集合中元素和分数变化的个数。
INCR,Redis3.0.2版本开始使用,参数表示对score做增加。
时间复杂度:O(k*log(n)),k是要添加的元素个数,n是现在集合中的元素个数。比集合类型要慢,因为要排序。
127.0.0.1:7379> zadd temp 1 jim 2 tom
(integer) 2
2,获得成员个数 zcard
zcard key
时间复杂度:O(1)
举例:
127.0.0.1:7379> zadd temp 1 jim 2 tom
(integer) 2
127.0.0.1:7379> zcard temp
(integer) 2
3,获得成员分数 zscore
zscore key member
时间复杂度:O(1)
举例:
127.0.0.1:7379> zadd temp 1 jim 2 tom
(integer) 2
127.0.0.1:7379> zscore temp tom
"2"
4,计算成员升序排名 zrank
zrank key member
排名从0开始
时间复杂度:O(log(n)),n是有序集合的元素个数
举例:
127.0.0.1:7379> zadd temp 5 jim 10 tom 15 lili
(integer) 3
127.0.0.1:7379> zrank temp tom
(integer) 1
5,计算成员降序排名 zrevrank
zrevrank key member
排名从0开始
时间复杂度:O(log(n)),n是有序集合的元素个数
举例:
127.0.0.1:7379> zadd temp 5 jim 10 tom 15 lili
(integer) 3
127.0.0.1:7379> zrevrank temp tom
(integer) 1
6,删除元素 zrem
zrem key member1 member2 …
可以一次删除多个member
返回删除成功的元素个数。
时间复杂度:O(k*log(n)),k是要添加的元素个数,n是现在集合中的元素个数。
127.0.0.1:7379> zadd temp 5 jim 10 tom 15 lili
(integer) 3
127.0.0.1:7379> zrem temp tom
(integer) 1
127.0.0.1:7379> zrem temp jim
(integer) 1
7,增加元素分数 zincrby
zincrby key increment member
increment是要增加的分数,可以是负数,负数代表减去分数
返回值是增加之后的分数。
时间复杂度:O(log(n)),n是有序集合的元素个数
127.0.0.1:7379> zadd temp 5 jim
(integer) 1
127.0.0.1:7379> zincrby temp 3 jim
"8"
8,返回升序排名范围内的元素 zrange
zrange key start stop [WITHSCORES]
升序排名从0开始计算
如果使用了WITHSCORES参数,则同时返回元素的分数。
时间复杂度:O(log(n)+k),n是有序集合的元素个数,k是要获取的元素个数。
127.0.0.1:7379> zadd temp 1 a 2 b 3 c 4 d 5 e 6 f
(integer) 6
127.0.0.1:7379> zrange temp 2 4
1) "c"
2) "d"
3) "e"
127.0.0.1:7379> zrange temp 2 4 WITHSCORES
1) "c"
2) "3"
3) "d"
4) "4"
5) "e"
6) "5"
9,返回将序排名范围内的元素 zrevrange
zrevrange key start stop [WITHSCORES]
升序排名从0开始计算
如果使用了WITHSCORES参数,则同时返回元素的分数。
时间复杂度:O(log(n)+k),n是有序集合的元素个数,k是要获取的元素个数。
127.0.0.1:7379> zadd temp 1 a 2 b 3 c 4 d 5 e 6 f
(integer) 6
127.0.0.1:7379> zrevrange temp 2 3
1) "d"
2) "c"
127.0.0.1:7379> zrevrange temp 2 3 WITHSCORES
1) "d"
2) "4"
3) "c"
4) "3"
10,获得指定分数范围内的升序元素 zrangebyscore
zrangebyscore key min max [WITHSCORES] [LIMIT offset count]
WITHSCORES参数和zrange中的参数意义相同。
min和max参数默认是闭区间,在这两个参数前面加上小括号(左括号)可以表示开区间。另外可以用-inf表示无限小,用+inf表示无限大,这可以用在小于某分数或大于某分数的场景。
LIMIT offset count参数代表显示的元素个数上限。offset从0开始计算。count是显示的元素上限。比如:LIMIT 2 3显示的是第3、4、5个元素。
时间复杂度:O(log(n)+k),n是有序集合的元素个数,k是要获取的元素个数。
127.0.0.1:7379> zadd temp 1 a 2 b 3 c 4 d 5 e 6 f
(integer) 6
127.0.0.1:7379> zrangebyscore temp 2 5
1) "b"
2) "c"
3) "d"
4) "e"
127.0.0.1:7379> zrangebyscore temp 2 5 WITHSCORES
1) "b"
2) "2"
3) "c"
4) "3"
5) "d"
6) "4"
7) "e"
8) "5"
127.0.0.1:7379> zrangebyscore temp 2 5 LIMIT 2 3
1) "d"
2) "e"
127.0.0.1:7379> zrangebyscore temp (2 5
1) "c"
2) "d"
3) "e"
127.0.0.1:7379> zrangebyscore temp 2 (5
1) "b"
2) "c"
3) "d"
127.0.0.1:7379> zrangebyscore temp (2 (5
1) "c"
2) "d"
127.0.0.1:7379> zrangebyscore temp 2 +inf
1) "b"
2) "c"
3) "d"
4) "e"
5) "f"
最后一个命令代表查找分数大于等于2的元素。
11,获得指定分数范围内的降序元素 zrevrangebyscore
zrevrangebyscore key min max [WITHSCORES] [LIMIT offset count]
各参数使用规则和zrangebyscore命令相同,区别只是获得的元素是降序排列的。
时间复杂度:O(log(n)+k),n是有序集合的元素个数,k是要获取的元素个数。
12,获得指定分数范围内的元素个数 zcount
zcount key min max
默认是闭区间,min和max参数可以使用左括号代表开区间,可以用-inf表示无限小,用+inf表示无限大。
时间复杂度:O(log(n)),n是有序集合的元素个数。
127.0.0.1:7379> zadd temp 1 a 2 b 3 c 4 d 5 e 6 f
(integer) 6
127.0.0.1:7379> zcount temp 2 4
(integer) 3
127.0.0.1:7379> zcount temp (2 4
(integer) 2
127.0.0.1:7379> zcount temp -inf 4
(integer) 4
13,删除指定排名范围的元素 zremrangebyrank
zremrangebyrank key start stop
默认是闭区间,start和stop参数不能使用左括号代表开区间,不能使用-inf和+inf。
返回删除的元素个数。
时间复杂度:O(log(n)+k),n是有序集合的元素个数,k是要删除的元素个数。
127.0.0.1:7379> zadd temp 1 a 2 b 3 c 4 d 5 e 6 f
(integer) 6
127.0.0.1:7379> zremrangebyrank temp 2 3
(integer) 2
127.0.0.1:7379> zrange temp 0 10
1) "a"
2) "b"
3) "e"
4) "f"
可见删除了元素c和d
14,删除指定分数范围内的元素 zremrangebyscore
zremrangebyscore key min max
默认是闭区间,min和max参数可以使用左括号代表开区间,可以用-inf表示无限小,用+inf表示无限大。
时间复杂度:O(log(n)+k),n是有序集合的元素个数,k是要删除的元素个数。
127.0.0.1:7379> zrange temp 0 -1 WITHSCORES
1) "a"
2) "1"
3) "b"
4) "2"
5) "c"
6) "3"
7) "d"
8) "4"
9) "e"
10) "5"
11) "f"
12) "6"
127.0.0.1:7379> zremrangebyscore temp 2 4
(integer) 3
127.0.0.1:7379> zrange temp 0 -1
1) "a"
2) "e"
3) "f"
127.0.0.1:7379> zremrangebyscore temp (5 6
(integer) 1
127.0.0.1:7379> zrange temp 0 -1
1) "a"
2) "e"
15,获得交集并保存 zinterstore
zinterstore destination numkeys key1 key2 …. [Weights weight1 weight2 …] [AGGREGATE SUM|MIN|MAX]
destination参数就是获得交集后保存的key
numberkeys是个数字,必须和后面要计算交集的key的个数相同,如果不相同则会返回错误。没明白为什么必须要写这么个参数。
[Weights weight1 weight2 …]参数是权重,权重个数必须和key的个数相同,每个元素的分数会分别乘以对应的权重,然后再进行计算,得到元素在最终交集中的分数。
[AGGREGATE SUM|MIN|MAX]参数是最终分数的计算规则,SUM代表加和,相同的元素在不同key中的分数会加起来作为最终交集中的分数,MIN代表取最小值,MAX代表取最大值。这个参数的默认值是SUM。
返回值是新建交集中的元素个数,如果没有交集,新的key将不会创建。
时间复杂度:O(n*k)+O(m*log(m)),n是元素最少的有序集合的元素个数,k是参与计算交集的集合数量,m是最终交集中的元素个数。
没有zinter命令,也就是说有序集合的交集必须保存下来,不知道为什么。
127.0.0.1:7379> zadd temp 1 a 2 b 3 c 4 d 5 e 6 f
(integer) 6
127.0.0.1:7379> zadd temp2 1 a 2 b 3 c
(integer) 3
127.0.0.1:7379> zadd temp3 4 d 5 e 6 f
(integer) 3
127.0.0.1:7379> zinterstore zintertemp 2 temp temp2 temp3
(error) ERR syntax error
127.0.0.1:7379> zinterstore zintertemp 3 temp temp2 temp3
(integer) 0
127.0.0.1:7379> del zintertemp
(integer) 0
可以看到,3个参数求交集,numberkeys写2,会返回错误,numberkeys写3才会返回正确的交集(本例中三个集合没有交集)。
127.0.0.1:7379> zinterstore zintertemp 2 temp temp2
(integer) 3
127.0.0.1:7379> zrange zintertemp 0 -1 WITHSCORES
1) "a"
2) "2"
3) "b"
4) "4"
5) "c"
6) "6"
交集是元素a、b、c,各自的分数是在每个key中的分数加和。
127.0.0.1:7379> zinterstore zintertemp 2 temp temp2 Weights 0.5 2
(integer) 3
127.0.0.1:7379> zrange zintertemp 0 -1 WITHSCORES
1) "a"
2) "2.5"
3) "b"
4) "5"
5) "c"
6) "7.5"
使用了权重,这个命令中第一个key的分数乘以0.5,第二个key的分数乘以2,然后加和,得到最终的分数。
16,获得并集并保存 zunionstore
zunionstore destination numkeys key1 key2 …. [Weights weight1 weight2 …] [AGGREGATE SUM|MIN|MAX]
取得并集命令的参数使用方式和获得交集时相同。
时间复杂度:O(n)+O(m*log(m)),n是所有集合中元素数量总和,m是最终并集中的元素个数。
17,有序集合类型的内部编码
- ziplist:压缩列表。元素个数少于 zset-max-ziplist-entries,且每个元素的大小都小于zset-max-ziplist-value时,使用ziplist。
- skiplist:跳跃表。除ziplist之外的情况使用skiplist,比如元素个数大于 zset-max-ziplist-entries,或者有元素大小大于zset-max-ziplist-value时。
注: zset-max-ziplist-entries和zset-max-ziplist-value都是可配置的, zset-max-ziplist-entries默认128,zset-max-ziplist-value默认64字节。
以上就是Redis中一些常见的命令,不是全部,后续再不断添加。