前言
本文章所有笔记都是由哔哩哔哩狂神说Java提供,详细视屏请在哔哩哔哩搜狂神说Java里的Redis超详细视屏教程。
Redis的五大数据类型
官网上的描述
中文翻译
Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。
Redis-key
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> set age 1
OK
127.0.0.1:6379> keys *
1) "age"
127.0.0.1:6379> keys *
1) "name"
2) "age"
127.0.0.1:6379> exists name # 查看当前类是否存在
(integer) 1
127.0.0.1:6379> move name 1 # 移出当前类
(integer) 1
127.0.0.1:6379> keys *
1) "age"
127.0.0.1:6379> EXPIRE name 10
(integer) 0
127.0.0.1:6379> set name yu
OK
127.0.0.1:6379> EXPIRE name 10 #设置类过期时间,单位是秒
(integer) 1
127.0.0.1:6379> ttl name # 查看当前key的剩余时间
(integer) 3
127.0.0.1:6379> ttl name
(integer) 1
127.0.0.1:6379> ttl name
(integer) 1
127.0.0.1:6379> ttl name
(integer) -2
127.0.0.1:6379> get name
(nil)
127.0.0.1:6379> select 1
OK
127.0.0.1:6379> keys *
1) "age"
127.0.0.1:6379> set name yu
OK
127.0.0.1:6379> type name #查看当前类的一个类型
string
127.0.0.1:6379> type age
string
1、 String(字符串)
##################################################################
127.0.0.1:6379> set key1 v1 # 设置值
OK
127.0.0.1:6379> get key1 # 获得值
"v1"
127.0.0.1:6379> keys * #获取所有key
1) "age"
2) "name"
3) "key1"
127.0.0.1:6379> APPEND key1 "hello" # 追加字符串,如果当前key不存在,就相当于set key
(integer) 7
127.0.0.1:6379> get key1
"v1hello"
127.0.0.1:6379> STRLEN key1 #获取字符串长度
(integer) 7
127.0.0.1:6379> APPEND key1 "lllll"
(integer) 12
127.0.0.1:6379> STRLEN key1
(integer) 12
##################################################################
# i++
#步长 i+=
127.0.0.1:6379> set views 0
OK
127.0.0.1:6379> get views
"0"
127.0.0.1:6379> incr views # 自增1
(integer) 1
127.0.0.1:6379> incr views
(integer) 2
127.0.0.1:6379> get views
"2"
127.0.0.1:6379> decr views # 自减1
(integer) 1
127.0.0.1:6379> decr views
(integer) 0
127.0.0.1:6379> decr views
(integer) -1
127.0.0.1:6379> get views
"-1"
127.0.0.1:6379> incrby views 10 # 设置步长,指定自增量
(integer) 9
127.0.0.1:6379> decrby views 5 # 设置步长,指定自减量
(integer) 4
##################################################################
字符串范围
127.0.0.1:6379> set key1 "hello,yu" # 设置key1值
OK
127.0.0.1:6379> get key1
"hello,yu"
127.0.0.1:6379> GETRANGE key1 0 3 # 截取字符串【0,3】
"hell"
127.0.0.1:6379> GETRANGE key1 0 -1 # 获取全部字符串 和 get key 一样
"hello,yu"
#替换
127.0.0.1:6379> set key2 abcderg
OK
127.0.0.1:6379> get key2
"abcderg"
127.0.0.1:6379> setrange key2 1 xx # 替换指定位置开始字符串
(integer) 7
127.0.0.1:6379> get key2
"axxderg"
127.0.0.1:6379>
##################################################################
# setex (set with expire) #设置过期时间
# setnx (set if exist) #不存在在设置(在分布式锁中常常使用!)
127.0.0.1:6379> setex key3 30 "helllo" #设置key3 值为 “hello” 设置30秒过期
OK
127.0.0.1:6379> ttl key3
(integer) 26
127.0.0.1:6379> get key3
"helllo"
127.0.0.1:6379> setnx mykey "redis" # 如果mykey不存在,创建mykey
(integer) 1
127.0.0.1:6379> keys *
1) "key1"
2) "mykey"
3) "key2"
127.0.0.1:6379> ttl key3
(integer) -2
127.0.0.1:6379> setnx mykey "mogDb" # 如果mykey存在,创建失败
(integer) 0
127.0.0.1:6379> get mykey
"redis"
127.0.0.1:6379>
##################################################################
mset
mget
127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3 #同时设置多个值
OK
127.0.0.1:6379> keys *
1) "k3"
2) "k2"
3) "k1"
127.0.0.1:6379> mget k1 k2 k3 #同时获取多个值
1) "v1"
2) "v2"
3) "v3"
127.0.0.1:6379> msetnx k1 v1 k4 v4 #msetnx 是一个原子性的操作 要么一起成功,要么一起失败
(integer) 0
127.0.0.1:6379> get k3
"v3"
127.0.0.1:6379> get k4
(nil)
127.0.0.1:6379>
#对象
127.0.0.1:6379> set user:1 {name:zhangsan,age:3} #设置一个user:1对象 值为json字符来保存一个对象
#这里key是一个巧妙的设计 : user:{id}:{filed} , 如此设计在Redis中完全ok
OK
127.0.0.1:6379> get user:1
"{name:zhangsan,age:3}"
127.0.0.1:6379> mset user:1:name zhsngsan user:1:age 2
OK
127.0.0.1:6379> mget user:1:name user:1:age
1) "zhsngsan"
2) "2"
##################################################################
getset #先get然后在set
127.0.0.1:6379> getset db yu # 如果不存在值,返回nil
(nil)
127.0.0.1:6379> get db
"yu"
127.0.0.1:6379> getset db ming # 如果存在值,获取原来的值,并设置新的值
"yu"
127.0.0.1:6379> get db
"ming"
数据结构是相同的
String类似使用场景:value除了是字符串还可以是数字
- 计数器
- 统计多单位数量
- 粉丝数
- 对象缓存存储
2、List
基本的数据类型,列表
所有list命令都是L开头
##################################################################
127.0.0.1:6379> lpush list one #将一个值或多个插入到列表头部(左)
(integer) 1
127.0.0.1:6379> lpush list tow
(integer) 2
127.0.0.1:6379> lpush list three
(integer) 3
127.0.0.1:6379> lrange list 0 -1 #获取list的值
1) "three"
2) "tow"
3) "one"
127.0.0.1:6379> lrange list 0 1 #通过区间获取具体的值
1) "three"
2) "tow"
127.0.0.1:6379> RPUSH list right #将一个值或多个插入到列表尾部(右)
(integer) 4
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "tow"
3) "one"
4) "right"
##################################################################
Lpop
Rpop
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "tow"
3) "one"
4) "right"
127.0.0.1:6379> lpop list # 移除列表的第一元素
"three"
127.0.0.1:6379> RPOP list # 移除列表的最后一个元素
"right"
127.0.0.1:6379> lrange list 0 -1
1) "tow"
2) "one"
##################################################################
Lindex
127.0.0.1:6379> lrange list 0 -1
1) "tow"
2) "one"
127.0.0.1:6379> Lindex list 1 #通过下标获取list某一个值
"one"
127.0.0.1:6379> Lindex list 0
"tow"
##################################################################
llen
127.0.0.1:6379> lpush list one
(integer) 1
127.0.0.1:6379> lpush list tow
(integer) 2
127.0.0.1:6379> lpush list three
(integer) 3
127.0.0.1:6379> llen list # 返回列表的长度
(integer) 3
##################################################################
#移除指定的值
lrem
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "three"
3) "three"
4) "tow"
5) "one"
127.0.0.1:6379> lrem list 1 one #移除list集合中指定个数的value,精确匹配
(integer) 1
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "three"
3) "three"
4) "tow"
127.0.0.1:6379> lrem list 2 three
(integer) 2
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "tow"
127.0.0.1:6379> lpush list three
(integer) 3
127.0.0.1:6379> lrem list 2 three
(integer) 2
127.0.0.1:6379> lrange list 0 -1
1) "tow"
127.0.0.1:6379>
##################################################################
trim 修剪 list 截断
127.0.0.1:6379> rpush mylist "hello"
(integer) 1
127.0.0.1:6379> rpush mylist "hello1"
(integer) 2
127.0.0.1:6379> rpush mylist "hello2"
(integer) 3
127.0.0.1:6379> rpush mylist "hello3"
(integer) 4
127.0.0.1:6379> ltrim mylist 1 2 #通过下标截取指定的长度,这个list已经被改变了只剩下截取的元素
OK
127.0.0.1:6379> lrange mylist 0 -1
1) "hello1"
2) "hello2"
##################################################################
rpoplpush #移除列表最后一个元素,并添加一个新的元素
127.0.0.1:6379> rpush mylist "hello"
(integer) 1
127.0.0.1:6379> rpush mylist "hello1"
(integer) 2
127.0.0.1:6379> rpush mylist "hello2"
(integer) 3
127.0.0.1:6379> rpoplpush mylist myonelist #移除列表最后一个元素,并添加一个新的元素
"hello2"
127.0.0.1:6379> lrange mylist 0 -1 #查看原来列表
1) "hello"
2) "hello1"
127.0.0.1:6379> lrange myonelist 0 -1 #查看新的列表
1) "hello2"
##################################################################
lest 将列表中指定下标的值替换为另外一个值,更新操作
127.0.0.1:6379> exists list #判断列表是否存在
(integer) 0
127.0.0.1:6379> lset list 0 item #如果不存在列表,更新就会报错
(error) ERR no such key
127.0.0.1:6379> lpush list value1
(integer) 1
127.0.0.1:6379> lrange list 0 0
1) "value1"
127.0.0.1:6379> lset list 0 item #如果存在,更新当前下标的值
OK
127.0.0.1:6379> lrange list 0 0
1) "item"
127.0.0.1:6379> lset list 1 one #如果不存在,更新就会报错
(error) ERR index out of range
##################################################################
linsert #将某个具体的value插入到某个列表中某个元素的前面或者后面
127.0.0.1:6379> rpush list "hello"
(integer) 1
127.0.0.1:6379> rpush list "world"
(integer) 2
127.0.0.1:6379> linsert list before "world" "one" #插入到 world 前面
(integer) 3
127.0.0.1:6379> lrange list 0 -1
1) "hello"
2) "one"
3) "world"
127.0.0.1:6379> linsert list after "world" "hahah" #插入到 world 后面
(integer) 4
127.0.0.1:6379> lrange list 0 -1
1) "hello"
2) "one"
3) "world"
4) "hahah"
小结
- 是一个链表,before node after ,left , right 都可以插入
- 如果key不存在 ,创建新的链表
- 若果key存在,新增内容
- 若果移出所有值,空链表,也代表不存在
- 在两边插入或者改动值,效率最高! 中间插入,相对效率会低
适用场景:
消息排队!消息队列(Lpush Rpop),栈(Lpush Lpop)
3、set(集合)
set值是不能重复的
##################################################################
127.0.0.1:6379> sadd myset "hello" #set集合中添加元素
(integer) 1
127.0.0.1:6379> sadd myset "yu"
(integer) 1
127.0.0.1:6379> sadd myset "yulove"
(integer) 1
127.0.0.1:6379> smembers myset #查询指定set的所有值
1) "yu"
2) "hello"
3) "yulove"
127.0.0.1:6379> sismember myset hello #判断某个值是否存在set集合中
(integer) 1
127.0.0.1:6379> sismember myset hell1
(integer) 0
127.0.0.1:6379>
##################################################################
127.0.0.1:6379> scard myset #获取set集合中的元素个数
(integer) 3
##################################################################
rem
127.0.0.1:6379> srem myset "hello" #移出set集合中的指定元素
(integer) 1
127.0.0.1:6379> scard myset
(integer) 2
127.0.0.1:6379> smembers myset
1) "yu"
2) "yulove"
127.0.0.1:6379>
##################################################################
set 无序不重复集合
27.0.0.1:6379> smembers myset
1) "yu"
2) "yulove"
127.0.0.1:6379> SRANDMEMBER myset #随机抽取选中一个元素
"yulove"
127.0.0.1:6379> SRANDMEMBER myset
"yulove"
127.0.0.1:6379> SRANDMEMBER myset
"yulove"
127.0.0.1:6379> SRANDMEMBER myset
"yu"
127.0.0.1:6379> SRANDMEMBER myset
"yulove"
##################################################################
删除指定的key,随机删除一个key
127.0.0.1:6379> SMEMBERS myset
1) "yu"
2) "yulove"
127.0.0.1:6379> spop myset #随机删除一个元素
"yu"
127.0.0.1:6379> spop myset
"yulove"
127.0.0.1:6379> SMEMBERS myset
(empty list or set)
127.0.0.1:6379>
##################################################################
将一个指定的值移动到另一个set集合中
127.0.0.1:6379> sadd myset "hello"
(integer) 1
127.0.0.1:6379> sadd myset "word"
(integer) 1
127.0.0.1:6379> sadd myset2 "yu"
(integer) 1
127.0.0.1:6379> smove myset myset2 "hello" #将一个指定的值移动到另一个set集合中
(integer) 1
127.0.0.1:6379> SMEMBERS myset
1) "word"
127.0.0.1:6379> SMEMBERS myset2
1) "yu"
2) "hello"
##################################################################
数字集合类:
- 差集
- 交集
- 并集
127.0.0.1:6379> sadd key1 a
(integer) 1
127.0.0.1:6379> sadd key1 b
(integer) 1
127.0.0.1:6379> sadd key1 c
(integer) 1
127.0.0.1:6379> sadd key2 c
(integer) 1
127.0.0.1:6379> sadd key2 e
(integer) 1
127.0.0.1:6379> sadd key2 f
(integer) 1
127.0.0.1:6379> SDIFF key1 key2 # 差集
1) "a"
2) "b"
127.0.0.1:6379> SINTER key1 key2 # 交集
1) "c"
127.0.0.1:6379> SUNION key1 key2 # 并集
1) "f"
2) "c"
3) "b"
4) "e"
5) "a"
4、 Hash(哈希)
Map集合,key-value 这个值是一个map集合!本质上和String类型没有太大的区别,还是一个简单的key-value
##################################################################
127.0.0.1:6379> hset myhash f1 yu #set一个具体的值
(integer) 1
127.0.0.1:6379> hget myhash f1 #获取一个具体的值
"yu"
127.0.0.1:6379> hmset myhash f1 hello f2 word #存储多个字段
OK
127.0.0.1:6379> hmget myhash f1 f2 # 获取多个字段
1) "hello"
2) "word"
127.0.0.1:6379> hgetall myhash #获取全部数据
1) "f1"
2) "hello"
3) "f2"
4) "word"
127.0.0.1:6379> hdel myhash f1 #删除hash指定可以字段;对应value值也就消失了
(integer) 1
127.0.0.1:6379> hgetall myhash
1) "f2"
2) "word"
##################################################################
hlen
127.0.0.1:6379> hmset myhash f1 hello f2 world
OK
127.0.0.1:6379> hgetall myhash
1) "f2"
2) "world"
3) "f1"
4) "hello"
127.0.0.1:6379> hlen myhash #获取hash表的字段数量
(integer) 2
##################################################################
127.0.0.1:6379> hexists myhash f1 #判断hash中的指定字段是否存在
(integer) 1
127.0.0.1:6379> hexists myhash f3
(integer) 0
##################################################################
#hkeys 只获得所有的key
#hvalue 只获得所有的value
127.0.0.1:6379> hkeys myhash #获取所有的f
1) "f2"
2) "f1"
127.0.0.1:6379> HVALS myhash #获取所有的value
1) "world"
2) "hello"
##################################################################
incr decr
127.0.0.1:6379> hset myhash f3 5 #指定增量
(integer) 1
127.0.0.1:6379> HINCRBY myhash f3 1
(integer) 6
127.0.0.1:6379> HINCRBY myhash f3 -1
(integer) 5
127.0.0.1:6379> hgetall myhash
1) "f2"
2) "world"
3) "f1"
4) "hello"
5) "f3"
6) "5"
127.0.0.1:6379> HSETNX myhash f4 hello #如果不存在则可以设置
(integer) 1
127.0.0.1:6379> HSETNX myhash f4 world #如果存在则不能设置
(integer) 0
适用场景:
hash变更数据user name age ,尤其是用户信息之类,经常变动信息!hash更适合于对象存储,String更适合字符串存储
5、Zset(有序集合)
在set基础上,增加一个值
127.0.0.1:6379> zadd myset 1 A #添加一个值
(integer) 1
127.0.0.1:6379> zadd myset 2 B 3 D 4 C #添加多个值
(integer) 3
127.0.0.1:6379> ZRANGE myset 0 -1 #获取全部数据
1) "A"
2) "B"
3) "D"
4) "C"
##################################################################
排序实现
127.0.0.1:6379> zadd sal 2000 yu #添加三个用户
(integer) 1
127.0.0.1:6379> zadd sal 3000 ming
(integer) 1
127.0.0.1:6379> zadd sal 200 zhang
(integer) 1
127.0.0.1:6379> ZRANGEBYSCORE sal -inf +inf #从小到大排序
1) "zhang"
2) "yu"
3) "ming"#
127.0.0.1:6379> ZRANGEBYSCORE sal -inf +inf withscores #返回全部用户并且不带成绩
1) "zhang"
2) "200"
3) "yu"
4) "2000"
5) "ming"
6) "3000"
127.0.0.1:6379> ZRANGEBYSCORE sal -inf 2500 #显示工资小于2500的员工的升序排序
1) "zhang"
2) "yu"
127.0.0.1:6379> ZRANGE sal 0 -1 #从大到小排序
1) "yu"
2) "ming"
127.0.0.1:6379> ZRANGEBYSCORE sal -inf 2500 withscores
1) "zhang"
2) "200"
3) "yu"
4) "2000"
##################################################################
#移出rem中的元素
127.0.0.1:6379> ZRANGE sal 0 -1
1) "zhang"
2) "yu"
3) "ming"
127.0.0.1:6379> ZREM sal zhang # 移出集合中的指定元素
(integer) 1
127.0.0.1:6379> ZRANGE sal 0 -1
1) "yu"
2) "ming"
127.0.0.1:6379> ZCARD sal #获取有序集合中的个数
(integer) 2
##################################################################
127.0.0.1:6379> zadd myset 1 hello
(integer) 1
127.0.0.1:6379> zadd myset 2 world
(integer) 1
127.0.0.1:6379> zadd myset 3 yu
(integer) 1
127.0.0.1:6379> ZCOUNT myset 1 2 #获取指定区间的成员数量!
(integer) 2
127.0.0.1:6379> ZCOUNT myset 1 3
(integer) 3