Redis学习之数据类型及基本操作
前言
在前面一个小节中,我们学习了Redis的安装、客户端的使用等,在这一小节中,将学习Redis的五种数据结构及对应的操作。
在前面我们提到了,Redis是基于键值对的,也就是说,所有的数据类型都必须有一个键与其对应,而这里五种数据结构,指的是对应的值的类型,这一点需要注意一下。
基本操作
Redis中有非常多的命令,有一些命令是用于操作特定数据结构的,而有一些命令则是通用的,我们先来学习一些通用的命令
获取符合规则的键名列表
操作命令:keys PATTERN
PATTERN支持通配符的形式
-
?
匹配一个字符 -
*
匹配任意多个字符 -
[]
匹配括号中间的任意字符 -
\x
匹配字符x,其中x需要进行转移
注意事项:由于keys命令会遍历Redis中所有键,当数量比较大的时候,会影响性能,所以,不建议在生成环境中使用
判断一个键是否存在
操作命令:exists KEY
,如果存在则返回1,否则返回0
删除键
操作命令:del KEY
,返回删除的键的个数
获取键值的类型
操作命令:type KEY
,返回类型:string、hash、list、set、zset
字符串类型
字符串类型是Redis中最基本的数据类型,能存储任意形式的字符串,包括二进制数据,可以用于存储用户的邮箱,JSON化的数据,甚至是一张图片,一个字符串类型键允许存储的数据的最大容量是512MB
基本命令
赋值与取值
命令:set KEY VALUE
、get KEY
127.0.0.1:6379> set name xavier
OK
127.0.0.1:6379> get name
"xavier"
递增数字
命令:incr KEY
注意
- 该命令只能用于值是数字类型的,如果是字符串等,会报错(很合理嘛)
- incr命令在内的所有Redis命令都是原子操作,所以不用担心会出现竞态条件
127.0.0.1:6379> set age 22
OK
127.0.0.1:6379> incr age
(integer) 23
127.0.0.1:6379> get age
"23"
127.0.0.1:6379> incr age
(integer) 24
增加指定的整数
命令:incr KEY INCREMENT
,INCRMENT指定要增加的数值
127.0.0.1:6379> incrby year 2018
(integer) 2018
127.0.0.1:6379> get year
"2018"
减少指定的整数
命令:decr KEY
,减一
命令:decrby KEY DECREMENT
,减少DECREMENT
127.0.0.1:6379> get year
"2018"
127.0.0.1:6379> decr year
(integer) 2017
127.0.0.1:6379> decrby year 10
(integer) 2007
增加指定浮点数
命令:incrbyfloat KEY INCREMENT
27.0.0.1:6379> incrbyfloat num 3.2
"3.2"
127.0.0.1:6379> get num
"3.2"
向尾部追加值
命令:append KEY VALUE
127.0.0.1:6379> append year years
(integer) 9
127.0.0.1:6379> get year
"2018years"
获取字符串长度
命令:strlen KEY
127.0.0.1:6379> get year
"2018years"
127.0.0.1:6379> strlen year
(integer) 9
同时设置/获取多个键值
命令:mget KEY [KEY1 KEY2 ...]
命令:mset KEY VALUE [KEY1 VALUE1 KEY2 VALUE2 ...]
127.0.0.1:6379> mset name xavier age 23 school szu
OK
127.0.0.1:6379> mget name age school
1) "xavier"
2) "23"
3) "szu"
散列类型
散列类型,也就是hash,是一种键值对,存储了字段和字段值的映射,但是字段值只能放字符串类型,不能存放其他类型,也就是hash类型不支持嵌套
举Java中的Map
作为例子,此时的名字就是Map
结构的名字,而对应的字段就是Map
中的key,对应的字段值就是Map
中的value
基本操作
赋值与取值
命令:hset KEY FILED VALUE
命令:hget KEY FILED
127.0.0.1:6379> hset stu name xavier
(integer) 0
127.0.0.1:6379> hget stu name
"xavier"
命令:hmset KEY FIELD VALUE [FIELD1 VALUE1 FIELD2 VALUE2 ...]
命令:hmget KEY FIELD [FIELD1 FIELD2 ...]
127.0.0.1:6379> hmset stu name xavier age 23 school szu
OK
127.0.0.1:6379> hmget stu name age school
1) "xavier"
2) "23"
3) "szu"
命令:hgetall KEY
,获取hash结构的所有字段及其值
127.0.0.1:6379> hgetall stu
1) "name"
2) "xavier"
3) "age"
4) "23"
5) "school"
6) "szu"
注意跟mset
命令的区别,mset的是设置多个键,hmset
设置的一个键的多个字段
判断字段是否存在
命令:hexists KEY FIELD
127.0.0.1:6379> hexists stu hello
(integer) 0
127.0.0.1:6379> hexists stu name
(integer) 1
字段不存在时赋值
命令:hsetnx KEY FIElD VALUE
127.0.0.1:6379> hsetnx stu name xavier
(integer) 0
127.0.0.1:6379> hsetnx stu country china
(integer) 1
127.0.0.1:6379> hgetall stu
1) "name"
2) "xavier"
3) "age"
4) "23"
5) "school"
6) "szu"
7) "country"
8) "china"
增加数字
命令:hincryby KEY FIElD INCREMENT
,注意,字段不存在时会新增并且赋值
127.0.0.1:6379> hincrby stu age 1
(integer) 24
删除字段
命令:hdel KEY FIELD [FIELD1 FIELD2]
127.0.0.1:6379> hdel stu work_year
(integer) 1
只获取字段名或字段值
命令:hkeys KEY
命令:hvals KEY
127.0.0.1:6379> hkeys stu
1) "name"
2) "age"
3) "school"
4) "country"
127.0.0.1:6379> hvals stu
1) "xavier"
2) "24"
3) "szu"
4) "china"
获取字段数量
命令:hlen KEY
127.0.0.1:6379> hlen stu
(integer) 4
列表类型
列表类型,list,可以存储一个有序的字符串列表,Redis中使用的列表是双向链表,可以从链表两端操作数据
基本操作
向列表两端增加数据
命令:lpush KEY VALUE [VALUE1 VALUE2 ...]
命令:rpush KEY VALUE [VALUE1 VALUE2 ...]
127.0.0.1:6379> lpush page 1 2 3 5
(integer) 4
127.0.0.1:6379> rpush page 9 8 7
(integer) 7
# 此时列表内容为 5 3 2 1 9 8 7
从列表两端弹出元素
命令:lpop KEY
命令:rpop KEY
127.0.0.1:6379> lpop page
"5"
127.0.0.1:6379> rpop page
"7"
# 此时列表内容为 3 2 1 9 8
获取列表中元素的个数
命令:llen KEY
127.0.0.1:6379> llen page
(integer) 5
获取列表片段
命令:lrange KEY START END
注意
- START、END表示的是起始位置到结束位置(从0开始计数,包含两端)
- 如果START大于END,则返回空列表
- 负数表示从右边开始,如 -1表示最后的位置
- 如果END大于实际的位置,只返回到最右边的位置(不会超出)
127.0.0.1:6379> lrange page 0 2
1) "3"
2) "2"
3) "1"
127.0.0.1:6379> lrange page 0 -1
1) "3"
2) "2"
3) "1"
4) "9"
5) "8"
127.0.0.1:6379> lrange page 100 1
(empty list or set)
127.0.0.1:6379> lrange page 0 100
1) "3"
2) "2"
3) "1"
4) "9"
5) "8"
删除列表中指定的值
命令:lrem KEY COUNT VALUE
,删除列表中前COUNT个值为VALUE的元素,返回实际删除的个数
注意
- 如果COUNT > 0 时,会从列表左边开始删除前COUNT个值为VALUE的元素
- 如果COUNT < 0 时,从列表右边开始删除前COUNT个值为VALUE的元素
- 如果COUNT = 0 时,会删除所有值为VALUE的元素
127.0.0.1:6379> lrange numbers 0 -1
1) "2"
2) "0"
3) "1"
4) "2"
5) "2"
6) "3"
7) "2"
127.0.0.1:6379> lrem numbers -1 2
(integer) 1
127.0.0.1:6379> lrange numbers 0 -1
1) "2"
2) "0"
3) "1"
4) "2"
5) "2"
6) "3"
127.0.0.1:6379> lrem numbers 1 2
(integer) 1
127.0.0.1:6379> lrange numbers 0 -1
1) "0"
2) "1"
3) "2"
4) "2"
5) "3"
127.0.0.1:6379> lrem numbers 0 2
(integer) 2
127.0.0.1:6379> lrange numbers 0 -1
1) "0"
2) "1"
3) "3"
获取/设置指定索引的元素值
命令:lindex KEY INDEX
命令:lset KEY INDEX VALUE
127.0.0.1:6379> lindex numbers 0
"0"
127.0.0.1:6379> lset numbers 0 100
OK
127.0.0.1:6379> lrange numbers 0 -1
1) "100"
2) "1"
3) "3"
只保留列表指定片段
命令:ltrim KEY START END
127.0.0.1:6379> ltrim numbers 0 1
OK
127.0.0.1:6379> lrange numbers 0 -1
1) "100"
2) "1"
向列表中插入元素
命令:linsert KEY BEFORE|AFTER VAL VALUE
,在列表中VAL的前/后插入值为VALUE的元素
127.0.0.1:6379> linsert numbers before 100 200
(integer) 3
127.0.0.1:6379> lrange numbers 0 -1
1) "200"
2) "100"
3) "1"
127.0.0.1:6379> linsert numbers after 100 300
(integer) 4
127.0.0.1:6379> lrange numbers 0 -1
1) "200"
2) "100"
3) "300"
4) "1"
将元素从一个列表转到另一个列表
命令:rpoplpush SOURCE DEST
,执行一次,传输一个元素,不是整个列表
127.0.0.1:6379> rpoplpush numbers list_
"1"
127.0.0.1:6379> lrange list_ 0 -1
1) "1"
127.0.0.1:6379> rpoplpush numbers list_
"300"
127.0.0.1:6379> rpoplpush numbers list_
"100"
127.0.0.1:6379> rpoplpush numbers list_
"200"
集合类型
集合中的元素是无序的,并且不存在重复元素,Redis中使用值为空的hash table实现的
基本操作
增加/删除元素
命令:sadd KEY VALUE [VALUE1 VALUE2 ...]
命令:srem KEY VALUE [VALUE1 VALUE2 ...]
127.0.0.1:6379> sadd letters a b c a b c
(integer) 3 # 实际上值增加了三个元素,不是六个
127.0.0.1:6379> srem letters a b d
(integer) 2 # d不存在,也就不存在所谓的删除了
获取集合中的所有元素
命令:smembers KEY
127.0.0.1:6379> smembers letters
1) "c"
判断元素是否在集合中
命令:sismember KEY VALUE
,1表示存在,0表示不存在
127.0.0.1:6379> sismember letters c
(integer) 1
127.0.0.1:6379> sismember letters e
(integer) 0
集合间运算
命令:sdiff KEY [KEY1 KEY2 ...]
,差集,从KEY集合中去掉其他
命令:sinter KEY [KEY1 KEY2 ...]
,交集,KEY集合与其他集合的交集
命令:sunion KEY [KEY1 KEY2 ...]
,并集,KEY集合与其他集合的并集
127.0.0.1:6379> sadd setA 1 2 3
(integer) 3
127.0.0.1:6379> sadd setB 2 3 4
(integer) 3
127.0.0.1:6379> sdiff setA setB
1) "1"
127.0.0.1:6379> sdiff setB setA
1) "4"
127.0.0.1:6379> sinter setA setB
1) "2"
2) "3"
127.0.0.1:6379> sunion setA setB
1) "1"
2) "2"
3) "3"
4) "4"
获取集合中元素的个数
命令:scard KEY
127.0.0.1:6379> scard setA
(integer) 3
进行集合运算并将结果存储
命令:sdiffstore DEST KEY1 [KEY2 ...]
命令:sinterstore DEST KEY1 [KEY2 ...]
命令:sunionstore DEST KEY1 [KEY2 ...]
从集合中弹出一个元素
命令:spop KEY
,随机弹出
127.0.0.1:6379> spop setA
"2"
有序集合
与集合类似,但是具有排序的能力,在集合的基础上,为每个元素关联一个分数,然后根据分数进行排序
基本操作
增加元素
命令:zadd KEY SCORE VALUE [SCORE1 VALUE1 SCORE2 VALUE2 ...]
,如果元素存在,则用新的分数替换原来的分数,分数可以是整数,也可以是双精度浮点数(+inf表示正无穷、-inf表示负无穷)
127.0.0.1:6379> zadd scoreboard 89 tom 67 peter 100 david
(integer) 3
127.0.0.1:6379> zadd scoreboard 76 peter
(integer) 0
获取元素分数
命令:zscore KEY VALUE
127.0.0.1:6379> zscore scoreboard peter
"76"
获取排名在某个范围的元素列表
命令:zrange KEY START STOP [WITHSCORES]
,START、END指的是索引,不是分数值,WITHSCORES表示将分数也显示出来,如果分数相同,则字段按照字典序排序,下同,分数从小到大
命令:zrevrange KEY START STOP [WITHSCORES]
,逆序
127.0.0.1:6379> zrange scoreboard 0 1 WITHSCORES
1) "peter"
2) "76"
3) "tom"
4) "89"
127.0.0.1:6379> zrevrange scoreboard 0 1 WITHSCORES
1) "david"
2) "100"
3) "tom"
4) "89"
127.0.0.1:6379> zrevrange scoreboard 0 1
1) "david"
2) "tom"
获得指定分数范围的元素
命令:zrangebyscore KEY MIN MAX [WITHSCORE] [LIMIT OFFSET COUNT]
,默认包含端点,如果不希望包含端点,在分数前面加上(
,如(80
,OFFSET、COUNT用法同SQL,用于指定偏移位置以及元素个数
命令:zrevrangebyscore
,原理同上,注意,MIN和MAX的位置也是相反的
127.0.0.1:6379> zrangebyscore scoreboard 80 100 WITHSCORES
1) "tom"
2) "89"
3) "david"
4) "100"
127.0.0.1:6379> zrangebyscore scoreboard 80 (100 WITHSCORES
1) "tom"
2) "89
增加某个元素的分数
命令:zincrby KEY INCREMENT VALUE
127.0.0.1:6379> zincrby scoreboard 3 peter
"79"
获取集合中元素个数
命令:zcard KEY
获取指定分数范围内元素的个数
命令:zcount KEY MIN MAX
127.0.0.1:6379> zcount scoreboard 80 100
(integer) 2
删除一个或者多个元素
命令:zrem KEY MEMBER [MEMBER1 MEMBER2 ...]
,返回成功删除元素个数
127.0.0.1:6379> zrange scoreboard 0 -1
1) "peter"
2) "tom"
3) "david"
127.0.0.1:6379> zrem scoreboard tom
(integer) 1
127.0.0.1:6379> zrange scoreboard 0 -1
1) "peter"
2) "david"
按照排名范围删除元素
命令:zremrangebyrank KEY START END
127.0.0.1:6379> zrange scoreboard 0 -1
1) "peter"
2) "david"
127.0.0.1:6379> zremrangebyrank scoreboard 0 1
(integer) 2
127.0.0.1:6379> zrange scoreboard 0 -1
(empty list or set)
按照分数范围删除元素
命令:zremrangebyscore KEY MIN MAX
获取元素排名
命令:zrank KEY MEMBER
,排名从0开始,默认是根据分数从小到大
127.0.0.1:6379> zadd scoreboard 1 a 2 b 3 c
(integer) 3
127.0.0.1:6379> zrange scoreboard 0 -1
1) "a"
2) "b"
3) "c"
127.0.0.1:6379> zrank scoreboard a
(integer) 0
127.0.0.1:6379> zrank scoreboard b
(integer) 1
计算有序集合的交集
命令:zinterstore DEST NUM_KEYS KEY [KEY ...] [weight WEIGHT [WEIGHT ...] [aggregate SUM|MIN|MAX]]
注意,DEST中元素分数是由aggrate参数决定的
- SUM,也是默认值时,DEST中元素的分数是每个参与运算的集合中该元素的分数和
- MIN,表示采用最小值
- MAX,表示采用最大值
可以通过weight参数设置每个集合的权重,每个集合在参与计算时元素的分数乘上该权重
127.0.0.1:6379> zadd sortedSet1 1 a 2 b
(integer) 2
127.0.0.1:6379> zadd sortedSet2 10 a 20 b
(integer) 2
127.0.0.1:6379> zinterstore sortedSetsResult 2 sortedSet1 sortedSet2
(integer) 2
127.0.0.1:6379> zrange sortedSetsResult 0 -1 withscores
1) "a"
2) "11"
3) "b"
4) "22"
# min/max基本同上,不演示
127.0.0.1:6379> zinterstore sortedSetsResult 2 sortedSet1 sortedSet2 weights 20 2
(integer) 2
127.0.0.1:6379> zrange sortedSetsResult 0 -1 withscores
1) "a"
2) "40"
3) "b"
4) "80"
zunionstore命令的用法与zinterstore类似
总结
本小节主要学习了Redis的五种数据类型,string、hash、list、set、zset,在Redis中,每个不同的数据类型有不同的用法,适用于不同的场景,在使用的时候需要灵活使用,选择最合适的数据结构