Redis

关注公众号 jb51net

关闭
首页 > 数据库 > Redis > Redis 基本数据类型

Redis 8种基本数据类型及常用命令和数据类型的应用场景小结

作者:师小师

Redis是一种基于内存操作的数据库,其中多亏于高效的数据结构,本文主要介绍了Redis 8种基本数据类型及常用命令和数据类型的应用场景小结,具有一定的参考价值,感兴趣的可以了解一下

Redis 五大数据类型

redis 官方网张:https://redis.io/

redis 常用命令:https://www.redis.net.cn/order/

使用 SpringBoot。Jedis 连接的方法也是这些命令

key

# 验证 redis 服务密码
127.0.0.1:6379> auth 123456
# 查看 redis 节点信息
127.0.0.1:6379> info replication
# 测试是否连接 redis
127.0.0.1:6379> ping
# 查看所有的key
127.0.0.1:6379> keys * 
#关闭redis 
127.0.0.1:6379> shutdown
# 退出
127.0.0.1:6379> exit  
# 切换数据库
127.0.0.1:6379> select 3
# 查看DB大小
127.0.0.1:6379> DBSIZE  
# 清除当前数据库
127.0.0.1:6379> flushdb
# 清除全部数据库的内容
127.0.0.1:6379> flushall
# 判断当前的key是否存在
127.0.0.1:6379> exists name
127.0.0.1:6379> set name
# 移动key到第一个数据库
127.0.0.1:6379> move name 1
# 设置key的过期时间,单位是秒
127.0.0.1:6379> expite name 10
# 查看当前 key 的剩余时间
127.0.0.1:6379> ttl name  
# 查看当前key的一个类型
127.0.0.1:6379> type name

String

# 设置值
127.0.0.1:6379> set k1 v1  
# 获取值
127.0.0.1:6379> get k1  
# 获取所有的 key
127.0.0.1:6379> keys *
# 判断一个 key 是否存在
127.0.0.1:6379> exists k1
# 获取字符串的长度
127.0.0.1:6379> STRLEN key1
# 追加字符串,如果当前 key 不存在,就相当于set key
127.0.0.1:6379> APPEND k1 ",Hello"
# 初始浏览量为 0
127.0.0.1:6379> set views 0
# 自增1 浏览量变为1
127.0.0.1:6379> incr views
# 自减1  浏览量-1
127.0.0.1:6379> decr views
# 可以设置步长,指定增加10
127.0.0.1:6379> incrby views 10 
# 可以设置步长,指定减小10
127.0.0.1:6379> decrby views 10 
# 设置 k1 的值
127.0.0.1:6379> set k1 "hello,world"
# 截取字符串 [0,3]
127.0.0.1:6379> getrange k1 0 3
# 获取全部的字符串和 get key 是一样的
127.0.0.1:6379> getrange k1 0 -1
# 设置 k2 的值 "12345678"
127.0.0.1:6379> set k2 "12345678"
# 替换指定位置开始的字符串
127.0.0.1:6379> SETRANGE k2 1 xx

# setex (set with expire)  # 设置过期时间
# setnx (set if not exist)  # 不存在在设置 (在分布式锁中会常常使用!)
# 设置key3 的值为 hello,30秒后过期
127.0.0.1:6379> setex k3 30 "hello" 
# 查看 k3 过期时间
127.0.0.1:6379> ttl k3
# 如果 k3 不存在,创建 k3
127.0.0.1:6379> setnx k3 "haha"
# 清除当前数据库的所有 key
127.0.0.1:6379> flushdb
# 同时设置多个值
127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3  
# 同时获取多个值
127.0.0.1:6379> mget k1 k2 k3

# msetnx 是一个原子性的操作,要么一起成功,要么一起失败 结果返回 0
127.0.0.1:6379> msetnx k1 v1 k4 v4

# 对象 set user:1 {name:zhangsan,age:3}  设置一个user:1 对象值为 json 字符来保存一个对象
# 这里的key是一个巧妙的设计: user:{id}:{filed} , 如此设计在Redis中是完全OK了
127.0.0.1:6379> mset user:1:name zhangsan user:1:age 2
# 获取对象中的值
127.0.0.1:6379> mget user:1:name user:1:age

# getset  先get然后在set
# 如果不存在值,则返回 nil
127.0.0.1:6379> getset db redis
# 如果存在值,获取原来的值,并设置新的值
127.0.0.1:6379> getset db mongodb

String类似的使用场景:value 除了是字符串还可以是数字

List

基本的数据类型,列表,在redis里面,list 是一种比较灵活的链表数据结构,可以充当栈、队列、阻塞队列

list 列表是链表型的数据结构,所以它的元素是有序的,而且列表内的元素是可以重复的。意味着它可以根据链表的下标获取指定的元素和某个范围内的元素集。

# 将一个值或者多个值,插入到列表头部 (左)
127.0.0.1:6379> lpush list one
127.0.0.1:6379> lpush list one two three
# 获取 list 中的所有值
127.0.0.1:6379> lpush list 0 -1
# 通过区间获取具体的值
127.0.0.1:6379> lrange lisr 0 1
# 将一个值或者多个值,插入到列表位部 (右)
127.0.0.1:6379> rpush list righr

# 通过下标获得 list 中的某一个值
127.0.0.1:6379> lindex list 1
# 返回 list 列表的长度
127.0.0.1:6379> llen list

# 移除list的第一个元素
127.0.0.1:6379> lpop list
# 移除list的最后一个元素
127.0.0.1:6379> rpop list  
# 移除list集合中指定个数的value,精确匹配
127.0.0.1:6379> lrem list 1 one 


# trim 修剪 
# 新建一个 newlist 集合
127.0.0.1:6379> lpush newlist "hello" "hello1" "hello2" "hello3" "hello4"
# 通过下标截取指定的长度,这个list已经被改变了,截断了只剩下截取的元素
127.0.0.1:6379> ltrim newlist 1 2

# rpoplpush 移除列表的最后一个元素,将他移动到新的列表中
127.0.0.1:6379> rpush newlist "hello1"
# 移除列表的最后一个元素,将他移动到新的列表中
127.0.0.1:6379> rpoplpush another anotherlist
# 查看目标列表中,确实存在改值
127.0.0.1:6379> lrange anotherlist 0 -1 

# lset 将列表中指定下标的值替换为另外一个值,更新操作
127.0.0.1:6379> exists list
# 如果不存在列表更新机会报错,更新前先检查列表是否存在(0表示下表索引)
127.0.0.1:6379> lset list 0 item
# 如果下标不存在,则会报错
127.0.0.1:6379> lset list 10 other

# linsert 将某个具体的 value 插入到列表中某个元素的前面或者后面
127.0.0.1:6379> rpush list "hello"
127.0.0.1:6379> rpush list "world"
# 把 other 添加到 world 前面
127.0.0.1:6379> linsert list before "world" "other"
# 把 another 添加到 world 后面
127.0.0.1:6379> linsert list after "world" "another"

List 是一个链表,before , after , left,right 都可以插入值,在两边插入或者改动值,效率最高! 中间元素,相对来说效率会低一点

使用场景:

Set

Sets: 不重复且无序的字符串元素的集合。

set 类型是 string 类型的集合,其特点是集合元素无序且不重复,每个集合最多可以存储 232 - 1 个元素(40多亿)

所有的 set 命令都是 s 开始

# 清空当前数据库
127.0.0.1:6379> flushdb
# set 集合中添加几个值
127.0.0.1:6379> sadd myset "1"
127.0.0.1:6379> sadd myset "1" "2" "3" "4" "5" "6" "7" "8" "9" "0"
# 查看指定 set 的所有值
127.0.0.1:6379> smembers myset
# 判断某一个值是不是在 set 集合中
127.0.0.1:6379> sismember myset

# 获取 set 集合中的内容元素个数
127.0.0.1:6379> scard myset
# 移除 set 集合中的指定元素
127.0.0.1:6379> srem myset 3

# 随机抽选出一个元素,set 无序不重复集合。抽随机
127.0.0.1:6379> srandmember myset
# 随机抽取2个
127.0.0.1:6379> srandmember myset 2

# 随机删除 myset 中的值
127.0.0.1:6379> spop myset

# 将一个指定的值,移动到另外一个set集合
127.0.0.1:6379> sadd "hello"
127.0.0.1:6379> sadd "world"
127.0.0.1:6379> smove myset newset "hello"

# 数字集合类 - 差集 sdiff - 交集 sinter - 并集 sunion
127.0.0.1:6379> sadd key1 "a" "b" "c"
127.0.0.1:6379> sadd key2 "c" "e" "f"
# 差集—— key1 在 key2 中没有的值
127.0.0.1:6379> sdiff key1 key2
# 交集—— key1 和 key2 共同拥有的值
127.0.0.1:6379> sinter key1 key2
# 并集—— key1 和 key2 所有的值
127.0.0.1:6379> sunion key1 key2

Set使用场景:

Hash

Map集合,key-maps 时候这个值是一个map集合! 本质和String类型没有太大区别,还是一个简单的key-vlaue!

有点像 HashMap 的 value 又套了个HashMap

所有 hash 的命令都是 h 开头

# set一个具体 key-vlaue
127.0.0.1:6379> hset myhash field "hello
# 获取一个字段值
127.0.0.1:6379> hget myhash field
# set 多个 key-vlaue 返回 OK
127.0.0.1:6379> hmset myhash field1 "hello" field2 "world"
# set 多个 key-vlaue 返回成功的数量
127.0.0.1:6379> hset myhash field3 "hello" field4 "world"
# 获取多个字段值
127.0.0.1:6379> hmget myhash field1 field2
# 获取全部的数据
127.0.0.1:6379> hgetall myhash

# 获取hash表的字段数量
127.0.0.1:6379> hlen myhash
# 判断hash中指定字段是否存在
127.0.0.1:6379> hexists myhash field1

# 只获得所有 field
127.0.0.1:6379> hkeys myhash
# 只获得所有value
127.0.0.1:6379> hvals myhash

# 指定增量
127.0.0.1:6379> hset myhash field5 5
127.0.0.1:6379> hincrby myhash field5 5
127.0.0.1:6379> hincrby myhash field5 -2

# 如果不存在则可以设置,存在则不能设置
127.0.0.1:6379> hsetnx myhash field6 "hello"
# 删除指定的 field
127.0.0.1:6379>hdel myhash field

# 返回 hash 指定 field 的 value 的字符串长度,field 不存在返回 0
127.0.0.1:6379> hstrlen myhash field1

hash变更的数据 user name age,尤其是是用户信息之类的,经常变动的信息! hash 更适合于对象的存储,String更加适合字符串存储

购物车的实现:field (商品id),hincrby (商品数量,添加增量会返回总数),hdel(删除),hgetall(全选),hlen(购物车车数量),key(用户id)

Hash 结构优点:

缺点:

Sorted Set

Sorted-Set和Set类型极为相似,它们都是字符串的集合,都不允许重复的成员出现在一个Set中。它们之间的主要差别是Sorted-Set中的每一个成员都会有一个分数(score)与之关联,Redis正是通过分数来为集合中的成员进行从小到大的排序。然而需要额外指出的是,尽管Sorted-Set中的成员必须是唯一的,但是分数(score)却是可以重复的

在set的基础上,增加了一个值,set k1 v1 zset k1 score1 v1

# 添加一个值
127.0.0.1:6379> zadd myzset 1 one 
# 添加多个值
127.0.0.1:6379> zadd myzset 2 two 3 three
# zincrby 和 zadd 效果一样,最后返回结果是字符串,zadd 返回添加总数

# 查看添加的值
127.0.0.1:6379> zrange myzset 0 -1
127.0.0.1:6379> zrange myzset 0 -1 withscores

# 实现排序 添加三个用户
127.0.0.1:6379>	zadd salary 120 zhang 98 wang 110 li
# ZRANGEBYSCORE key min max   显示全部的用户 从小到大
127.0.0.1:6379>	zrangebyscore salary -inf +inf
# 从大到进行排序
127.0.0.1:6379>	zrevrange salary 0 -1
# 显示全部的用户并且附带成绩
127.0.0.1:6379>	zrangebyscore salary -inf +inf withscores
# 显示成绩小于 110 的所有人,升序排序
127.0.0.1:6379>	zrangebyscore salary -inf 110 withscores
# zrem 移除,移除有序集合中的指定元素
127.0.0.1:6379> zrem salary zhang

# 添加值
127.0.0.1:6379> zadd myzset 2 hello 3 world
# 有序集合的元素个数, key 不存在则返回0 
127.0.0.1:6379> zcard myzset
# 获取区间成员数量
127.0.0.1:6379> zcount myzset 1 3
# 计算成员之间的数量
127.0.0.1:6379> zlexcount myzset - +
127.0.0.1:6379> zlexcount myzset [b [f

# 删除一个 zset -> del myzset
127.0.0.1:6379> del myzset

ZSet 数据类型使用场景:游戏排名、微博热点话题,根据时间排序的新闻列表, 阅读排行榜,延时队列等

限流,滑动窗口是限流常见的一种策略。如果我们把一个用户的 ID 作为 key 来定义一个 zset ,member 或者 score 可以都为访问时的时间戳。我们只需统计某个 key 下在指定时间戳区间内的个数,就能得到这个用户滑动窗口内访问频次,与最大通过次数比较,来决定是否允许通过。

三种特殊类型

Geospatial 地理位置

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

常用命令:

命令描述
Redis GEOHASH 命令返回一个或多个位置元素的 Geohash 表示
Redis GEOPOS 命令从key里返回所有给定位置元素的位置(经度和纬度)
Redis GEODIST 命令返回两个给定位置之间的距离
Redis GEORADIUS 命令以给定的经纬度为中心, 找出某一半径内的元素
Redis GEOADD 命令将指定的地理空间位置(纬度、经度、名称)添加到指定的key中
Redis GEORADIUSBYMEMBER 命令找出位于指定范围内的元素,中心点是由给定的位置元素决定

使用场景:

例如:微信位置共享,附近的人等地图功能

redis 127.0.0.1:6379>  GEOADD Sicily 13.361389 38.115556 "beijing" 15.087269 37.502669 "shanghai"
(integer) 2
redis 127.0.0.1:6379>  GEODIST Sicily beijing shanghai
"166274.15156960039"
redis 127.0.0.1:6379>  GEORADIUS Sicily 15 37 100 km
1) "shanghai"
redis 127.0.0.1:6379>  GEORADIUS Sicily 15 37 200 km
1) "beijing"
2) "shanghai"

Hyperloglog

使用场景:

统计注册的IP数,每日访问数,每天在线人数,搜索词条数等类似场景

命令描述
Redis Pgmerge 命令将多个 HyperLogLog 合并为一个 HyperLogLog
Redis Pfadd 命令添加指定元素到 HyperLogLog 中。
Redis Pfcount 命令返回给定 HyperLogLog 的基数估算值。

示例1:

redis 127.0.0.1:6379> PFADD mykey a b c d e f g h i j
(integer) 1
redis 127.0.0.1:6379> PFCOUNT mykey
(integer) 10

示例2:

redis 127.0.0.1:6379> PFADD hll1 foo bar zap a
(integer) 1
redis 127.0.0.1:6379> PFADD hll2 a b c foo
(integer) 1
redis 127.0.0.1:6379> PFMERGE hll3 hll1 hll2
OK
redis 127.0.0.1:6379> PFCOUNT hll3
(integer) 6

Bitmap

使用场景:

统计用户信息、活跃、不活跃、 登录 、 未登录、打卡、365打卡! 两个状态的,都可以使用 Bitmaps!

Bitmap 位图,数据结构,都是操作二进制位来进行记录,就只有0 和 1 两个状态!

365 天 = 365 bit 1字节 = 8bit 46 个字节左右!

# 使用 bitmap 记录周一到周日打卡
127.0.0.1:6379> setbit sign 0 1
127.0.0.1:6379> setbit sign 1 1
127.0.0.1:6379> setbit sign 2 1
127.0.0.1:6379> setbit sign 3 0
127.0.0.1:6379> setbit sign 4 1
127.0.0.1:6379> setbit sign 5 1
127.0.0.1:6379> setbit sign 6 1
# 查看那一天是否打卡
127.0.0.1:6379> getbit sign 3
127.0.0.1:6379> getbit sign 4

# 统计这周的打卡记录,就可以看到是否有全勤
127.0.0.1:6379> bitcount sign

到此这篇关于Redis 8种基本数据类型及常用命令和数据类型的应用场景小结的文章就介绍到这了,更多相关Redis 基本数据类型内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家! 

您可能感兴趣的文章:
阅读全文