Redis八种数据类型
五大基本数据类型
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 地理位置
将指定的地理空间位置(纬度、经度、名称)添加到指定的
key
中。这些数据将会存储到sorted set
,这样的目的是为了方便使用GEORADIUS或者GEORADIUSBYMEMBER命令对数据进行半径查询等操作。该命令以采用标准格式的参数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>
#########################################################################################################