Redis的五大数据类型
下面只是常用的命令,其余的命令如果要使用请参考官方文档!
String(字符串)
90%的java程序员在使用redis的时候只会使用一个String类型
127.0.0.1:6379> keys * # 查看数据库中所有的key
(empty array)
127.0.0.1:6379> set key1 v1 # 设置key值
OK
127.0.0.1:6379> get key1 # 获得key的值
"v1"
127.0.0.1:6379> keys *
1) "key1"
127.0.0.1:6379> append key1 "hello" # 在key值得后面追加字符串
(integer) 7 # 冒号可加可不加
127.0.0.1:6379> get key1
"v1hello"
127.0.0.1:6379> strlen key1 # 获得key值的长度
(integer) 7
127.0.0.1:6379> append key1 "world"
(integer) 12
127.0.0.1:6379> strlen key1
(integer) 12
127.0.0.1:6379> keys *
1) "key1"
127.0.0.1:6379> append name lisi # 如果append后跟的key不在,
(integer) 4 # 就相当于设置key
127.0.0.1:6379> keys *
1) "name"
2) "key1"
127.0.0.1:6379>
# i++
# 步长 i+=
127.0.0.1:6379> set views 0 # 初始浏览量为0
OK
127.0.0.1:6379> get views
"0"
127.0.0.1:6379> incr views # 自增1
(integer) 1 # 浏览量变为1
127.0.0.1:6379> incr views
(integer) 2 # 浏览量变为2
127.0.0.1:6379> get views
"2"
127.0.0.1:6379> decr views # 自减1 浏览量-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> incrby views 10
(integer) 19
127.0.0.1:6379> decrby views 5
(integer) 14
127.0.0.1:6379> get views
"14"
127.0.0.1:6379>
# 字符串位置 range
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> set key1 hello,world!
OK
127.0.0.1:6379> get key1
"hello,world!"
127.0.0.1:6379> getrange key1 0 5 # 获取字符串[0,5]
"hello,"
127.0.0.1:6379> getrange key1 0 -1 # 0~-1可以表示获取整个字符串 和get key1是一样的
"hello,world!"
127.0.0.1:6379>
# 替换
127.0.0.1:6379> set key2 abcdefg
OK
127.0.0.1:6379> get key2
"abcdefg"
127.0.0.1:6379> SETRANGE key2 2 xxx # 替换从指定位置开始的字符串
(integer) 7
127.0.0.1:6379> get key2
"abxxxfg"
127.0.0.1:6379>
# setex (set with expire) # 设置过期时间
# setnx (set if not exist) # 不存在设置 (在分布式锁中会常常用到)
127.0.0.1:6379> SETEX key3 20 hello # 设置key3的值为hello 20秒后过期
OK
127.0.0.1:6379> TTL key3 #过期时间
(integer) 11
127.0.0.1:6379> TTL key3
(integer) 10
127.0.0.1:6379> keys * # 还未过期
1) "key3"
2) "key1"
3) "key2"
127.0.0.1:6379> TTL key3
(integer) -2
127.0.0.1:6379> keys * # 已过期
1) "key1"
2) "key2"
127.0.0.1:6379> SETNX key4 world # 如果key4不存在 创建key4
(integer) 1
127.0.0.1:6379> keys *
1) "key1"
2) "key4"
3) "key2"
127.0.0.1:6379> SETNX key4 hello,world # 如果key4存在 则创建失败
(integer) 0
127.0.0.1:6379>
# mset
# mget
127.0.0.1:6379> flushdb # 清除当前数据库中的所有内容
OK
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> MSET k1 v1 k2 v2 k3 v3 # 同时设置多个值
OK
127.0.0.1:6379> keys *
1) "k1"
2) "k3"
3) "k2"
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 # k1存在 k4不存在
(integer) 0 # 操作失败 msetnx是一个原子性的操作,要么一起成功,要么一起失败
127.0.0.1:6379> keys *
1) "k1"
2) "k3"
3) "k2"
127.0.0.1:6379>
# 进阶用法
set user:1 {name:zhangsan,age:18} # 设置一个user:1对象,值为一个json字符串
# 这里的key是一个巧妙的设计:user:{id}:{filed}
127.0.0.1:6379> MSET user:1:name zhangsan user:1:age 18
OK
127.0.0.1:6379> MGET user:1:name user:1:age
1) "zhangsan"
2) "18"
# getset 先get后set 可以用来做一些更新操作
127.0.0.1:6379> GETSET db hello # 如果不存在值 则返回nil
(nil)
127.0.0.1:6379> GET db
"hello"
127.0.0.1:6379> GETSET db world # 如果存在值 则获取原来的值,并设置新的值
"hello"
127.0.0.1:6379> GET db
"world"
127.0.0.1:6379>
List(列表)
基本的数据类型,列表
list 类似一个双端队列,即可以从左边 push 和 pop,也可以从右边 push 和 pop,底层其实是一个单链表
在redis里面,我们可以把list玩成 栈、队列、阻塞队列
大部分的的list命令都是用l开头的,Redis不区分大小命令
# push
127.0.0.1:6379> LPUSH list 1 2 3 4 # 将一个或多个值插入到列表头部(左)
(integer) 4
127.0.0.1:6379> LRANGE list 0 -1 # 获取list的值
1) "4"
2) "3"
3) "2"
4) "1"
127.0.0.1:6379> LRANGE list 0 2 # 通过区间获取list的值
1) "4"
2) "3"
3) "2"
127.0.0.1:6379> RPUSH list 5 # 将一个或多个值插入到列表尾部(右)
(integer) 5
127.0.0.1:6379> LRANGE list 0 -1
1) "4"
2) "3"
3) "2"
4) "1"
5) "5"
127.0.0.1:6379>
# pop
127.0.0.1:6379> LPOP list # 移除list的第一个元素
"4"
127.0.0.1:6379> LRANGE list 0 -1
1) "3"
2) "2"
3) "1"
4) "5"
127.0.0.1:6379> RPOP list # 移除list的最后一个元素
"5"
127.0.0.1:6379> LRANGE list 0 -1
1) "3"
2) "2"
3) "1"
127.0.0.1:6379>
# lindex
127.0.0.1:6379> LRANGE list 0 -1
1) "3"
2) "2"
3) "1"
127.0.0.1:6379> LINDEX list 1 # 通过下标获得list中的某一个值
"2"
127.0.0.1:6379> LINDEX list 0
"3"
127.0.0.1:6379>
# llen
127.0.0.1:6379> FLUSHDB
OK
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> LPUSH list 1 2 3 4 5
(integer) 5
127.0.0.1:6379> LLEN list # 返回列表的长度
(integer) 5
127.0.0.1:6379>
# 移除指定的值
lrem
127.0.0.1:6379> LRANGE list 0 -1
1) "5"
2) "5"
3) "4"
4) "3"
5) "2"
6) "1"
127.0.0.1:6379> LREM list 1 3 # 移除list集合中指定个数的value,精确匹配
(integer) 1
127.0.0.1:6379> LRANGE list 0 -1
1) "5"
2) "5"
3) "4"
4) "2"
5) "1"
127.0.0.1:6379> LREM list 2 5
(integer) 2
127.0.0.1:6379> LRANGE list 0 -1
1) "4"
2) "2"
3) "1"
127.0.0.1:6379>
# ltrim 修剪 截断
127.0.0.1:6379> FLUSHDB
OK
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> RPUSH list hello hello1 hello2 hello3
(integer) 4
127.0.0.1:6379> LRANGE list 0 -1
1) "hello"
2) "hello1"
3) "hello2"
4) "hello3"
127.0.0.1:6379> LTRIM list 1 2 # 通过下标截取指定的长度,这个list列表已经被改变,只剩下截取的元素
OK
127.0.0.1:6379> LRANGE list 0 -1
1) "hello1"
2) "hello2"
127.0.0.1:6379>
# rpoplpush 移除列表的最后一个元素,将他移动到新的列表中
127.0.0.1:6379> LRANGE list 0 -1
1) "hello"
2) "hello1"
3) "hello2"
4) "hello3"
127.0.0.1:6379> RPOPLPUSH list newlist # 移除列表的最后一个元素,将他移动到新的列表中
"hello3"
127.0.0.1:6379> LRANGE list 0 -1 # 查看原来的列表
1) "hello"
2) "hello1"
3) "hello2"
127.0.0.1:6379> LRANGE newlist 0 -1 # 查看目标列表
1) "hello3"
127.0.0.1:6379>
# lset 将列表中指定下标的值替换为另一个值,相当于更新操作
127.0.0.1:6379> EXISTS list # 判断这个列表是否存在
(integer) 0
127.0.0.1:6379> LSET list 0 world # 如果不存在,执行更新操作就会报错
(error) ERR no such key
127.0.0.1:6379> LPUSH list hello
(integer) 1
127.0.0.1:6379> LRANGE list 0 -1
1) "hello"
127.0.0.1:6379> LSET list 0 world # 如果存在,就会更新指定下标的值
OK
127.0.0.1:6379> LRANGE list 0 -1
1) "world"
127.0.0.1:6379> LSET list 1 world1 # 如果下标不存在,也会报错
(error) ERR index out of range
127.0.0.1:6379>
# linsert 将某个具体的value插入到列表中某个元素的前面或者后面
127.0.0.1:6379> RPUSH list hello world
(integer) 2
127.0.0.1:6379> LRANGE list 0 -1
1) "hello"
2) "world"
127.0.0.1:6379> LINSERT list before world my # 将某个具体的value插入到列表中某个元素的前面
(integer) 3
127.0.0.1:6379> LRANGE list 0 -1
1) "hello"
2) "my"
3) "world"
127.0.0.1:6379> LINSERT list after my other # 将某个具体的value插入到列表中某个元素的后面
(integer) 4
127.0.0.1:6379> LRANGE list 0 -1
1) "hello"
2) "my"
3) "other"
4) "world"
127.0.0.1:6379>
小结
-
它实际上是一个链表,before Node(节点) after,left right都可以插入值
-
如果key不存在,创建新的链表
-
如果key存在,新增内容
-
如果移除了所有值(也就是空链表),也代表不存在
-
在两边插入或者改动值,效率最高;在中间插入或者改动值,相对来说效率可能会低一些
消息队列(Lpush Rpop) 栈(Lpush Lpop)
Set(集合)
set中的值是不能重复的
# sadd
# smembers
# sismember
127.0.0.1:6379> SADD set hello my world # 在set集合中添加元素
(integer) 3
127.0.0.1:6379> SMEMBERS set # 查看指定set的所有值
1) "world"
2) "my"
3) "hello"
127.0.0.1:6379> sismember set my # 判断某一个值是不是在set集合中
(integer) 1
127.0.0.1:6379> sismember set other
(integer) 0
# scard
127.0.0.1:6379> SCARD set # 获取set集合中元素的个数
(integer) 3
127.0.0.1:6379> SADD set my # set集合中没有重复的值
(integer) 0
127.0.0.1:6379> SMEMBERS set
1) "world"
2) "my"
3) "hello"
127.0.0.1:6379> SADD set other
(integer) 1
127.0.0.1:6379> SCARD set
(integer) 4
# srem
127.0.0.1:6379> SMEMBERS set
1) "other"
2) "world"
3) "my"
4) "hello"
127.0.0.1:6379> SREM set my # 移除set集合中的一个或者多个指定元素
(integer) 1
127.0.0.1:6379> SMEMBERS set
1) "other"
2) "world"
3) "hello"
127.0.0.1:6379>
# srandmember
127.0.0.1:6379> SMEMBERS set
1) "other"
2) "world"
3) "hello"
127.0.0.1:6379> SRANDMEMBER set # 随机抽取指定个数的元素,1可以默认不写
"hello"
127.0.0.1:6379> SRANDMEMBER set
"world"
127.0.0.1:6379> SRANDMEMBER set
"world"
127.0.0.1:6379> SRANDMEMBER set 2
1) "world"
2) "other"
127.0.0.1:6379> SRANDMEMBER set 2
1) "world"
2) "other"
127.0.0.1:6379> SRANDMEMBER set 2
1) "world"
2) "hello"
127.0.0.1:6379> SMEMBERS set
1) "other"
2) "world"
3) "hello"
# spop
127.0.0.1:6379> SMEMBERS set
1) "other"
2) "world"
3) "hello"
127.0.0.1:6379> SPOP set 2 # 随机删除指定个数的元素,1可以不写
1) "world"
2) "hello"
127.0.0.1:6379> SMEMBERS set
1) "other"
127.0.0.1:6379> SADD set one two three # 添加元素
(integer) 3
127.0.0.1:6379> SMEMBERS set
1) "two"
2) "three"
3) "one"
4) "other"
127.0.0.1:6379> SPOP set
"one"
127.0.0.1:6379> SMEMBERS set
1) "two"
2) "three"
3) "other"
# smove
127.0.0.1:6379> SADD set one two three
(integer) 3
127.0.0.1:6379> SMEMBERS set
1) "two"
2) "three"
3) "one"
127.0.0.1:6379> SADD myset hello
(integer) 1
127.0.0.1:6379> SMEMBERS set
1) "two"
2) "three"
3) "one"
127.0.0.1:6379> SMEMBERS myset
1) "hello"
127.0.0.1:6379> SMOVE set myset one # 将一个指定的值移动到另一个集合中
(integer) 1
127.0.0.1:6379> SMEMBERS myset
1) "one"
2) "hello"
127.0.0.1:6379> SMEMBERS set
1) "two"
2) "three"
# 差集 交集 并集
# sdiff
# sinter
# sunion
# 例子:微博的共同关注
127.0.0.1:6379> SADD set a b c d
(integer) 4
127.0.0.1:6379> SMEMBERS set
1) "c"
2) "a"
3) "d"
4) "b"
127.0.0.1:6379> SADD myset d e f g
(integer) 4
127.0.0.1:6379> SMEMBERS myset
1) "e"
2) "d"
3) "g"
4) "f"
127.0.0.1:6379> SDIFF set myset # set集合与myset集合的差集
1) "c"
2) "a"
3) "b"
127.0.0.1:6379> SINTER set myset # set集合与myset集合的交集
1) "d"
127.0.0.1:6379> SUNION set myset # set集合与myset集合的并集
1) "b"
2) "c"
3) "a"
4) "f"
5) "g"
6) "e"
7) "d"
Hash(哈希)
value为map集合(key1,map<key,value>)
127.0.0.1:6379> hset hash h1 one # 设置一个具体的key-value
(integer) 1
127.0.0.1:6379> hget hash h1 # 获取一个字段值
"one"
127.0.0.1:6379> hmset hash h1 hello h2 world # 设置多个key-value
OK
127.0.0.1:6379> hmget hash h1 h2 # 获取多个字段值
1) "hello"
2) "world"
127.0.0.1:6379> HGETALL hash # 获取一个hash中的所有数据
1) "h1" # k1
2) "hello" # v1
3) "h2" # k2
4) "world" # v2
127.0.0.1:6379>
# hdel
127.0.0.1:6379> HGETALL hash
1) "h1"
2) "hello"
3) "h2"
4) "world"
127.0.0.1:6379> HDEL hash h1 # 删除hash中指定的key字段,对应的value也随之被删除
(integer) 1
127.0.0.1:6379> HGETALL hash
1) "h2"
2) "world"
# hlen
127.0.0.1:6379> HGETALL hash
1) "h2"
2) "world"
3) "h1"
4) "hello"
5) "h3"
6) "one"
127.0.0.1:6379> hlen hash # 获取hash表的字段数量
(integer) 3
# hexists
127.0.0.1:6379> HGETALL hash
1) "h2"
2) "world"
3) "h1"
4) "hello"
5) "h3"
6) "one"
127.0.0.1:6379> HEXISTS hash h1 # 判断hash中指定字段是否存在
(integer) 1
127.0.0.1:6379> HEXISTS hash h4
(integer) 0
# hkeys
# hvals
127.0.0.1:6379> HKEYS hash # 获取所有的key
1) "h2"
2) "h1"
3) "h3"
127.0.0.1:6379> HVALS hash # 获取所有的value
1) "world"
2) "hello"
3) "one"
# hincrby
# hdecrby
127.0.0.1:6379> HSET hash h4 6
(integer) 1
127.0.0.1:6379> HINCRBY hash h4 1 # value值自增1
(integer) 7
127.0.0.1:6379> HINCRBY hash h4 -1 # value值自减1,相当于hdecrby
(integer) 6
# hash存放用户信息之类的经常变动的信息,更加方便
127.0.0.1:6379> HSET user:1 name "zhangsan" age 16
(integer) 2
127.0.0.1:6379> HGET user:1 name
"zhangsan"
127.0.0.1:6379> HGET user:1 age
"16"
# hsetnx
127.0.0.1:6379> HSETNX hash h5 hello # 如果不存在,设置成功
(integer) 1
127.0.0.1:6379> HSETNX hash h5 world # 如果存在,则设置失败
(integer) 0
小结
Hash更适合于对象的存储
String更适合于字符串的存储
Zset(有序集合)
在set的基础上,增加了一个值
127.0.0.1:6379> ZADD zset 1 one # 添加一个值
(integer) 1
127.0.0.1:6379> ZADD zset 2 two 3 three # 添加多个值
(integer) 2
127.0.0.1:6379> ZRANGE zset 0 -1 # 获取zset的所有值
1) "one"
2) "two"
3) "three"
# zrangebyscore 有序集合中指定区间内的值,由低到高
# -inf 负无穷
# +inf 正无穷
127.0.0.1:6379> ZADD salary 2000 zhang
(integer) 1
127.0.0.1:6379> ZADD salary 500 li
(integer) 1
127.0.0.1:6379> ZADD salary 10000 wang
(integer) 1
127.0.0.1:6379> ZRANGEBYSCORE salary -inf +inf # 有序集合中指定区间内的值,由低到高
1) "li"
2) "zhang"
3) "wang"
127.0.0.1:6379> ZRANGEBYSCORE salary -inf +inf withscores # 加上withscores可以显示具体的值
1) "li"
2) "500"
3) "zhang"
4) "2000"
5) "wang"
6) "10000"
127.0.0.1:6379> ZRANGEBYSCORE salary 0 3000 withscores
1) "li"
2) "500"
3) "zhang"
4) "2000"
# zrem
127.0.0.1:6379> ZRANGE salary 0 -1 # 查询salary中的所有值
1) "li"
2) "zhang"
3) "wang"
127.0.0.1:6379> ZREM salary li # 移除一个元素
(integer) 1
127.0.0.1:6379> ZRANGE salary 0 -1
1) "zhang"
2) "wang"
# zcard
127.0.0.1:6379> ZRANGE salary 0 -1
1) "zhang"
2) "wang"
127.0.0.1:6379> ZCARD salary # 获取有序集合中的个数
(integer) 2
# zcount
127.0.0.1:6379> ZADD zset 1 one 2 two 3 three
(integer) 3
127.0.0.1:6379> ZCOUNT zset 1 3 # 获取指定区间的成员数量
(integer) 3
127.0.0.1:6379> ZCOUNT zset 1 2
(integer) 2
使用思路
- set排序
- 存储班级成绩表
- 工资表排序
- 普通消息 1,重要消息 2;带权重进行判断
- 排行榜应用实现等