⭐ 作者简介:码上言
⭐ 代表教程:Spring Boot + vue-element 开发个人博客项目实战教程
⭐专栏内容:个人博客系统
⭐我的文档网站:http://xyhwh-nav.cn/
文章目录
- 2.2、GET key
- 2.3、MSET key value [key value ...\]
- 2.4、MGET key1 [key2..\]
- 2.5、INCR key
- 2.6、INCRBY key increment
2.7、INCRBYFLOAT key increment
- 2.8、DECR key
- 2.9、DECRBY key decrement
- 2.10、SETNX key value
- 2.11、SETEX key seconds value
- 2.12、APPEND key value
- 3.3、HMSET key field1 value1 [field2 value2 \]
- 3.4、HMGET key field1 [field2\]
- 3.5、HGETALL key
- 3.6、HKEYS key
- 3.7、HVALS key
- 4、列表(List)4.1、LPUSH key value1 [value2\]
- 4.2、LPOP key
- 4.3、RPUSH key value1 [value2\]
- 4.4、RPOP key
- 4.5、LRANGE key start stop
4.6、LREM key count value - 4.7、LTRIM key start stop
- 4.8、RPOPLPUSH source destination
- 4.9、LSET key index value
- 5、集合(Set)
5.1、SADD key member1 [member2\] - 5.2、SMEMBERS key
- 5.3、SISMEMBER key member
- 5.4、SCARD key
- 5.5、SREM key member1 [member2\]
5.6、SRANDMEMBER key [count\]
- 6.2、ZRANGE key start stop [WITHSCORES\]
- 6.3、ZRANGEBYSCORE key min max [WITHSCORES\] [LIMIT]
- 6.4、ZREM key member [member ...\]
- 6.5、ZCARD key
6.6、ZCOUNT key min max - 6.7、ZRANK key member
- 6.8、ZREVRANK key member
- 6.9、ZSCORE key member
- 6.10、ZINCRBY key increment member
- 6.11、练习
Redis数据类型
Redis是一个key-value的数据库,key一般是String类型,不过value的类型多种多样。
这里先列出五中数据类型:String(字符串)、Hash(哈希)、List(列表)、Set(集合)、Zset(有序集合)需要注意的是:
每种数据结构都有自己底层的内部编码实现,而且是多种实现,这样Redis会在合适的场景选择合 适的内部编码。
每种数据结构都有两种以上的内部编码实现,例如string数据结构就包含了raw、int和 embstr三种内部编码。
有些内部编码可以作为多种外部数据结构的内部实现,例如ziplist就是hash、list和zset共有的内部编码
1、Redis 键(key)
Redis 键命令用于管理 redis 的键。
例如:我们删除key,前提是key存在。
127.0.0.1:6379> set name redis OK 127.0.0.1:6379> del name (integer) 1
DEL 是一个命令, runoobkey 是一个键。 如果键被删除成功,命令执行后输出 (integer) 1,否则将输出 (integer) 0
接下来我们来学习key的有关命令。
通过help [command] 可以查看一个命令的具体用法:
127.0.0.1:6379> help keys KEYS pattern summary: Find all keys matching the given pattern since: 1.0.0 group: generic
1.1、KEYS pattern
查看所有符合给定模式的key
127.0.0.1:6379> keys * (empty list or set) 127.0.0.1:6379> set name redis OK 127.0.0.1:6379> keys * 1) "name"
1.2、EXISTS key
检查给定 key 是否存在。
127.0.0.1:6379> exists name (integer) 1 127.0.0.1:6379> exists age (integer) 0
1.3、DEL key
该命令用于在 key 存在时删除 key。
127.0.0.1:6379> DEL name (integer) 1 127.0.0.1:6379> DEL age (integer) 0
1.4、MOVE key db
将当前数据库的 key 移动到给定的数据库 db 当中。
127.0.0.1:6379> move name 1 (integer) 1 127.0.0.1:6379> keys * (empty list or set) //切换到数据库1中,查询 127.0.0.1:6379> select 1 OK 127.0.0.1:6379[1]> keys * 1) "name"
1.5、EXPIRE key seconds
为给定 key 设置过期时间,以秒计。
127.0.0.1:6379> expire name 3 (integer) 1 //等3秒查询 127.0.0.1:6379> keys * (empty list or set)
1.6、RENAME key newkey
修改key的名称
127.0.0.1:6379> rename name name1 OK 127.0.0.1:6379> keys * 1) "name1"
1.7、TYPE key
返回 key 所储存的值的类型。
127.0.0.1:6379> type name string
1.8、PERSIST key
移除 key 的过期时间,key 将持久保持。
127.0.0.1:6379> set age 12 OK 127.0.0.1:6379> expire age 60 (integer) 1 127.0.0.1:6379> persist age (integer) 1 127.0.0.1:6379> ttl age (integer) -1
1.9、TTL key
查看还有多少秒过期,-1 表示永不过期,-2 表示已过期。
以下是设置age为10秒过期,中间使用ttl查看还有多久过期,最后过期就会返回-2
127.0.0.1:6379> expire age 10 (integer) 1 127.0.0.1:6379> ttl age (integer) 5 127.0.0.1:6379> ttl age (integer) 1 127.0.0.1:6379> ttl age (integer) -2
2、 字符串(String)
String是redis最基本的类型,你可以理解成Memcached一模一样的类型,一个key对应一个value。
Redis的string可以包含任何数据,比如jpg图片或者序列化的对象。
其value是字符串,不过根据字符串的格式不同,又可以分为3类:
- string:普通字符串
- int:整数类型,可以做自增、自减操作
- float:浮点类型,可以做自增、自减操作
不管是哪种格式,底层都是字节数组形式存储,只不过是编码方式不同。字符串类型的最大空间不能超过512M。
2.1、SET key value
设置指定 key 的值。
127.0.0.1:6379> set name xiaoming OK
2.2、GET key
获取指定 key 的值。
127.0.0.1:6379> get name "xiaoming"
2.3、MSET key value [key value …]
批量添加多个String类型的键值对
127.0.0.1:6379> mset k1 v1 k2 v2 OK 127.0.0.1:6379> keys * 1) "k2" 2) "k1" 3) "name"
2.4、MGET key1 [key2…]
根据多个key获取多个String类型的value,这个可以用在项目的浏览量和点赞的应用上
127.0.0.1:6379> mget k1 k2 1) "v1" 2) "v2"
2.5、INCR key
将 key 中储存的数字值增一。
127.0.0.1:6379> set age 20 OK 127.0.0.1:6379> incr age (integer) 21 127.0.0.1:6379> incr age (integer) 22
2.6、INCRBY key increment
让一个整型的key自增并指定步长,例如:incrby num 2 让num值自增2
127.0.0.1:6379> incr age (integer) 22 127.0.0.1:6379> incrby age 20 (integer) 42
2.7、INCRBYFLOAT key increment
将 key 所储存的值加上给定的浮点增量值(increment)
127.0.0.1:6379> incrbyfloat age 9 "51" 127.0.0.1:6379> incrbyfloat age 0.1 "51.10000000000000001"
2.8、DECR key
将 key 中储存的数字值减一。
127.0.0.1:6379> set num 1 OK 127.0.0.1:6379> decr num (integer) 0
2.9、DECRBY key decrement
key 所储存的值减去给定的减量值(decrement) 。
127.0.0.1:6379> incrby num 20 (integer) 21 127.0.0.1:6379> decrby num 10 (integer) 11
2.10、SETNX key value
添加一个String类型的键值对,前提是这个key不存在,否则不执行
127.0.0.1:6379> setnx num 10 (integer) 0 127.0.0.1:6379> get num "11"
2.11、SETEX key seconds value
添加一个String类型的键值对,并且指定有效期(以秒为单位)。
127.0.0.1:6379> setex time 200 fly OK 127.0.0.1:6379> get time "fly"
2.12、APPEND key value
如果 key 已经存在并且是一个字符串, APPEND 命令将指定的 value 追加到该 key 原来值(value)的末尾
127.0.0.1:6379> get num "11" 127.0.0.1:6379> append num 200 (integer) 5 127.0.0.1:6379> get num "11200"
2.13、GETRANGE key start end
getrange 获取指定区间范围内的值,类似between…and的关系,从零到负一表示全部
127.0.0.1:6379> set name a3121assaxd OK //全部获取 127.0.0.1:6379> getrange name 0 -1 "a3121assaxd" //截取部分字符串 127.0.0.1:6379> getrange name 0 2 "a31"
2.14、SETRANGE key offset value
setrange 设置指定区间范围内的值,格式是setrange key值 具体值
127.0.0.1:6379> setrange name 1 xxx (integer) 11 127.0.0.1:6379> get name "axxx1assaxd"
2.15、总结
- String数据结构是简单的key-value类型,value其实不仅可以是String,也可以是数字。
- 常规key-value缓存应用: 常规计数:微博数,粉丝数等。
问题1:Redis没有类似MySQL中的Table的概念,我们该如何区分不同类型的key呢?
比如在我们开发一个项目中,需要将用户和产品的信息存入到id,这时用户的id和产品的id可能都为1,那我们怎么存储到redis,我们知道redis的key不能重复。
这时我们就要看一下key的结构了:
Redis的key允许有多个单词形成层级结构,多个单词之间用’:'隔开,格式如下:
例如:项目名称:业务名称:类型:id
这个格式并非固定,也可以根据自己的需求来删除或添加词条。
例如我们的项目名称叫 blog,有user和product两种不同类型的数据,我们可以这样定义key:user相关的key:blog:user:1
product相关的key:blog:product:1
如果Value是一个Java对象,例如一个User对象,则可以将对象序列化为JSON字符串后存储:
key | value |
blog:user:1 | {“id”:1, “name”: “xiaoming”, “phone”: 123456789} |
blog:product:1 | {“id”:1, “name”: “huwei”, “color”: “red”} |
添加的数据:
'{"id":1, "name":"xiaoming", "phone": 12345678911}' '{"id":2, "name":"xiaohong", "phone": 18212121111}' '{"id":1, "name":"huwei", "color": "red"}' '{"id":2, "name":"xiaomi", "color": "black"}'
127.0.0.1:6379> set blog:user:1 '{"id":1, "name": "xiaoming", "phone": 123456789}' OK 127.0.0.1:6379> set blog:user:2 '{"id":2, "name":"xiaohong", "phone": 18212121111}' OK 127.0.0.1:6379> set blog:product:1 '{"id":1, "name":"huwei", "color": "red"}' OK 127.0.0.1:6379> set blog:product:2 '{"id":2, "name":"xiaomi", "color": "black"}' OK
添加完之后,打开之前安装的Redis客户端工具,然后查看我们刚添加的数据,树状的文件夹列表。还有很多的命令这里不再一一讲述,具体可以看官网发布的命令去学习:https://redis.io/commands
3、哈希(Hash)
Redis hash 是一个 string 类型的 field(字段) 和 value(值) 的映射表,hash 特别适合用于存储对象。如用户信息等。
Redis hash 是一个键值对集合,类似于Java中的HashMap结构。
Redis 中每个 hash 可以存储 232 - 1 键值对(40多亿)。
String结构是将对象序列化为JSON字符串后存储,当需要修改对象某个字段时很不方便
key | value |
blog:user:1 | {“id”:1, “name”: “xiaoming”, “phone”: 123456789} |
blog:user:2 | {“id”:2, “name”:“xiaohong”, “phone”: 18212121111} |
Hash结构可以将对象中的每个字段独立存储,可以针对单个字段做CRUD:
以下是Hash常见的命令:
3.1、HSET key field value
添加或者修改hash类型 key 的field的值
127.0.0.1:6379> hset dog color red (integer) 1 127.0.0.1:6379> hset dog age 2 (integer) 1 127.0.0.1:6379> hset tree name guihua (integer) 1 127.0.0.1:6379> hset tree age 20 (integer) 1
3.2、HGET key field
获取存储在哈希表中指定字段的值。
127.0.0.1:6379> hget tree age "20" 127.0.0.1:6379> hget dog color "red"
3.3、HMSET key field1 value1 [field2 value2 ]
批量添加多个hash类型key的field的值
127.0.0.1:6379> hmset dog name xiaohua sex nan OK
3.4、HMGET key field1 [field2]
批量获取多个hash类型key的field的值
127.0.0.1:6379> hmget dog name age 1) "xiaohua" 2) "2"
3.5、HGETALL key
获取在哈希表中指定 key 的所有字段和值
127.0.0.1:6379> hgetall dog 1) "color" 2) "red" 3) "age" 4) "2" 5) "name" 6) "xiaohua" 7) "sex" 8) "nan"
3.6、HKEYS key
获取一个hash类型的key中的所有的field
127.0.0.1:6379> hkeys dog 1) "color" 2) "age" 3) "name" 4) "sex"
3.7、HVALS key
获取一个hash类型的key中的所有的value
127.0.0.1:6379> hvals dog 1) "red" 2) "2" 3) "xiaohua" 4) "nan"
3.8、HINCRBY key field increment
让一个hash类型key的字段值自增并指定步长
127.0.0.1:6379> hincrby dog age 5 (integer) 7
3.9、HSETNX key field value
只有在字段 field 不存在时,设置哈希表字段的值。
127.0.0.1:6379> hsetnx dog age 3 (integer) 0
3.10、HEXISTS key field
查看哈希表 key 中,指定的字段是否存在。
127.0.0.1:6379> hexists dog name (integer) 1
3.11、HLEN key
获取哈希表中字段的数量
127.0.0.1:6379> hlen dog (integer) 4
4、列表(List)
Redis列表是简单的字符串列表,按照插入顺序排序,你可以添加一个元素到列表的头部(左边)或者尾部(右边)。
它的底层实际是个链表 !
Redis中的List类型与Java中的LinkedList类似,可以看做是一个双向链表结构。既可以支持正向检索和也可以支持反向检索。
特征也与LinkedList类似:
- 有序
- 元素可以重复
- 插入和删除快
- 查询速度一般
常用来存储一个有序数据,例如:朋友圈点赞列表,评论列表等。
一个列表最多可以包含 232 - 1 个元素 (4294967295, 每个列表超过40亿个元素)。
4.1、LPUSH key value1 [value2]
将一个或多个值插入到列表头部(左侧)。
127.0.0.1:6379> lpush cat xiaohua (integer) 1
4.2、LPOP key
移出并获取列表的第一个元素(左侧),当列表 key 不存在时,则返回nil。
127.0.0.1:6379> lpop cat1 (nil) 127.0.0.1:6379> lpop cat "xiaohua"
4.3、RPUSH key value1 [value2]
向列表右侧插入一个或多个元素。
127.0.0.1:6379> rpush cat xiaolan xiaoming (integer) 2
4.4、RPOP key
移除并返回列表右侧的第一个元素。
127.0.0.1:6379> rpop cat "xiaoming"
4.5、LRANGE key start stop
获取列表指定范围内的元素。
其中 0 表示列表的第一个元素, 1 表示列表的第二个元素,以此类推
0,-1范围是全部查出。
127.0.0.1:6379> lrange cat 0 2 1) "xiaolan"
4.6、LREM key count value
根据参数 COUNT 的值,移除列表中与参数 VALUE 相等的元素。
127.0.0.1:6379> lrem cat 1 "xiaolan" (integer) 1
4.7、LTRIM key start stop
对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。
127.0.0.1:6379> RPUSH mylist "hello" (integer) 1 127.0.0.1:6379> RPUSH mylist "hello" (integer) 2 127.0.0.1:6379> RPUSH mylist "foo" (integer) 3 127.0.0.1:6379> RPUSH mylist "bar" (integer) 4 127.0.0.1:6379> LTRIM mylist 1 -1 OK 127.0.0.1:6379> LRANGE mylist 0 -1 1) "hello" 2) "foo" 3) "bar"
4.8、RPOPLPUSH source destination
移除列表的最后一个元素,并将该元素添加到另一个列表并返回
127.0.0.1:6379> rpoplpush mylist myotherlist "bar" 127.0.0.1:6379> LRANGE mylist 0 -1 1) "hello" 2) "foo"
4.9、LSET key index value
将列表 key 下标为 index 的元素的值设置为 value 。
127.0.0.1:6379> exists mylist # 对空列表(key 不存在)进行 LSET (integer) 1 127.0.0.1:6379> lset mylist 0 item # 对非空列表进行 LSET OK 127.0.0.1:6379> LRANGE mylist 0 -1 1) "item" 2) "foo"
4.10、LINSERT key BEFORE|AFTER pivot value
在列表的元素前或者后插入元素。
127.0.0.1:6379> LINSERT mylist BEFORE "foo" "world" (integer) 3 127.0.0.1:6379> Lrange mylist 0 -1 1) "item" 2) "world" 3) "foo"
4.11、LLEN key
获取哈希表中字段的数量。
127.0.0.1:6379> Llen mylist (integer) 3
4.12、Lindex key index
按照索引下标获得元素(-1代表最后一个,0代表是第一个,即所有)
相当于 Java 链表操作中的 get(int index) 操 作;
127.0.0.1:6379> Lindex cat 1 (nil) 127.0.0.1:6379> Lindex cat 0 "xiaolan" 127.0.0.1:6379> Lindex cat -1 "xiaolan"
4.13、总结
- 链表的操作无论是头和尾效率都极高,但假如是对中间元素进行操作,效率就低了。
- 它是一个字符串链表,left,right 都可以插入添加 。
- 如果键不存在,创建新的链表 如果键已存在,新增内容。
- 如果值全移除,对应的键也就消失了。
list就是链表,略有数据结构知识的人都应该能理解其结构。使用Lists结构,我们可以轻松地实现最新消息排行等功能。List的另一个应用就是消息队列,可以利用List的PUSH操作,将任务存在List中,然后工作线程再用POP操作将任务取出进行执行。Redis还提供了操作List中某一段的api,你可以直接查询,删除List中某一段的元素。
Redis的list是每个子元素都是String类型的双向链表,可以通过push和pop操作从列表的头部或者尾部 添加或者删除元素,这样List即可以作为栈,也可以作为队列。
4.14、问题
1、list 实现队列
队列是先进先出的数据结构,常用于消息排队和异步逻辑处理,它会确保元素的访问顺序:
127.0.0.1:6379> RPUSH books python java golang (integer) 3 127.0.0.1:6379> LPOP books "python" 127.0.0.1:6379> LPOP books "java" 127.0.0.1:6379> LPOP books "golang" 127.0.0.1:6379> LPOP books (nil)
2、list 实现栈
栈是先进后出的数据结构,跟队列正好相反:
127.0.0.1:6379> RPUSH books python java golang (integer) 3 127.0.0.1:6379> RPOP books "golang" 127.0.0.1:6379> RPOP books "java" 127.0.0.1:6379> RPOP books "python" 127.0.0.1:6379> RPOP books (nil) 127.0.0.1:6379>