引言
Redis是一个内存数据库,在学习它的内部原理与实现之前,我们首先要做到的就是学会使用,学会其丰富的命令操作。
一、字符串
Redis的字符串类型之前笔者的一篇入门介绍中曾经说过,不是简单的只存人可以阅读的字符串,实际可以是任意二进制的字节序列。在Redis中,字符串可以存储以下3中类型值:
- 字节串(byte string)
- 整数
- 浮点数
虽然我们以字符的形式把数值类型的整数或浮点数存到redis中,但我们仍然可以对这些以字符形式存储的整数或浮点数进行自增(increment)或自减(decrement)操作,必要时Redis还会把整数转换为浮点数。
整数的取值范围和系统的长整数取值范围相同,32位系统就是32位有符号整数,64位系统就是64位有符号整数。
Redis中的自增和自减命令
命令 | 描述 |
---|---|
incr | incr key-name ——把键存储的值加1 |
decr | decr key-name ——把键存储的值减1 |
incrby | incrby key-name amount 把键存储的值加上整数amount |
decrby | decrby key-name amount 把键存储的值减去整数amount |
incrbyfloat | incrbyfloatkey-name amount 把键存储的值加上浮点数amount |
测试代码如下,笔者使用的是Jedis库:
public class RedisTest {public static void main(String[] args) {try (JedisPool jedisPool = new JedisPool(new JedisPoolConfig(), "localhost", 6379)){Jedis jedis = jedisPool.getResource();jedis.incr("key-name");System.out.println("把键存储的值加1: "+jedis.get("key-name"));jedis.decr("key-name");System.out.println("把键存储的值减1: "+jedis.get("key-name"));jedis.incrBy("key-name", 10);System.out.println("把键存储的值加10: "+jedis.get("key-name"));jedis.decrBy("key-name", 5);System.out.println("把键存储的值减5: "+jedis.get("key-name"));jedis.incrByFloat("key-name", 0.1);System.out.println("把键存储的值加0.1: "+jedis.get("key-name"));}}
}
注意点如果Redis对于一个已经存在的键值进行incr、decr、incrBy、decrBy操作,则要求该键对应的值必须是整数,否则报错
比如上面的代码,再执行一次,对5.1进行自增操作,报错如下:
对于代码:
jedis.incrByFloat("key-name", 0.1);System.out.println("把键存储的值加0.1: "+jedis.get("key-name"));
5.1加上0.1会遇到精度问题,并不是5.2 而是5.199999999999,所以对于非整数类型的数值,解决方法是先从redis获取值,再使用java的BigDecimal对其进行处理,再写入redis,代码大致如下:
Redis强大到提供了字符串子串和二进制位的操作命令。这是一般的键值对数据库所没有的,命令如下:
命令 | 用例和描述 |
---|---|
APPEND | 如果 key 已经存在并且是一个字符串, APPEND 命令将给定的 value 追加到 key 原来的值的末尾 |
GETRANGE | 如果 key 已经存在并且是一个字符串, APPEND 命令将给定的 value 追加到 key 原来的值的末尾 |
SETRANGE | 重写 key 中字符串值的一部分,从 offset 开始用新的字符串替换 |
GETBIT | 返回 key 中指定偏移量 offset 上的位(bit)。偏移量 0 是第一位 |
SETBIT | 设置或清除 key 中指定偏移量 offset 上的位(bit),并返回修改前的 bit 值 |
BITCOUNT | 对一个 bit 字符串进行计数,在指定范围内计算为 1 的 bit 的数量 |
BITOP | 对两个或更多的 bit 字符串进行位操作(AND, OR, XOR, NOT)并将结果保存到 destination key |
这些命令笔者这里就不详细演示了,不怎么常用,感兴趣可以自行尝试:
二、列表
列表是Redis早期就实现的数据结构,从开始的普通双向链表到后来的快速列表实现,Redis在内存和性能的平衡上花了不少功夫。下面是一些常用的列表命令
命令 | 描述 |
---|---|
RPUSH | RPUSH key-name value [value …]——将一个或多个值推入列表的右端 |
LPUSH | LPUSH key-name value [value …]——将一个或多个值推入列表左端 |
RPOP | RPOP key-name——移除并返回列表最右端的元素 |
LPOP | LPOP key-name——移除并返回列表最左端的元素 |
LINDEX | LINDEX key-name offset——返回列表中偏移量位offset的元素 |
LRANGE | LRANGE key-name start end——返回列表从start偏移量到end偏移量范围 |
LTRIM | LTRIM key-name start end ——对列表进行修剪,只保留从start偏移量到end偏移量范围内的元素,其中包含stdart和end处的元素 |
笔者也是使用Jedis简单操作了下,也可以使用工具连redis server,使用redis相关命令操作。
没问题的哈
阻塞式的列表弹出命令以及在列表间移动元素的命令
命令 | 用例描述 |
---|---|
BLPOP | BLPOP key-name [key-name …] timeout ——从第一个非空列表中弹出位于最左端的元素,或者在timeout秒内阻塞等待可弹出的元素出现 |
BRPOP | BRPOP key-name [key-name …] timeout ——从第一个非空列表中弹出位于最右端的元素,或者在timeout秒内阻塞等待可弹出的元素出现 |
RPOPLPUSH | RPOPLPUSH source-key dest-key——从source-key列表中弹出位于最右端的元素,然后将这个元素推入dest-key列表的最左端,并向用户返回这个元素 |
BRPOPLPUSH | BRPOPLPUSH source-key dest-key timeout——从source-key列表中弹出位于最右端的元素,然后将这个元素推入dest-key列表的最左端,并向用户返回这个元素;如果source-key为空,则阻塞等待timeout秒 |
这些命令,现在看起来好像有用但不知道哪里适合用,不用管,后续介绍队列时会经常用到这些命令。
三、散列
散列相当于HashMap,可以让用户把多个键值对存储到一个Redis键里。Redis的散列值提供了一些与字符串值相同的特性,使得散列非常适合把一些相关的数据存储在一起。可以把这个数据聚集看成是关系数据库里的行,或者文档数据库的文档。
常用的散列命令如下:
命令 | 描述 |
---|---|
HMGET | HMGET key-name key [key …]——从散列中获取一个或多个键的值 |
HMSET | HMSET key-name key value [key value …]——为散列里面的一个或多个键设置值 |
HDEL | HDEL key-name key [key …]——删除散列里面的一个或多个键值对,返回成功找到并删除的键值对数量 |
HLEN | HLEN key-name——返回散列包含的键值对数量 |
Redis散列的高级命令如下:
命令 | 描述 |
---|---|
HEXISTS | HEXISTS key-name key——检查给定键是否存在于散列中 |
HKEYS | HKEYS key-name——获取散列包含的所有键 |
HVALS | HVALS key-name——获取散列包含的所有值 |
HGETALL | HGETALL key-name——获取散列包含的所有键值对 |
HINCRBY | HINCRBY key-name key increment——将key存储的值加上整数increment |
HINCRBYFLOAT | HINCRBYFLOAT key-name key increment——将key存储的值加上浮点数increment |
对于以上的命令我们需要注意的是HKEYS 和HVALS 的用处,尽管HGETALL可以获取所有键值信息,但是当散列包含的值非常大时,HKEYS就派上了用场,可以先使用HKEYS获取所有键,再使用HMGET一个个去除键的值,避免一次获取多个大体积的值造成服务器阻塞。
四、集合
集合和列表优点类似,但是集合只能保存各不相同的元素。集合以无序的方式存储多个各不相同的元素。
下面是一些常用的集合命令
命令 | 描述 |
---|---|
SADD | SADD key-name item [item…]——把一个或多个元素添加到集合里,并返回被添加元素中原本不存在于集合中的元素数量 |
SREM | SREM key-name item [item…]——从集合里面移除一个或多个元素,并返回被移除元素的数量 |
SMEMBERS | SMEMBERS key-name——返回集合包含的所有元素 |
SISMEMBER | SISMEMBER key-name item——检查元素item是否存在于集合key-name里 |
SCARD | SCARD key-name——返回集合包含的所有元素 |
SRANDMEMBER | SRANDMEMBER key-name [count]——从集合中返回一个或多个元素。当count为正数时,命令返回的随机元素可能会重复 |
SPOP | SPOP key-name——随机地移除集合中的一个元素,并返回被移除的元素 |
SMOVE | SMOVE source-key dest-key item——如果集合source-key包含item,那么从source-key中移除item,并将元素item移动到dest-key中,如果item移除成功,那么命令返回1,否则返回0 |
同样的,这些命令笔者也不再演示,感兴趣的可以使用Jedis尝试下,或者直接使用redis原生命令操作。
用于组合和处理多个集合的Redis命令
命令 | 描述 |
---|---|
SDIFF | SDIFF key-name [key-name…]——返回哪些存在于第一个集合、但不存在于其他集合中的元素(数学上的差集运算) |
SDIFFSTORE | SDIFFSTORE dest-key key-name [key-name…]——把那些存在于第一个集合但并不存在于其他集合中的元素(数学上的差集运算)存储到dest-key键里面 |
SINTER | SINTER key-name [key-name…]——返回那些同时存在所有集合中的元素,相当于数学的交集 |
SINTERSTORE | SINTERSTORE dest-key key-name [key-name…]——把那些同时存在所有集合中的元素存储到dest-key键中 |
SUNION | SUNION key-name [key-name…]——返回那些至少存在于一个集合中的元素(数学里的并集) |
SUNIONSTORE | SUNIONSTORE dest-key key-name [key-name…]——把并集元素存储到dest-key键中 |
五、有序集合
虽然叫有序集合,但是数据结构和集合反而不同,却是和散列类似,它存储着成员与分值之间的映射,提供了许多针对这个分值的处理命令,比如排序。这个score分值的作用就是排序。
常用的有序集合的命令如下:
命令 | 描述 |
---|---|
ZADD | ZADD key-name score member [score member…]——把带有给定分值的成员添加到有序集合中去 |
ZREM | ZREM key-name member [member…]——从有序集合中移除给定成员,返回移除成功的成员数量 |
ZCARD | ZCARD key-name——返回有序集合包含的成员数量 |
ZINCRBY | ZINCRBY key-name increment member——把member成员的分值加上increment |
ZCOUNT | ZCOUNT key-name min max——返回分值介于min和max之间的成员数量 |
ZRANK | ZRANK key-name member——返回成员member在有序集合中的排名,注意排名是从0开始的 |
ZSCORE | ZSCORE key-name member——返回成员member的分值 |
ZRANGE | ZRANGE key-name start stop [WITHSCORES]——返回有序集合中排名介于start和stop之间的成员,如果给定了可选的WITHSCORES选项,那么命令会将成员的分值也一并返回 |
自行在Redis中测试如下命令
ZADD zset-key 3 a 2 b 1 cZCARD zset-keyZINCRBY zset-key 3 cZSCORE zset-key cZRANK zset-key cZRANGE zset-key 0 -1 withscores
高阶有序集合命令:
命令 | 描述 |
---|---|
ZREVERANK | ZREVERANK key-name member——返回有序集合里成员member的排名,成员按照分数从大到小排列 |
ZREVERANGE | ZREVERANGE key-name start stop [withscores]——返回有序集合给定排名范围内的成员,成员按照分值从大到小排序 |
ZRANGEBYSCORE | ZRANGEBYSCORE key min max [withscores] [limit offset count]——返回有序集合中,分值介于min和max之间的所有成员 |
ZREVERANGEBYSCORE | ZREVERANGEBYSCOREkey min max [withscores] [limit offset count]——获取有序集合中分值介于min和max之间的所有成员,并按照分值从大到小的顺序来返回它们 |
ZREMRANGEBYRANK | ZREMRANGEBYRANK key-name start stop——移除有序集合中排名介于start和stop之间的所有成员 |
ZREMRANGEBYSCORE | ZREMRANGEBYSCORE key-name min max——移除有序集合中分值介于min和max之间的所有成员 |
ZINTERSTORE | ZINTERSTORE dest-key key-count key [key…] [weights weight [weight…]] [AGGREGATE SUM|MIN|MAX]——对给定集合执行类似于集合的交集运算 |
ZUNIONSCORE | ZUNIONSCORE dest-key key-count key [key…] [weights weight [weight…]] [AGGREGATE SUM|MIN|MAX]——对给定的有序集合执行类似于集合的交集运算 |
交集运算使用的是默认的聚集函数sum,输出的有序集合为交集成员的各自的分值累加。
并集运算是取每个并集成员最小分值的成员输出到有序集合中。