Redis是REmote DIctionary Server(远程字典服务器)的缩写,它以字典结构存储数据。现在我们来学习它的五种键值数据类型。学习之前先来了解几个基础命令。
先开启Redis服务:
$ redis-server
接着开启Redis客户端:
$ redis-cli
获取所有键:
127.0.0.1:6379> KEYS *
Redis不区分大小写
判断一个键是否存在,1 表示存在,0 表示不存在:
127.0.0.1:6379> EXISTS key
删除键,可以删除一个或多个键,返回值是删除键的个数:
127.0.0.1:6379> DEL key1 key2 key3
获取键的类型:
127.0.0.1:6379> TYPE key
字符串类型
它能存储任何类型的字符串,包括二进制数据。一个字符串类型键允许存储的数据的最大容量是512MB。
赋值与取值
当键不存在时,会返回空结果
127.0.0.1:6379> set key hello
OK
127.0.0.1:6379> get key
"hello"
127.0.0.1:6379> get name
(nil)
递增数字
当要操作的键不存在时会默认键值为0,所以第一次递增后的结果是1,当键值不是整数时 Redis会提示错误:
127.0.0.1:6379> set age 23
OK
127.0.0.1:6379> incr age
(integer) 24
127.0.0.1:6379> incr num
(integer) 1
127.0.0.1:6379> incr num
(integer) 2
127.0.0.1:6379> set foo lorem
OK
127.0.0.1:6379> incr foo
(error) ERR value is not an integer or out of range
增加指定的整数
127.0.0.1:6379> incrby age 10
(integer) 34
减少指定的整数
127.0.0.1:6379> decr age
(integer) 33
127.0.0.1:6379> decrby age 6
(integer) 27
增加指定浮点数
127.0.0.1:6379> incrbyfloat score 2.7
"2.7"
127.0.0.1:6379> incrbyfloat score 5E+4
"50002.69999999999999929"
向尾部增加值
APPEND作用是向键值的末尾追加value。如果键不存在则将该键的值设置为value,返回值是追加后字符串的总长度。
127.0.0.1:6379> append name 'jenkin'
(integer) 6
127.0.0.1:6379> append name ' wang'
(integer) 11
127.0.0.1:6379> get name
"jenkin wang"
获取字符串长度
STRLEN命令返回键值的长度,如果键不存在则返回0。UTF-8编码的每个中文汉字的长度都是3,本例中则会返回 6.
127.0.0.1:6379> strlen name
(integer) 11
127.0.0.1:6379> strlen ping
(integer) 0
127.0.0.1:6379> set key 你好
OK
127.0.0.1:6379> strlen key
(integer) 6
同时获得/设置多个键值
127.0.0.1:6379> mset name 'jenkin' age 24 email 'mark94@live.cn'
OK
127.0.0.1:6379> mget name age email
1) "jenkin"
2) "24"
3) "mark94@live.cn"
位操作
GETBIT key offset:获得一个字符串类型键指定位置的二进制位的值(0或1),索引从0开始,如果获取的二进制位的索引超出了键值的二进制实际长度,则默认位值是0
SETBIT key offset value:设置字符串类型建指定位值的二进制位的值,返回的是该位置的旧值
BITCOUNT key [start] [end]:获得字符串类型键中值是1的二进制位个数,可通过参数来限制统计的字节范围
BITOP operation destkey key [key ...]:可以对多个字符串类型键进行位运算,并将结果存储在destkey参数指定的键中,BITOP支持的运算操作有 AND、OR、XOR、NOT
b a r
ASCII 98 97 114
二进制 01100010 01100001 01110010
a a r
ASCII 98 97 114
二进制 01100001 01100001 01110010
127.0.0.1:6379> set foo bar
OK
127.0.0.1:6379> getbit foo 0
(integer) 0
127.0.0.1:6379> getbit foo 6
(integer) 1
127.0.0.1:6379> getbit foo 1000
(integer) 0
127.0.0.1:6379> setbit foo 2 0
(integer) 1
127.0.0.1:6379> get foo
"Bar"
如果要设置的位置超过了键值的二进制位的长度,SETBIT会自动将中间的二进制位设置为0,同理设置一个不存在的键的指定二进制位的值会自动将其前面的位赋值为0
127.0.0.1:6379> bitcount foo
(integer) 10
127.0.0.1:6379> bitcount foo 0 1
(integer) 6
127.0.0.1:6379> bitcount foo 1 2
(integer) 7
127.0.0.1:6379> set foo1 bar
OK
127.0.0.1:6379> set foo2 aar
OK
127.0.0.1:6379> bitop or dest foo1 foo2
(integer) 3
127.0.0.1:6379> get dest
"car"
散列类型
散列类型的键值也是一种字典结构,其存储了字段和字段值的映射,但字段值只能是字符串,不支持其他数据类型。散列类型不能嵌套其它的数据类型。一个散列类型键可以包含至多2^32-1个字段。
除了散列类型,Redis的其他数据类型同样不支持数据类型嵌套,比如集合类型的每个元素都只能是字符串,不能是另一个集合或散列表等
赋值与取值
HSET key field value:不区分插入和更新操作,当执行的是插入操作时(即之前字段不存在)HSET命令会返回1,当执行的是更新操作时(即之前字段已经存在)HSET命令会返回0.当键本身不存在时,HSET命令还会自动创建它。
HGET key field:
HMSET key field value [field value ...]:同时设置多个字段的值
HMGET key field [field ...]:
HGETALL key: 获取键中所有的字段和字段值。很多语言的Redis客户端会将HGETALL的返回结果封装成编程语言中的对象。
127.0.0.1:6379> hset car price 500
(integer) 1
127.0.0.1:6379> hset car name BMW
(integer) 1
127.0.0.1:6379> hget car name
"BMW"
127.0.0.1:6379> hmset student name jenkin age 24 score 100
OK
127.0.0.1:6379> hmget student name age score
1) "jenkin"
2) "24"
3) "100"
127.0.0.1:6379> hgetall student
1) "name"
2) "jenkin"
3) "age"
4) "24"
5) "score"
6) "100"
判断字段是否存在
HEXISTS key field:如果存在则返回1,否则返回0(如果键不存在也会返回0)。
127.0.0.1:6379> hexists car price
(integer) 1
127.0.0.1>6379> hexists car brand
(integer) 0
当字段不存在时赋值
HSETNX key field value:如果字段已经存在,HSETNX命令将不执行任何操作。HSETNX命令是原子操作,不用担心竞态条件。
127.0.0.1:6379> hgetall car
1) "price"
2) "500"
3) "name"
4) "BMW"
127.0.0.1:6379> hsetnx car price 1000
(integer) 0
127.0.0.1:6379> hget car price
"500"
127.0.0.1:6379> hsetnx car place China
(integer) 1
127.0.0.1:6379> hgetall car
1) "price"
2) "500"
3) "name"
4) "BMW"
5) "place"
6) "China"
增加数字
HINCRBY key field increment:返回值是增值后的字段值。如果该键不存在,会自动增加该键。散列类型没有HINCR命令.
127.0.0.1:6379> hincrby car price 200
(integer) 700
删除字段
HDEL key field [field ...]:可以删除一个或多个字段,返回值是被删除的字段个数。
127.0.0.1:6379> hdel car price
(integer) 1
127.0.0.1:6379> hdel car price
(integer) 0
只获取字段名或字段值
127.0.0.1:6379> hkeys car
1) "name"
2) "place"
127.0.0.1:6379> hvals car
1) "BMW"
2) "China"
获取字段数量
127.0.0.1:6379> hlen car
(integer) 2
列表类型
列表类型可以存储一个有序的字符串列表,常用的操作是向列表两端添加元素或者获得列表的某一个片段。列表类型内部是使用双向链表实现的,向列表两端添加元素的时间复杂度为O(1),获取越接近两端的元素越快。一个列表类型键最多能容纳2^32-1个元素。
向列表两端增加元素
LPUSH key value [value …]:向列表左边增加元素,返回值表示增加元素后列表的长度。
RPUSH key value [value …]:向列表右边增加元素,返回值表示增加元素后列表的长度。
127.0.0.1:6379> lpush numbers 1
(integer) 1
127.0.0.1:6379> lpush numbers 2 3
(integer) 4
127.0.0.1:6379> rpush numbers 7 8 9
(integer) 7
向列表两端弹出元素
LPOP key:从列表左边弹出一个元素(将列表左边的元素从列表中移除,并返回被移除的元素值)
RPOP key:从列表右边弹出一个元素(将列表右边的元素从列表中移除,并返回被移除的元素值)
127.0.0.1:6379> lpop numbers
"4"
127.0.0.1:6379> rpop numbers
"9"
获取列表中元素的个数
127.0.0.1:6279> llen numbers
(integer) 5
LLEN命令的功能类似SQL语句 SELELCT COUNT(*) FROM table_name,但LLEN的时间复杂度为O(1)。
获得列表片段
LRANGE key start stop
127.0.0.1:6379> lrange numbers 0 3
1) "3"
2) "2"
3) "1"
4) "7"
127.0.0.1:6379> lrange numbers -2 -1
1) "7"
2) "8"
127.0.0.1:6379> lrange numbers 9 10
(empty list or set)
127.0.0.1:6379> lrange numbers 1 999
1) "2"
2) "1"
3) "7"
4) "8"
如果start的索引位置比stop的索引位置靠后,则会返回空列表;
如果stop大于实际的索引范围,则会返回到列表左右边的元素。
删除列表中指定的值
LREM key count value:删除列表中前count个值为value的元素,返回值是实际删除的元素。
1.当count > 0 时,LREM命令会从列表左边开始删除前count个值为value的元素;
2.当count < 0 时,LREM命令会从列表右边开始删除前|count|个值为value的元素;
3.当count = 0 时,LREM命令会删除所有值为value的元素。
127.0.0.1:6379> lrange numbers 0 -1
1) "3"
2) "2"
3) "1"
4) "7"
5) "8"
127.0.0.1:6379> lrem numbers 3 1
(integer) 1
127.0.0.1:6379> lrem numbers -1 8
(integer) 1
获得/设置指定索引的元素值
LINDEX key index:返回指定索引的元素,索引从0开始,如果index是负数表示从右边开始计算的索引,最右边元素索引是-1。
LSET key index value:将索引为index的元素赋值为value。
127.0.0.1:6379> lrange numbers 0 -1
1) "5"
2) "6"
3) "7"
4) "8"
5) "9"
6) "7"
127.0.0.1:6379> lindex numbers 5
"7"
127.0.0.1:6379> lindex numbers -1
"7"
127.0.0.1:6379> lset numbers -1 10
OK
127.0.0.1:6379> lindex numbers -1
"10"
只保留列表指定片段
LTRIM key start end:删除指定索引范围之外的所有元素。
127.0.0.1:6379> lrange numbers 0 -1
1) "10"
2) "6"
3) "7"
4) "8"
5) "9"
6) "10"
127.0.0.1:6379> ltrim numbers 1 4
OK
127.0.0.1:6379> lrange numbers 0 -1
1) "6"
2) "7"
3) "8"
4) "9"
向列表中插入元素
LINSERT key BEFORE|AFTER pivot value:先在列表中从左到右查找值为pivot的元素,然后根据第二个参数是before还是after来决定将value插入到该元素的前面还是后面。返回值是插入后列表的元素个数。
127.0.0.1:6379> lrange numbers 0 -1
1) "8"
2) "6"
3) "7"
4) "8"
5) "9"
127.0.0.1:6379> linsert numbers after 8 -2
(integer) 6
127.0.0.1:6379> lrange numbers 0 -1
1) "8"
2) "-2"
3) "6"
4) "7"
5) "8"
6) "9"
将元素从一个列表转移到另一个列表
RPOPLPUSH source destination:先执行RPOP命令再执行LPUSH命令。RPOPLPUSH命令会先从source列表类型键的右边弹出一个元素,然后将其加入到destination列表类型键的左边,并返回这个元素的值,整个过程是原子的。
127.0.0.1:6379> rpoplpush numbers new_numbers
"9"
集合类型
集合类型在Redis内部是使用值为空的散列表(hash table)实现的,所以这些操作的时间复杂度都是O(1)。在集合中的每个元素都是不同的,且没有顺序。一个集合类型(Set)键可以存储至多2^32-1个字符串。
增加/删除元素
SADD key member [member …]:向集合增加一个或多个元素,如果键不存在则会自动创建。
SREM key member [member …]:从集合中删除一个或多个元素,并返回删除成功的个数。
127.0.0.1:6379> sadd letters a
(integer) 1
127.0.0.1:6379> sadd letters a b c
(integer) 2
127.0.0.1:6379> srem letters c d
(integer) 1
获得集合中的所有元素
SMEMBERS key:返回集合中的所有元素。
127.0.0.1:6379> smembers letters
1) "b"
2) "a"
判断元素是否在集合中
SISMEMEBER key member:判断一个元素是否在集合中,时间复杂度是O(1)。当值存在时返回1,当值不存在或键不存在时返回0.
127.0.0.1:6379> sismember letters b
(integer) 1
127.0.0.1:6379> sismember letters f
(integer) 0
127.0.0.1:6379> sismember letter b
(integer) 0
集合间运算
SDIFF key [key …]:对多个集合进行差集运算
SINTER key [key ...]:对多个集合执行交集运算
SUNION KEY [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> sadd setC 2 3
(integer) 2
127.0.0.1:6379> sdiff setA setB setC
1) "1"
127.0.0.1:6379> sinter setA setB
1) "2"
2) "3"
127.0.0.1:6379> sinter setA setB setC
1) "2"
2) "3"
127.0.0.1:6379> sunion setA setB
1) "1"
2) "2"
3) "3"
4) "4"
127.0.0.1:6379> sunion setA setB setC
1) "1"
2) "2"
3) "3"
4) "4"
获取元素中集合个数
SCARD key:获取集合中的元素个数。
127.0.0.1:6379> smembers letters
1) "c"
2) "b"
3) "a"
127.0.0.1:6379> scard letters
(integer) 3
进行集合运算并将结果存储
SDIFFFSTORE destination key [key ...]:
SINTERSTORE destination key [key ...]:
SUNIONSTORE destination key [key ...]:
127.0.0.1:6379> sdiffstore setAB setA setB
(integer) 1
127.0.0.1:6379> smembers setAB
1) "1"
127.0.0.1:6379> sinterstore setAinB setA setB
(integer) 2
127.0.0.1:6379> smembers setAinB
1) "2"
2) "3"
127.0.0.1:6379> sunionstore setAandB setA setB
(integer) 4
127.0.0.1:6379> smembers setAandB
1) "1"
2) "2"
3) "3"
4) "4"
随机获取集合中的元素
SRANDMEMBER key [count]:随机从集合中获取一个元素
1.当count为正数时,SRANDMEMBER 会随机从集合里获得count个不重复的元素。如果count的值大于集合中的元素个数,则返回全部元素。
2.当count为负数时,SRANDMEMBER会随机从集合里获得|count|个的元素,这些元素有可能相同。
127.0.0.1:6379> srandmember letters
"a"
127.0.0.1:6379> srandmember letters 2
1) "a"
2) "b"
127.0.0.1:6379> srandmember letters -2
1) "a"
2) "a"
127.0.0.1:6379>
从集合中弹出一个元素
SPOP key:从集合中随机选择一个元素弹出。
127.0.0.1:6379> spop letters
"c"
有序集合类型
在集合类型的基础上有序集合类型为集合中的每一个元素都关联了一个分数。有序集合类型是使用散列表和跳跃表
实现的,时间复杂度为O(log(n))。有序集合比列表类型更耗费内存。
增加元素
ZADD key score member [score member ...] :向有序集合中加入一个元素和该元素的分数,如果该元素已经存在则会用新的分数替换原有的分数。返回值是新加入到集合中的元素个数(不包含之前已经存在的元素)。分数不仅可以是整数,还可以是双精度浮点数。
127.0.0.1:6379> zadd scoreboard 89 Tom 67 Peter 100 Jenkin
(integer) 3
127.0.0.1:6379> zadd scoreboard 76 Peter
(integer) 0
127.0.0.1:6379> zadd testboard +inf c
(integer) 1
127.0.0.1:6379> zadd testboard -inf d
(integer) 1
+inf 表示正无穷,-inf表示负无穷。
获得元素的分数
ZSCORE key member:
127.0.0.1:6379> zscore scoreboard Jenkin
"100"
获取排名在某个范围的元素列表
ZRANGE key start stop [WITHSCORES]:按照元素分数从小到大的顺序返回索引从start到stop之间的所有元素(包含两端的元素)。时间复杂度为O(log n+m) (其中n为有序集合的基数,m为返回的元素个数)。如果两个元素的分数相同则会按照字典顺序(0<9<A<Z<a<z)进行排序。ZRANGE与LRANGE命令十分相似。
ZREVRANGE key start stop [WITHSCORES]:按照元素分数从大到小的顺序给出结果。
127.0.0.1:6379> zrange scoreboard 0 2
1) "Peter"
2) "Tom"
3) "Jenkin"
127.0.0.1:6379> zrange scoreboard 1 -1
1) "Tom"
2) "Jenkin"
127.0.0.1:6379> zrange scoreboard 0 -1 withscores
1) "Peter"
2) "76"
3) "Tom"
4) "89"
5) "Jenkin"
6) "100"
127.0.0.1:6379> zrevrange scoreboard 0 -1 withscores
1) "Jenkin"
2) "100"
3) "Tom"
4) "89"
5) "Peter"
6) "76"
获得指定分数范围的元素
ZRANGEBYSCORE key min max [WITHSCORES][LIMIT offset count]:按照元素分数从小到大的顺序返回分数在min和max之间的元素。LIMIT offset count与SQL中的用法基本相同,即在获得的元素列表的基础上向后偏移offset个元素,并且只获取前count个元素。
27.0.0.1:6379> zrange scoreboard 0 -1 withscores
1) "Jerry"
2) "56"
3) "Danny"
4) "67"
5) "Peter"
6) "76"
7) "Tom"
8) "89"
9) "Wenddy"
10) "92"
11) "Jenkin"
12) "100"
127.0.0.1:6379> zrangebyscore scoreboard 80 100
1) "Tom"
2) "Wenddy"
3) "Jenkin"
127.0.0.1:6379> zrangebyscore scoreboard 80 (100
1) "Tom"
2) "Wenddy"
127.0.0.1:6379> zrangebyscore scoreboard (80 +inf
1) "Tom"
2) "Wenddy"
3) "Jenkin"
127.0.0.1:6379> zrangebyscore scoreboard 60 +inf limit 1 3
1) "Peter"
2) "Tom"
3) "Wenddy"
127.0.0.1:6379> zrevrangebyscore scoreboard 100 0 limit 0 3
1) "Jenkin"
2) "Wenddy"
3) "Tom"
增加某个元素的分数
ZINCRBY key increment member:增加一个元素的分数,返回值是更改后的分数。如果指定的元素不存在,Redis在执行命令前会先建立它并将它的分数赋为0再执行操作。
127.0.0.1:6379> zincrby scoreboard 100 Jenkin
"200"
127.0.0.1:6379> zincrby scoreboard -100 Jenkin
"100"
获取集合中元素的数量
ZCARD key
127.0.0.1:6379> zcard scoreboard
(integer) 6
获得指定分数范围内的元素个数
ZCOUNT key min max
127.0.0.1:6379> zcount scoreboard 80 100
(integer) 3
127.0.0.1:6379> zcount scoreboard 80 (100
(integer) 2
删除一个或多个元素
ZREM key member [member ...]:命令返回值是成功删除的元素数量(不包含本来就不存在的元素)。
127.0.0.1:6379> zrem scoreboard Wenddy
(integer) 1
127.0.0.1:6379> zcard scoreboard
(integer) 5
按照排名范围删除元素
ZREMRANGEBYRANK key start stop:按照元素分数从小到大的顺序删除处在指定排名范围内的所有元素,并返回删除的元素数量。
127.0.0.1:6379> zadd testRem 1 a 2 b 3 c 4 d 5 e 6 f
(integer) 6
127.0.0.1:6379> zremrangebyrank testRem 0 2
(integer) 3
127.0.0.1:6379> zrange testRem 0 -1
1) "d"
2) "e"
3) "f"
按照分数范围删除元素
ZREMRANGEBYSCORE key min max:删除指定范围内的所有元素。
127.0.0.1:6379> zremrangebyscore testRem (4 5
(integer) 1
127.0.0.1:6379> zrange testRem 0 -1
1) "d"
2) "f"
获得元素的排名
ZRANK key member:按照元素分数从下到大的顺序获得指定的元素排名
ZREVRANK member:分数最大的元素排名为0.
127.0.0.1:6379> zrange scoreboard 0 -1 withscores
1) "Jerry"
2) "56"
3) "Danny"
4) "67"
5) "Peter"
6) "76"
7) "Tom"
8) "89"
9) "Jenkin"
10) "100"
127.0.0.1:6379> zrank scoreboard Jenkin
(integer) 4
127.0.0.1:6379> zrevrank scoreboard Jenkin
(integer) 0
计算有序集合的交集
ZINTERSTORE destination numkeys key [key ...][WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]:计算多个有序集合的交集并将结果存储在destination键中,返回值为destination键中的元素个数。destination键中元素的分数是由AGGREGATE参数决定的。
1.当AGGREGATE是SUM时(也就是默认值),destination键中元素的分数是每一个参与计算的集合中该元素分数的和。
2.当AGGREGATE是MIN时,destination键中元素的分数是每一个参与计算的集合中该元素分数的最小值。
3.当AGGREGATE是MAX时,destination键中元素的分数是每一个参与计算的集合中该元素分数的最大值。
ZINTERSTORE还能够通过WEIGHTS参数设置每个集合的权重,每个集合在参与计算时元素的分数会被乘上该集合 的权重。
127.0.0.1:6379> zadd sortedSets1 1 a 2 b
(integer) 2
127.0.0.1:6379> zadd sortedSets2 10 a 20 b
(integer) 2
127.0.0.1:6379> zinterstore sortedSetsResults 2 sortedSets1 sortedSets2
(integer) 2
127.0.0.1:6379> zrange sortedSetsResults 0 -1 withscores
1) "a"
2) "11"
3) "b"
4) "22"
127.0.0.1:6379> zinterstore sortedSetsResult 2 sortedSets1 sortedSets2 aggregate min
(integer) 2
127.0.0.1:6379> zrange sortedSetsResult 0 -1 withscores
1) "a"
2) "1"
3) "b"
4) "2"
127.0.0.1:6379> zinterstore sortedSetsResult 2 sortedSets1 sortedSets2 aggregate max
(integer) 2
127.0.0.1:6379> zrange sortedSetsResult 0 -1 withscores
1) "a"
2) "10"
3) "b"
4) "20"
127.0.0.1:6379> zinterstore sortedSetsResults 2 sortedSets1 sortedSets2 weights 1 0.1
(integer) 2
127.0.0.1:6379> zrange sortedSetsResults 0 -1 withscores
1) "a"
2) "2"
3) "b"
4) "4"
个人博客:https://jenkinwang.github.io/
参考书籍:《Redis入门指南(第二版)》李子骅 编著