Redis的几种数据类型你搞清楚了吗?

162 阅读6分钟

1. 五种基本的数据结构

1.1 String字符串

可以用来存储字符串、整数、浮点数。
常见命令

  • set 设置key值,get获取key值
127.0.0.1:6379> set name Armin
OK
127.0.0.1:6379> get name
"Armin"
  • mset 设置多个值 mget获取多个key值
127.0.0.1:6379> del name  //删除name的key值
(integer) 1
127.0.0.1:6379> get name
(nil)
127.0.0.1:6379> mset name Armin age 23 //设置name:Armin,age:23
OK
127.0.0.1:6379> mget name age //批量获取key为name和age的值
1) "Armin"
2) "23"
  • setnx 如果key存在,则设置失败。可以基于此实现分布式锁,用del key来释放锁,一般为了防止释放锁失败,我们还会加上过期时间expire
127.0.0.1:6379> flushdb //首先我们先清空当前库
OK
127.0.0.1:6379> keys *
(empty array)
127.0.0.1:6379> setnx name Armin //设置成功
(integer) 1
127.0.0.1:6379> setnx name lisi //失败
(integer) 0
127.0.0.1:6379> get name
"Armin"
127.0.0.1:6379> expire name 3 //设置三秒后过期,一般与set操作一起执行,保证原子性 
(integer) 1
127.0.0.1:6379> get name
(nil)
127.0.0.1:6379> set name Armin EX 3 NX
OK
127.0.0.1:6379> get name
"Armin"
127.0.0.1:6379> get name
(nil)
  • incr/incrby 整数递增, incrby指定增加的数值
127.0.0.1:6379> set num 1
OK
127.0.0.1:6379> incr num
(integer) 2
127.0.0.1:6379> get num
"2"
127.0.0.1:6379> incrby num 3
(integer) 5
127.0.0.1:6379> get num
"5
  • decr/decrby 整数递减,decrby指定减少的数值
127.0.0.1:6379> decr num
(integer) 4
127.0.0.1:6379> decrby num 2
(integer) 2
  • strlen 获取指定key的长度
127.0.0.1:6379> get name
"Armin"
127.0.0.1:6379> strlen name
(integer) 5
  • append 追加内容
127.0.0.1:6379> append name good
(integer) 9
127.0.0.1:6379> get name
"Armingood"

getrange 获取指定范围字符串

127.0.0.1:6379> getrange name 0 3
"Armi"

应用场景

  • 热点数据缓存(set方法)
  • 计数器(incr)
  • 限流(incr)
  • 分布式锁(setnx)

1.2 Hash哈希

可以用于存储多个键值对
常见命令

  • hset 设置一个key的多个field的value ,hget/hgetall获取值
127.0.0.1:6379> hset user name Armin age 23 /
(integer) 2
127.0.0.1:6379> hget user name 
"Armin"
127.0.0.1:6379> hgetall user 获取该key的所有信息
1) "name"
2) "Armin"
3) "age"
4) "23"
  • hkeys/hvals 获取所有的key/value
127.0.0.1:6379> hkeys user //获取所有的key
1) "name"
2) "age"
127.0.0.1:6379> hvals user //获取所有的value
1) "Armin"
2) "23"
  • hincrby 增加执行字段的value,并没有hdecr相关操作
127.0.0.1:6379> hincrby user01 age 1
(integer) 24

应用场景

  • 存储对象类型数据,相比于String节省了更多key,例如购物车

1.3 List列表

有序重复字符串列表
操作命令

  • lpush/rpush/lpop/rpop 左推/右推/左出/右出
127.0.0.1:6379> lpush word a b c d // 往word列表从左依次推入a b c d
(integer) 4
127.0.0.1:6379> lpop word //word //列表左侧弹出元素
"d"
127.0.0.1:6379> rpop word //word //列表右侧弹出元素
"a"
127.0.0.1:6379> lrange word 0 -1 //获取指定索引元素,当前获取全部
1) "c"
2) "b"
  • lrange 获取指定范围索引元素
127.0.0.1:6379> lrange word 0 0
1) "c"
127.0.0.1:6379> lrange word 0 1
1) "c"
2) "b"
  • lindex 获取指定位置元素
127.0.0.1:6379> lindex word 1
"b"
  • llen 获取列表长度
127.0.0.1:6379> llen word
(integer) 2

应用场景

  • 队列 (lpush/rpop)
  • 栈 (lpush/lpop)
  • 因为列表是有序的可做事件时间线

1.4 Set集合

无序不重复字符串集合
操作命令

  • sadd 添加一个或者多个元素
127.0.0.1:6379> sadd word a b c d
(integer) 4
  • smembers 获取全部元素
127.0.0.1:6379> smembers word
1) "a"
2) "d"
3) "b"
4) "c"
  • scard 统计元素个数
127.0.0.1:6379> scard word
(integer) 4
  • srandmenber 随机获取元素
127.0.0.1:6379> srandmember word 
"d"
127.0.0.1:6379> srandmember word 2 //随机获取指定数量元素
1) "b"
2) "c"
  • srem 移除一个或多个元素
127.0.0.1:6379> srandmember word 2
1) "b"
2) "c"
127.0.0.1:6379> srem word b c 
(integer) 2
127.0.0.1:6379> smembers word
1) "a"
2) "d"
  • sismember 查看元素是否存在
127.0.0.1:6379> sismember word a //存在
(integer) 1
127.0.0.1:6379> sismember word b // 不存在
(integer) 0
  • spop 随机弹出元素
127.0.0.1:6379> spop word 
"d"
  • sunion/sinter/sdiff 并集/交集/差集
127.0.0.1:6379> sadd word1 a b c d 
(integer) 4
127.0.0.1:6379> sadd word2 a b 
(integer) 2
127.0.0.1:6379> sunion word1 word2
1) "b"
2) "d"
3) "c"
4) "a"
127.0.0.1:6379> sinter word1 word2
1) "a"
2) "b"

127.0.0.1:6379> sdiff word1 word2
1) "d"
2) "c"

应用场景

  • 抽奖(spop)
  • 点赞(sadd/srem ...)
  • 筛选,例如朋友相互关注,可能认识的人(交并差集)

1.5 Zset有序集合

有序去重的集合,每个元素拥有score
操作命令

  • zadd 批量设定score和memeber
127.0.0.1:6379> zadd exam 88 zhangsan 90 lisi 100 wangwu 98 zhaoliu
(integer) 4
  • zrange/zrevrange 按照分数从低/高-高/低,
127.0.0.1:6379> zrange exam  0 -1 
1) "zhangsan"
2) "lisi"
3) "zhaoliu"
4) "wangwu"
127.0.0.1:6379> zrange exam  0 -1 withscores //带上分数
1) "zhangsan"
2) "88"
3) "lisi"
4) "90"
5) "zhaoliu"
6) "98"
7) "wangwu"
8) "100"
127.0.0.1:6379> zrevrange exam  0 -1 withscores
1) "wangwu"
2) "100"
3) "zhaoliu"
4) "98"
5) "lisi"
6) "90"
7) "zhangsan"
8) "88"
  • zrangebyscore 分数区间查询
127.0.0.1:6379> zrangebyscore exam 90 100 
1) "lisi"
2) "zhaoliu"
3) "wangwu"
  • zrem 移除元素
127.0.0.1:6379> zrem exam zhangsan lisi
(integer) 1
127.0.0.1:6379> zrange exam  0 -1 
1) "zhaoliu"
2) "wangwu"
  • zincrby 分值递增
127.0.0.1:6379> zincrby exam 2 zhaoliu 
"100"
  • zcount 根据分值统计个数
127.0.0.1:6379> zcount exam 90 100
(integer) 2
  • zcard 统计元素个数
127.0.0.1:6379> zcard exam
(integer) 2
  • zrank 获取元素的rank
127.0.0.1:6379> zadd exam  88 zhangsan 90  lisi
(integer) 1
127.0.0.1:6379> zrank exam zhangsan
(integer) 0
127.0.0.1:6379> zrank exam lisi
(integer) 1
127.0.0.1:6379> zrank exam wangwu
(integer) 2

应用场景

  • 排行榜

2. 三种特殊数据类型

2.1 BitMap

基于String的位操作,一个比特位只有 0 和1两种状态

  • getbit 获取指定key对应offset的二进制值 给一个key设值为c,由于ASCII码为99,对应的二进制数为01100011
127.0.0.1:6379> set k1 c
OK
127.0.0.1:6379> getbit k1 0 //根据valueoffset取值,从左开始
(integer) 0
127.0.0.1:6379> getbit k1 1
(integer) 1
127.0.0.1:6379> getbit k1 2
(integer) 1
127.0.0.1:6379> getbit k1 3
(integer) 0 
  • setbit 设定指定key对应offset的数值
127.0.0.1:6379> setbit k1 5 1
(integer) 0
127.0.0.1:6379> get k1
"g"
  • bitcount 统计二进制1的个数
127.0.0.1:6379> bitcount k1
(integer) 5
  • bittpos 获取第一个0/1的位置
127.0.0.1:6379> bitpos k1 1
(integer) 1
127.0.0.1:6379> bitpos k1 0
(integer) 0

应用场景

  • 户访问统计
  • 用户统计

2.2 Hyperloglogs

提供了一种不太准确的基数(一组集合中不重复的元素数量)统计方法,比如统计网站的 UV,存在一定的误差

  • pfadd 添加元素
127.0.0.1:6379> pfadd myset a b c d e 
(integer) 1
  • pfcount 统计元素个数
127.0.0.1:6379> pfcount myset
(integer) 5
  • pfmerge 合并集合去重(相当于取并集)
127.0.0.1:6379> pfadd myset2 c d e f g
(integer) 1
127.0.0.1:6379> pfmerge set myset myset2
OK
127.0.0.1:6379> pfcount set
(integer) 7

2.3 geospatial

用于存储地理位置信息,并对存储的信息进行操作

  • geoadd:添加地理位置的坐标。
127.0.0.1:6379> geoadd china:city 116.23128 40.22077 beijing 121.48941 31.40527 shanghai 106.54041 29.40268 chongqin 120.21201 30.2084 hangzhou
(integer) 4
  • geopos:获取地理位置的坐标。
127.0.0.1:6379> geopos china:city beijing
 1) "116.23128265142440796"
 2) "40.22076905438526495"
  • geodist:计算两个位置之间的距离。
127.0.0.1:6379> geodist china:city beijing shanghai  //默认单位m
"1088644.3544"
127.0.0.1:6379> geodist china:city beijing shanghai km
"1088.6444" 
  • georadius:根据用户给定的经纬度坐标来获取指定范围内的地理位置集合
127.0.0.1:6379> georadius china:city 121 31 500 km 离这个经纬度半径 500KM距离的城市
1) "hangzhou"
2) "shanghai"
127.0.0.1:6379> georadius china:city 121 31 100 km
1) "shanghai
127.0.0.1:6379> georadius china:city 121 31 500 km withdist 显示距离
1) 1) "hangzhou"
   2) "115.9428"
2) 1) "shanghai"
   2) "64.8057"
127.0.0.1:6379> georadius china:city 121 31 500 km withcoord 显示将经纬度
1) 1) "hangzhou
   2) 1) "120.21200805902481079"
      2) "30.20839995425554747"
2) 1) "shanghai"
   2) 1) "121.48941010236740112"
      2) "31.40526993848380499"
127.0.0.1:6379> georadius china:city 121 31 500 km count 1 显示指定数量
1) "shanghai
  • georadiusbymember:根据储存在位置集合里面的某个地点获取指定范围内的地理位置集合
127.0.0.1:6379> georadiusbymember china:city shanghai 1300 km
1) "hangzhou"
2) "shanghai"
3) "beijing"
  • geohash:返回一个或多个位置对象的 geohash 值
127.0.0.1:6379> GEOHASH china:city beijing chongqin //经纬度的字符串
1) "wx4sucvncn0"
2) "wm5z22s7520"