五大数据类型

官方文档:https://redis.io/
中文网:http://www.redis.cn/

Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings)散列(hashes)列表(lists)集合(sets)有序集合(sorted sets) 与范围查询, bitmapshyperloglogs地理空间(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 带权重进行排序 比如排行榜应用的实现!