五大数据类型
官方文档:https://redis.io/
中文网:http://www.redis.cn/
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)。
String(key—— value)
127.0.0.1:6379[1]> set hello hello
OK
127.0.0.1:6379[1]> get hello
"hello"
127.0.0.1:6379[1]> append hello ",world" #追加 如果没有key就创建
(integer) 11
127.0.0.1:6379[1]> strlen hello #长度
(integer) 11
127.0.0.1:6379[1]>
############################################################
127.0.0.1:6379[1]> get views
"0"
127.0.0.1:6379[1]> incr views #自增,默认步长为1
(integer) 1
127.0.0.1:6379[1]> incr views
(integer) 2
127.0.0.1:6379[1]> get views
"2"
127.0.0.1:6379[1]> decr views #自减
(integer) 1
127.0.0.1:6379[1]> get views
"1"
127.0.0.1:6379[1]> incrby views 10 #自增,步长设置为10
(integer) 11
127.0.0.1:6379[1]> get views
"11"
127.0.0.1:6379[1]> decrby views 5
(integer) 6
127.0.0.1:6379[1]> get views
"6"
############################################################
#字符串范围
127.0.0.1:6379[1]> keys *
1) "views"
2) "hello"
3) "age"
127.0.0.1:6379[1]> get hello
"hello,world"
127.0.0.1:6379[1]> getrange hello 0 3 #getrange <key> start end
"hell"
127.0.0.1:6379[1]> getrange hello 0 -1
"hello,world"
127.0.0.1:6379[1]> get hello
"hello,world"
127.0.0.1:6379[1]> setrange hello 6 redis
(integer) 11
127.0.0.1:6379[1]> get hello
"hello,redis"
127.0.0.1:6379[1]>
############################################################
#setex (set with expire) 设置k-v和存活时间
#setnx (set if not existed) 不存在设置
127.0.0.1:6379[1]> setex diy 30 logo #设置30s存活时间
OK
127.0.0.1:6379[1]> ttl diy
(integer) 25
127.0.0.1:6379[1]> setnx mykey value #设置成功返回1
(integer) 1
127.0.0.1:6379[1]> setnx mykey value #当前存在key,则返回失败0
(integer) 0
############################################################
#在set和get前加个m可以批量处理
127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3 #同时设置多个值
OK
127.0.0.1:6379> mget k1 k2 k3 #同时取多个值
1) "v1"
2) "v2"
3) "v3"
127.0.0.1:6379> msetnx k3 v3 k4 v4 #msetnx是一个原子性操作,如果一个存在都会设置不成功
(integer) 0
127.0.0.1:6379> keys *
1) "k3"
2) "k1"
3) "k2"
#对象
set user:1 {name:zyj,age:18} #设置一个user对象用json来保存
#set user:{id}:{field}
127.0.0.1:6379> mset user:1:name zyj user:1:age 18
OK
127.0.0.1:6379> keys *
1) "user:1:age"
2) "user:1:name"
127.0.0.1:6379> mget user:1
1) (nil)
127.0.0.1:6379> mget user:1:name user:1:age
1) "zyj"
2) "18"
############################################################
getset #先get后set
127.0.0.1:6379> getset name zyj #如果不存在就set
(nil)
127.0.0.1:6379> get name
"zyj"
127.0.0.1:6379> getset name redis #如果存在,获取原来的值,set新的值
"zyj"
127.0.0.1:6379> get name
"redis"
String类型的常用使用场景
- 计数器
- 统计多单位的数量
- 比如说粉丝数,订阅数等对象
List(key——values)
在redis里面,可以用List实现栈、队列
所有list的命令都要加一个l
127.0.0.1:6379> lpush mylist "hello"
(integer) 1
127.0.0.1:6379> lpush mylist "world"
(integer) 2
127.0.0.1:6379> lpush mylist "hello"
(integer) 3
127.0.0.1:6379> lpush mylist "redis" #将一个或多个值插入列表头部
(integer) 4
127.0.0.1:6379> keys *
1) "mylist"
127.0.0.1:6379> lrange mylist 0 1
1) "redis"
2) "hello"
127.0.0.1:6379> lrange mylist 0 -1
1) "redis"
2) "hello"
3) "world"
4) "hello"
127.0.0.1:6379> rpush mylist zyj #将一个或多个值插入到列表头部
(integer) 5
127.0.0.1:6379> lrange mylist 0 -1
1) "redis"
2) "hello"
3) "world"
4) "hello"
5) "zyj"
###########################################################
lpop、rpop
127.0.0.1:6379> lpop mylist #弹出列表头部元素
"redis"
127.0.0.1:6379> rpop mylist #弹出列表尾部元素
"zyj"
127.0.0.1:6379> lindex mylist 0 #通过索引获取值
"hello"
127.0.0.1:6379> lindex mylist 1
"world"
127.0.0.1:6379> llen mylist #返回列表的长度
(integer) 3
###########################################################
#lrem 移除指定的值
127.0.0.1:6379> lrange mylist 0 -1
1) "hello"
2) "world"
3) "hello"
127.0.0.1:6379> lrem mylist 2 hello #lrem <list> <count> <element> 去除list指定的值
(integer) 2
127.0.0.1:6379> lrange mylist 0 -1
1) "world"
###########################################################
#ltrim 截取list
127.0.0.1:6379> lpush list e1 e2 e3 e4
(integer) 4
127.0.0.1:6379> lrange list 0 -1
1) "e4"
2) "e3"
3) "e2"
4) "e1"
127.0.0.1:6379> ltrim list 0 1 #ltrim截取指定的长度
OK
127.0.0.1:6379> lrange list 0 -1
1) "e4"
2) "e3"
###########################################################
#rpoplpush 从一个列表的尾部取出元素放入其他列表中
127.0.0.1:6379> keys *
1) "list"
127.0.0.1:6379> lrange list 0 -1
1) "e4"
2) "e3"
127.0.0.1:6379> rpoplpush list otherlist #如果list中只有一个元素,那么执行完之后list消失,所以redis的list底层是链表
"e3"
127.0.0.1:6379> keys *
1) "otherlist"
2) "list"
127.0.0.1:6379> lrange list 0 -1
1) "e4"
127.0.0.1:6379> lrange otherlist 0 -1
1) "e3"
###########################################################
#lset 更新列表
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 item1
(integer) 1
127.0.0.1:6379> lrange list 0 -1
1) "item1"
127.0.0.1:6379> lset list 0 item2 #如果存在,就能改变对应索引的值
OK
127.0.0.1:6379> lrange list 0 -1
1) "item2"
###########################################################
#linsert 将具体的value插入列表
127.0.0.1:6379> lrange list 0 -1
1) "item1"
2) "item2"
127.0.0.1:6379> linsert list before item2 hello #在value前插入
(integer) 3
127.0.0.1:6379> lrange list 0 -1
1) "item1"
2) "hello"
3) "item2"
127.0.0.1:6379> linsert list after item2 world #在value后插入
(integer) 4
127.0.0.1:6379> lrange list 0 -1
1) "item1"
2) "hello"
3) "item2"
4) "world"
小结
- redis的list实际上是一个链表,所以当list中没有值的时候,就是空链表相当于不存在
- 如果key不存在,就创建新的列表
- 如果key存在,新增内容
- 在两边插入或者改动值,效率最高
Set(key——values)
set中的值是不能重复的且无序,相当于java的set
127.0.0.1:6379> sadd myset "hello" #向set中添加元素
(integer) 1
127.0.0.1:6379> sadd myset "world"
(integer) 1
127.0.0.1:6379> smembers myset #查看某个set
1) "world"
2) "hello"
127.0.0.1:6379> keys *
1) "myset"
127.0.0.1:6379> sismember myset hello #查看set是否存在元素
(integer) 1
127.0.0.1:6379> sismember myset redis
(integer) 0
###########################################################
#scard 获取set的集合元素个数
127.0.0.1:6379> smembers myset
1) "world"
2) "hello"
127.0.0.1:6379> scard myset
(integer) 2
###########################################################
#srem 去除set集合的某个元素
127.0.0.1:6379> srem myset hello
(integer) 1
127.0.0.1:6379> smembers myset
1) "world"
###########################################################
#srandmember 随机抽出元素
127.0.0.1:6379> smembers set
1) "m3"
2) "m2"
3) "m4"
4) "m1"
127.0.0.1:6379> srandmember set
"m4"
127.0.0.1:6379> srandmember set 2 #抽出两个元素
1) "m1"
2) "m4"
###########################################################
#spop 随机删除元素
127.0.0.1:6379> smembers set
1) "m3"
2) "m2"
3) "m4"
4) "m1"
127.0.0.1:6379> spop set
"m4"
127.0.0.1:6379> smembers set
1) "m3"
2) "m2"
3) "m1"
127.0.0.1:6379> spop set 2 #随机删除两个元素
1) "m1"
2) "m3"
127.0.0.1:6379> smembers set
1) "m2"
###########################################################
#smove 移动元素
127.0.0.1:6379> smembers myset
1) "world"
127.0.0.1:6379> smembers set
1) "m2"
127.0.0.1:6379> smove set myset m2 #smove <source> <destination> <element>
(integer) 1
127.0.0.1:6379> smembers myset
1) "world"
2) "m2"
127.0.0.1:6379> keys * #set中没有元素就消失了
1) "myset"
###########################################################
#两个集合求并集、交集和差集
127.0.0.1:6379> sadd set1 a
(integer) 1
127.0.0.1:6379> sadd set1 b
(integer) 1
127.0.0.1:6379> sadd set1 c
(integer) 1
127.0.0.1:6379> sadd set2 c
(integer) 1
127.0.0.1:6379> sadd set2 d
(integer) 1
127.0.0.1:6379> sadd set2 e
(integer) 1
127.0.0.1:6379> smembers set1
1) "b"
2) "a"
3) "c"
127.0.0.1:6379> smembers set2
1) "e"
2) "d"
3) "c"
#差集 sdiff
127.0.0.1:6379> sdiff set1 set2
1) "b"
2) "a"
#并集 sunion
127.0.0.1:6379> sunion set1 set2
1) "e"
2) "a"
3) "c"
4) "b"
5) "d"
#交集 sinter
127.0.0.1:6379> sinter set1 set2
1) "c"
Hash(哈希)(key——map)
Map集合,key-map,在这个数据结构中这个value是一个map集合,即键对应map
127.0.0.1:6379> hset user name zyj
(integer) 1
127.0.0.1:6379> hget user name
"zyj"
127.0.0.1:6379> hmset user name zzz age 18 #设置多个字段
OK
127.0.0.1:6379> hget user name
"zzz"
127.0.0.1:6379> hgetall user #获取所有字段和值
1) "name"
2) "zzz"
3) "age"
4) "18"
###########################################################
#hdel 删除指定的filed
127.0.0.1:6379> hdel user name
(integer) 1
127.0.0.1:6379> hgetall user
1) "age"
2) "18"
###########################################################
#hlen hash的长度
127.0.0.1:6379> hlen user
(integer) 1 #以键值对为计数方式
###########################################################
#hexists 判断hash指定的字段是否存在
127.0.0.1:6379> hexists user name
(integer) 1
127.0.0.1:6379> hexists user weight
(integer) 0
###########################################################
#hkeys hvals
127.0.0.1:6379> hgetall user
1) "age"
2) "18"
127.0.0.1:6379> hset user name zyj sex 1
(integer) 2
127.0.0.1:6379> hkeys user #查看hash里map的key
1) "age"
2) "name"
3) "sex"
127.0.0.1:6379> hvals user #查看hash里map的value
1) "18"
2) "zyj"
3) "1"
###########################################################
#hincrby
127.0.0.1:6379> hset user count 0
(integer) 1
127.0.0.1:6379> hincrby user count 10
(integer) 10
127.0.0.1:6379> hget user count
"10"
###########################################################
#hsetnx
127.0.0.1:6379> hsetnx user name redis #如果存在该字段,则set不成功
(integer) 0
127.0.0.1:6379> hsetnx user hobby code #如果存在该字段,则set成功
(integer) 1
在redis中hash多用来储存变更的数据,尤其是用户信息等,更适合对象的存储
Zset(有序集合)(key——values)
#zadd <zset> <score> <element>
127.0.0.1:6379> zadd zset 0 a
(integer) 1
127.0.0.1:6379> zadd zset 1 b
(integer) 1
127.0.0.1:6379> zadd zset 3 c
(integer) 1
127.0.0.1:6379> zrange zset 0 -1
1) "a"
2) "b"
3) "c"
###########################################################
#排序如何实现?——zset里面默认就是根据score从小到大排序
127.0.0.1:6379> zrange salary 0 -1 withscores
1) "c"
2) "300"
3) "b"
4) "800"
5) "a"
6) "1000"
7) "d"
8) "1000"
127.0.0.1:6379> zadd salary 200 e
(integer) 1
127.0.0.1:6379> zrange salary 0 -1 withscores
1) "e"
2) "200"
3) "c"
4) "300"
5) "b"
6) "800"
7) "a"
8) "1000"
9) "d"
10) "1000"
127.0.0.1:6379> zadd salary 1200 f
(integer) 1
127.0.0.1:6379> zrange salary 0 -1 withscores
1) "e"
2) "200"
3) "c"
4) "300"
5) "b"
6) "800"
7) "a"
8) "1000"
9) "d"
10) "1000"
11) "f"
12) "1200"
127.0.0.1:6379> zrangebyscore salary 500 1000 withscores #根据score的范围取element
1) "b"
2) "800"
3) "a"
4) "1000"
5) "d"
6) "1000"
127.0.0.1:6379> zrevrange salary 0 -1 withscores #zrevrange 是根据score从大到小排序
1) "f"
2) "1200"
3) "d"
4) "1000"
5) "a"
6) "1000"
7) "b"
8) "800"
9) "c"
10) "300"
11) "e"
12) "200"
###########################################################
#zrem 删除指定元素
127.0.0.1:6379> zrem salary a
(integer) 1
127.0.0.1:6379> zrevrange salary 0 -1 withscores
1) "f"
2) "1200"
3) "d"
4) "1000"
5) "b"
6) "800"
7) "c"
8) "300"
9) "e"
10) "200"
127.0.0.1:6379> zcard salary #获取zset的element数量
(integer) 5
这些API只是冰山一角,实践的时候还是要查官方文档!
使用思路:set 排序 普通消息 1 重要消息 2 带权重进行排序 比如排行榜应用的实现!