Redis八种数据类型

lijunyi2022-07-21Redis缓存框架

五大基本数据类型

String类型

1、常规命令

127.0.0.1:6379> set key1 wao  # 设置值
OK
127.0.0.1:6379> APPEND key1 "manwei"  # 追加字符串,如果当前key不存在,就相当于 set key
(integer) 9
127.0.0.1:6379> get key1
"waomanwei"
127.0.0.1:6379> STRLEN key1  # 获取字符串的长度
(integer) 9
127.0.0.1:6379> APPEND key1 ",zhizhuxia"
(integer) 19
127.0.0.1:6379> get key1
"waomanwei,zhizhuxia"
127.0.0.1:6379> 

2、自增与自减

  • 适用于博文浏览量这种场景
127.0.0.1:6379> set views 0 # 初始浏览量为0
OK
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> INCRBY views 10 #可以设置步长,指定增量!
(integer) 11
127.0.0.1:6379> DECRBY views 10
(integer) 1
127.0.0.1:6379> 

3、截取与替换

# 字符串范围  range
127.0.0.1:6379> set key1 "hello,wangwu"  # 设置key的值
OK
127.0.0.1:6379> GETRANGE key1 0 4    # 截取字符串 [0,3]
"hello"
127.0.0.1:6379> GETRANGE key1 0 -1   # 截取全部字符串
"hello,wangwu"
127.0.0.1:6379> 

# 替换
127.0.0.1:6379> set key abcfdhge
OK
127.0.0.1:6379> SETRANGE key 1 xxx   #替换指定位置开始的字符串!
(integer) 8
127.0.0.1:6379> get key
"axxxdhge"
127.0.0.1:6379> 

4、设置过期时间

# setex  (set with expire)   #设置过期时间
# setnx  (set if not exist)  #不存在再设置 (在分布式锁中会常常使用!保证当前的值是存在的)
127.0.0.1:6379> setex k1 30 "hello"  #设置 k1 的值,30s 过期
OK
127.0.0.1:6379> ttl k1
(integer) 25
127.0.0.1:6379> setnx k2 "redis" # 如果 k2 不存在,创建 k2
(integer) 1
127.0.0.1:6379> keys *
1) "k2"
127.0.0.1:6379> get k2
"redis"
127.0.0.1:6379> setnx k2 "mongoDB"  #如果 k2 存在,创建失败
(integer) 0
127.0.0.1:6379> get k2
"redis"
127.0.0.1:6379> 

5、批量设置-获取值

#  批量设置/获取值
# mset 
# mget 
127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3  # 批量设置  
OK
127.0.0.1:6379> keys *
1) "k1"
2) "k2"
3) "k3"
127.0.0.1:6379> mget k1 k2 k3  # 批量获取
1) "v1"
2) "v2"
3) "v3"

# msetnx 是一个原子性操作  k1已经存在,创建k1失败,则k4也无法创建
127.0.0.1:6379> msetnx k1 v1 k4 v4 
(integer) 0
127.0.0.1:6379> 

6、设置对象

# 设置一个user : 1 对象值为json字符来保存一个对象!
# set user:1 {name :zhangsan , age: 3} 
# key的设计: user:{id}:{filed}

127.0.0.1:6379> mset user:1:name zhangsan user:1:age 20
OK
127.0.0.1:6379> mget user:1:name user:1:age
1) "zhangsan"
2) "20"
127.0.0.1:6379> 

7、getset命令

# getset命令  先get再set
127.0.0.1:6379> getset db redis      #如果不存在值,则返回 nil
(nil)
127.0.0.1:6379> get db
"redis"
127.0.0.1:6379> getset db monggodb   #如果存在值,获取原来的值,并设置新的值
"redis"
127.0.0.1:6379> get db
"monggodb"
127.0.0.1:6379> 

List类型

  • 所有的list命令都是用I开头的,Redis不区分大小命令
127.0.0.1:6379> LPUSH list 1       #将一个值或者多个值,插入到列表头部(左)
(integer) 1
127.0.0.1:6379> LPUSH list 2
(integer) 2
127.0.0.1:6379> LPUSH list 33
(integer) 3
127.0.0.1:6379> LRANGE list 0 -1   #获取1ist中值!
1) "33"
2) "2"
3) "1"
127.0.0.1:6379> RPUSH list 99      #将一个值或者多个值,插入到列表位部(右)
(integer) 4
127.0.0.1:6379> LRANGE list 0 -1
1) "33"
2) "2"
3) "1"
4) "99"
127.0.0.1:6379> 
#########################################################################################################
# 移除命令  LPOL   RPOP
127.0.0.1:6379> LRANGE list 0 -1
1) "33"
2) "2"
3) "1"
4) "99"
127.0.0.1:6379> LPOP list   #移除list的第一个元素
"33"
127.0.0.1:6379> RPOP list   #移除list的最后一个元素
"99"
127.0.0.1:6379> 
#########################################################################################################
# 获取指定下标的值  Lindex
127.0.0.1:6379> LINDEX list 0   #通过下标获得list中的某一个值!
"2"
127.0.0.1:6379> LINDEX list 1
"1"
127.0.0.1:6379> 
#########################################################################################################
# 获取list长度  Llen
127.0.0.1:6379> LLEN list  #返回列表的长度
(integer) 2
127.0.0.1:6379> 
#########################################################################################################
# 移除指定值  LREM KEY COUNT VALUE
127.0.0.1:6379> LRANGE list 0 -1
1) "2"
2) "1"
127.0.0.1:6379> LPUSH list 1
(integer) 3
127.0.0.1:6379> LRANGE list 0 -1
1) "1"
2) "2"
3) "1"
127.0.0.1:6379> LREM list 1 1   #移除list集合中指定个数的value,精确匹配
(integer) 1
127.0.0.1:6379> LRANGE list 0 -1
1) "2"
2) "1"
127.0.0.1:6379> 
#########################################################################################################
# trim 修剪  截取list指定范围
127.0.0.1:6379> LPUSH list "hello"
(integer) 1
127.0.0.1:6379> LPUSH list "hello1"
(integer) 2
127.0.0.1:6379> LPUSH list "hello2"
(integer) 3
127.0.0.1:6379> LPUSH list "hello3"
(integer) 4
127.0.0.1:6379> LRANGE list 0 -1
1) "hello3"
2) "hello2"
3) "hello1"
4) "hello"
127.0.0.1:6379> LTRIM list 1 2     # 通过下标截取指定的长度,这个1ist已经被改变了,截断了只剩下截取的元素!
OK
127.0.0.1:6379> LRANGE list 0 -1
1) "hello2"
2) "hello1"
127.0.0.1:6379> 
#########################################################################################################
# RPOPLPUSH   移除列表的最后一个元素,将他移动到新的列表中!
127.0.0.1:6379> LRANGE list 0 -1
1) "hello3"
2) "hello2"
3) "hello1"
127.0.0.1:6379> RPOPLPUSH list mylist  #移除列表的最后一个元素,将他移动到新的列表中!
"hello1"
127.0.0.1:6379> LRANGE list 0 -1       #查看原来的列表
1) "hello3"
2) "hello2"
127.0.0.1:6379> LRANGE mylist 0 -1     #查看目标列表中,确实存在该值!
1) "hello1"
127.0.0.1:6379> 
#########################################################################################################
# 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 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 other    # 如果不存在列表 则会报错
(error) ERR index out of range
127.0.0.1:6379> 
#########################################################################################################
# linsert 将某个具体的value插入到列表中某个元素的前面或者后面

127.0.0.1:6379> RPUSH mylist hello
(integer) 1
127.0.0.1:6379> RPUSH mylist word
(integer) 2
127.0.0.1:6379> LINSERT mylist before "word" "other"
(integer) 3
127.0.0.1:6379> LRANGE mylist 0 -1
1) "hello"
2) "other"
3) "word"
127.0.0.1:6379> LINSERT mylist after "word" "beijing"
(integer) 4
127.0.0.1:6379> LRANGE mylist 0 -1
1) "hello"
2) "other"
3) "word"
4) "beijing"
127.0.0.1:6379> 

Set类型

  • set中的值 不能重复。
  • 命令开头都是s
127.0.0.1:6379> sadd myset hello     # set集合中添加元素
(integer) 1
127.0.0.1:6379> sadd myset wangwu
(integer) 1
127.0.0.1:6379> sadd myset layui
(integer) 1
127.0.0.1:6379> SMEMBERS myset      # 查看指定set的所有值
1) "layui"
2) "wangwu"
3) "hello"
127.0.0.1:6379> SISMEMBER myset hello  # 判断某一个值是不是在set集合中
(integer) 1
127.0.0.1:6379> SISMEMBER myset word
(integer) 0
127.0.0.1:6379> 
#########################################################################################################
# SCARD  获取set集合中的内容元素个数
127.0.0.1:6379> SCARD myset
(integer) 3
#########################################################################################################
127.0.0.1:6379> SREM myset hello   # 移除set集合中的指定元素
(integer) 1
127.0.0.1:6379> SCARD myset
(integer) 3
127.0.0.1:6379> SMEMBERS myset
1) "layui"
2) "wangwu"
3) "vue"
#########################################################################################################
#  set  无序不重复集合
127.0.0.1:6379> SRANDMEMBER myset   # 随机抽选出一个元素
"layui"
127.0.0.1:6379> SRANDMEMBER myset
"layui"
127.0.0.1:6379> SRANDMEMBER myset
"vue"
127.0.0.1:6379> SRANDMEMBER myset 2  # 随机抽选出指定个数的元素
1) "layui"
2) "wangwu"
127.0.0.1:6379> 
#########################################################################################################
# 删除指定的key,随机删除key
127.0.0.1:6379> SMEMBERS myset
1) "layui"
2) "wangwu"
3) "vue"
127.0.0.1:6379> spop myset      # 随机删除一些set集合中的元素
"vue"
127.0.0.1:6379> spop myset
"layui"
127.0.0.1:6379> SMEMBERS myset
1) "wangwu"
127.0.0.1:6379> 
#########################################################################################################
# 将一个指定的值移动到另外一个set集合中
127.0.0.1:6379> sadd myset hello
(integer) 1
127.0.0.1:6379> sadd myset layui
(integer) 1
127.0.0.1:6379> sadd myset vue
(integer) 1
127.0.0.1:6379> sadd myset2 set2
(integer) 1
127.0.0.1:6379> SMOVE myset myset2 vue   # 将一个指定的值移动到另外一个set集合中
(integer) 1
127.0.0.1:6379> SMEMBERS myset
1) "layui"
2) "hello"
127.0.0.1:6379> SMEMBERS myset2
1) "vue"
2) "set2"
127.0.0.1:6379> 
#########################################################################################################
# weibo  B站共同关注(并集)
# 数字集合类
#    - 差集  SDIFF
#    - 交集  SINTER
#    - 并集  SUNION
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 d
(integer) 1
127.0.0.1:6379> sadd key2 e
(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) "b"
2) "c"
3) "a"
4) "d"
5) "e"
127.0.0.1:6379> 

Hash类型

  • 哈希,可以看成一个Map集合 key-Map
  • 命令都是以H开头
  • 更适合存储对象
127.0.0.1:6379> hset myhash name layui        # set一个具体的key-value
(integer) 1
127.0.0.1:6379> hget myhash name               # 获取一个字段值
"layui"
127.0.0.1:6379> HMSET myhash name vue age 20  # set 多个具体的key-value
OK
127.0.0.1:6379> HMGET myhash name age         # 获取多个字段值
1) "vue"
2) "20"
127.0.0.1:6379> HGETALL myhash                 # 获取全部数据,展示形式以k-v展示
1) "name"
2) "vue"
3) "age"
4) "20"
#########################################################################################################
127.0.0.1:6379> hdel myhash name  # 删除hash指定的key字段,对应的value值也就消失了
(integer) 1
127.0.0.1:6379> HGETALL myhash
1) "age"
2) "20"
127.0.0.1:6379> 
#########################################################################################################
127.0.0.1:6379> HLEN myhash   # 获取hash表的字段数量
(integer) 1
127.0.0.1:6379> HMSET myhash name layui sex n
OK
127.0.0.1:6379> HGETALL myhash
1) "age"
2) "20"
3) "name"
4) "layui"
5) "sex"
6) "n"
127.0.0.1:6379> HLEN myhash
(integer) 3
#########################################################################################################
127.0.0.1:6379> HEXISTS myhash name   # 判断hash中的指定字段是否存在
(integer) 1
127.0.0.1:6379> HEXISTS myhash w
(integer) 0
#########################################################################################################
127.0.0.1:6379> HKEYS myhash   # 获取所有的key
1) "age"
2) "name"
3) "sex"
127.0.0.1:6379> HVALS myhash  # 获取所有的value
1) "20"
2) "layui"
3) "n"
#########################################################################################################
127.0.0.1:6379> HSET myhash num 5    # 指定增量 
(integer) 1
127.0.0.1:6379> HINCRBY myhash num 1
(integer) 6
127.0.0.1:6379> HINCRBY myhash num -1
(integer) 5
127.0.0.1:6379> HSETNX myhash num 10  # 如果不存在 则可以设置  如果存在  则不能设置
(integer) 0
127.0.0.1:6379> 

ZSet类型

  • 有序集合,在set的基础上增加了一个值(score)
127.0.0.1:6379> ZADD myset 1 one  # 添加一个值
(integer) 1
127.0.0.1:6379> ZADD myset 2 two
(integer) 1
127.0.0.1:6379> ZADD myset 3 three
(integer) 1
127.0.0.1:6379> ZRANGE myset 0 -1
1) "one"
2) "two"
3) "three"
#########################################################################################################
# 排序
127.0.0.1:6379> zadd salary 2500 xiaohong # 添加三个用户以及薪水
(integer) 1
127.0.0.1:6379> zadd salary 5000 zhangsan
(integer) 1
127.0.0.1:6379> zadd salary 200 xianxin
(integer) 1
#ZRANGEBYSCORE key min max
127.0.0.1:6379> ZRANGEBYSCORE salary -inf +inf  # 显示所有用户,从小到大排序
1) "xianxin"
2) "xiaohong"
3) "zhangsan"
127.0.0.1:6379> ZREVRANGE salary 0 -1  # 显示所有用户,从大到小排序
1) "zhangsan"
2) "xianxin"
127.0.0.1:6379> 
127.0.0.1:6379> ZRANGEBYSCORE salary -inf +inf withscores # 显示全部的用户并且附带成绩
1) "xianxin"
2) "200"
3) "xiaohong"
4) "2500"
5) "zhangsan"
6) "5000"
#########################################################################################################
#移除元素  ZREM
127.0.0.1:6379> zrange salary 0 -1
1) "xianxin"
2) "xiaohong"
3) "zhangsan"
127.0.0.1:6379> ZREM salary xiaohong  #移除有序集合中的指定元素
(integer) 1
127.0.0.1:6379> zrange salary 0 -1
1) "xianxin"
2) "zhangsan"
127.0.0.1:6379> ZCARD salary  # 获取有序集合中的个数
(integer) 2
127.0.0.1:6379> 
#########################################################################################################
#按区间计算
127.0.0.1:6379> ZCOUNT salary 1000 5000  # 获取指定区间的成员数量
(integer) 1

三种特殊数据类型

Bitmaps

  • 位存储

  • 统计用户信息:[登录、未登录]、[打卡、未打卡],这种两个状态的场景,都可以使用Bitmaps

  • Bitmaps就只有0和1两个状态

# 例如 使用bitmap记录周一到周日的打卡

127.0.0.1:6379> SETBIT sign 0 1
(integer) 0
127.0.0.1:6379> SETBIT sign 1 0
(integer) 0
127.0.0.1:6379> SETBIT sign 2 0
(integer) 0
127.0.0.1:6379> SETBIT sign 3 1
(integer) 0
127.0.0.1:6379> SETBIT sign 4 1
(integer) 0
127.0.0.1:6379> SETBIT sign 5 0
(integer) 0
127.0.0.1:6379> SETBIT sign 6 0
(integer) 0
127.0.0.1:6379> GETBIT sign 6  # 查询某天是否打卡
(integer) 0
127.0.0.1:6379> GETBIT sign 3
(integer) 1
127.0.0.1:6379> BITCOUNT sign  # 统计打卡记录
(integer) 3
127.0.0.1:6379> 

HyperLogLog

  • 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。

  • 在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。

  • 但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。

什么是基数?

比如数据集 {1, 3, 5, 7, 5, 7, 8}, 那么这个数据集的基数集为 {1, 3, 5 ,7, 8}, 基数(不重复元素)为5。 基数估计就是在误差可接受的范围内,快速计算基数。

127.0.0.1:6379> PFADD mykey a b c d e f g h i j  # 创建第一组元素
(integer) 1
127.0.0.1:6379> PFCOUNT mykey    # 统计 mykey 元素的基数数量
(integer) 10
127.0.0.1:6379> PFADD mykey2 i j z x c v b n m
(integer) 1
127.0.0.1:6379> PFCOUNT mykey2
(integer) 9
127.0.0.1:6379> PFMERGE mykey3 mykey mykey2  # 合并两组 mykey  mykey2 => mykey3 并集
OK
127.0.0.1:6379> PFCOUNT mykey3   # 查看并集的数量
(integer) 15
127.0.0.1:6379> 
  • 如果允许容错,那么一定可以使用Hyperloglog !
  • 如果不允许容错,就使用set或者自己的数据类型即可!

geospatial 地理位置

官方文档open in new window

  • 将指定的地理空间位置(纬度、经度、名称)添加到指定的key中。这些数据将会存储到sorted set,这样的目的是为了方便使用GEORADIUSopen in new window或者GEORADIUSBYMEMBERopen in new window命令对数据进行半径查询等操作。

  • 该命令以采用标准格式的参数x,y,所以经度必须在纬度之前。这些坐标的限制是可以被编入索引的,区域面积可以很接近极点但是不能索引。具体的限制,由EPSG:900913 / EPSG:3785 / OSGEO:41001 规定如下:

    有效的经度从 -180度 到 180度。
    
    有效的纬度从 -85.05112878度 到 85.05112878度。
    
  • 当坐标位置超出上述指定范围时,该命令将会返回一个错误。

  • 规则:两级无法直接添加,我们一般会下载城市数据,直接通过java程序一次性导入!

  • 参数key值:纬度、经度、名称

127.0.0.1:6379> GEOADD china:city 116.40 39.90 beijing
(integer) 1
127.0.0.1:6379> GEOADD china:city 121.47 31.23 shanghai
(integer) 1
127.0.0.1:6379> GEOADD china:city 106.50 29.53 chongqin 114.05 22.52 shenzhen
(integer) 2
127.0.0.1:6379> 
#########################################################################################################
127.0.0.1:6379> GEOPOS china:city beijing   #获取指定的城市的经度和纬度!
1) 1) "116.39999896287918091"
   2) "39.90000009167092543"
127.0.0.1:6379> GEOPOS china:city shanghai
1) 1) "121.47000163793563843"
   2) "31.22999903975783553"
127.0.0.1:6379> 
#########################################################################################################
#指定单位的参数 unit 必须是以下单位的其中一个:
#   m 表示单位为米。
#   km 表示单位为千米。
#   mi 表示单位为英里。
#   ft 表示单位为英尺。
#如果用户没有显式地指定单位参数, 那么 GEODIST 默认使用米作为单位。
#GEODIST 命令在计算距离时会假设地球为完美的球形, 在极限情况下, 这一假设最大会造成 0.5% 的误差。
127.0.0.1:6379> GEODIST china:city beijing shanghai
"1067378.7564"
127.0.0.1:6379> GEODIST china:city beijing shanghai km
"1067.3788"
127.0.0.1:6379> 
#########################################################################################################
# 获取附近的人,通过半径查询
127.0.0.1:6379> GEORADIUS china:city 110 30 1000 km  #以110,30这个经纬度为中心,寻找方圆1000km内的城市
1) "chongqin"
2) "shenzhen"
127.0.0.1:6379> GEORADIUS china:city 110 30 500 km
1) "chongqin"
127.0.0.1:6379> GEORADIUS china:city 110 30 500 km withdist # 显示到中心距离
1) 1) "chongqin"
   2) "341.9374"
127.0.0.1:6379> GEORADIUS china:city 110 30 500 km withcoord # 显示他人的定位信息
1) 1) "chongqin"
   2) 1) "106.49999767541885376"
      2) "29.52999957900659211"
127.0.0.1:6379> GEORADIUS china:city 110 30 1000 km withcoord count 1 # 筛选指定的结果
1) 1) "chongqin"
   2) 1) "106.49999767541885376"
      2) "29.52999957900659211"
127.0.0.1:6379> GEORADIUS china:city 110 30 1000 km withcoord count 2
1) 1) "chongqin"
   2) 1) "106.49999767541885376"
      2) "29.52999957900659211"
2) 1) "shenzhen"
   2) 1) "114.04999762773513794"
      2) "22.5200000879503861"
127.0.0.1:6379> 
#########################################################################################################
# 找出位于指定元素周围的其他元素!
127.0.0.1:6379> GEORADIUSBYMEMBER china:city beijing 1000 km
1) "beijing"
127.0.0.1:6379> 
#########################################################################################################
Last Updated 6/14/2024, 3:05:31 AM