Redis的8种数据类型及其适用场景

Redis是一个KV存储系统,使用C语言编写的。我们的key是字符串类型,是唯一的,value的数据类型如下

5种常用的

String字符串类型

list列表类型

set集合类型

sortedset(zset)有序集合类型

hash类型

2种不常用的

bitmap位图类型

geo地理位置类型

1种redis5.0新增的

stream类型

既然key是字符串类型,那么key有没有一些约定俗成的一些规则,或者说一些建议的规则呢?

redis key如何设计?

一般使用冒号分隔

一般会把表名或者表名的缩写作为key的前缀

比如:认证系统的用户表的id为001的key, auth:user:001

命名要具有一定的识别性,一看就知道是什么意思

key要尽量短一点,短key的效率比长key好一些,后面会讲到

1、String字符串

Redis的string能存储3种值的类型:字符串,整数,浮点数

1.1、应用场景

key和value都是字符串类型的应用场景极为广泛

普通的赋值操作

所有的kv存储都可以转换为value为字符串的存储,通过序列化转string,或者普通类型转string. 所以这种场景是最多的。

incr可以加上watch监听,实现乐观锁

incr实现的是数字递增

setnx可以实现分布式锁

value不存在时,可以用于分布式锁,最终可以一个会设置成功,设置成功的就是抢到锁资源的

1.2、String字符串类型命令

命令行罗列

命令帮助描述

setset key value赋值

getget key取值

getsetgetset key value取值赋值

setnxsetnx key value当key不存在时才赋值成功,存在时赋值失败 set key value NX PX 3000 原子操作,可用于分布式锁,px 设置毫秒数

appendappend key value向尾部追加值

strlenstrlen key获取字符串长度

incrincr key递增数字

incrbyincrby key increment增加指定的整数

decrdecr key递减数字

decrbydecrby key decrement减少指定的整数

命令行实际操作

127.0.0.1:6379> set name zhangsan

OK

127.0.0.1:6379> get name

"zhangsan"

127.0.0.1:6379> getset age 20

(nil)

127.0.0.1:6379> get age

"20"

127.0.0.1:6379> setnx lock_01 1001

(integer) 1

127.0.0.1:6379> setnx lock_01 1001

(integer) 0

127.0.0.1:6379> setnx lock_01 1002

(integer) 0

127.0.0.1:6379> append name 1

(integer) 9

127.0.0.1:6379> get name

"zhangsan1"

127.0.0.1:6379> strlen name

(integer) 9

127.0.0.1:6379> incr myid

(integer) 1

127.0.0.1:6379> incrby myid 2

(integer) 3

127.0.0.1:6379> decr myid

(integer) 2

127.0.0.1:6379> decrby myid 2

(integer) 0

# 设置分布式锁后的值,有效期20s

127.0.0.1:6379> set lock_02 1002 NX PX 30000 

OK

# 30s内重新设置值失败

127.0.0.1:6379> set lock_02 1002 NX

(nil)

# 30s内获取值成功

127.0.0.1:6379> get lock_02

"1002"

# 30s后获取值为空

127.0.0.1:6379> get lock_02

(nil)

# 重新设置值成功

127.0.0.1:6379> set lock_02 1003 NX PX 30000

OK

127.0.0.1:6379> get lock_02

"1003"

127.0.0.1:6379>

2、list列表

2.1、应用场景

list列表可以存储有序并且可以重复的元素。

获取头部或尾部的数据极快

列表最多存储2^32 -1个元素,大概40亿

看下面的命令,我们就知道这是一个双向列表。左进右出可以作为队列,左进左出可以作为栈使用。其实就是先进先出队列,后进先出为栈。

可以存储各种各样的列表数据。比如用户列表

2.2、list列表命令

命令罗列

命令帮助描述

lpushlpush key v1 v2 n3 ... vn从左侧插入列表

lpoplpop key从列表左侧取出

rpushrpush key v1 v2 n3 ... vn从右侧插入列表

rpoprpop key从列表右侧取出

lpushxlpushx key value将值插入到列表头部

rpushxrpushx key value将值插入到列表尾部

blpopblpop key timeout从列表左侧取出,如果为空阻塞,timeout最大阻塞时间(s)

brpopbrpop key timeout从列表右侧取出,如果为空阻塞,timeout最大阻塞时间(s)

llenllen key获得列表中元素个数

lindexlindex key index获得列表中下标为index的元素 index从0开始

lrangelrange key start end返回列表中指定区间的元素,区间通过start和end指定

lremlrem key count value删除列表中与value相等的元素 当count>0时, lrem会从列表左边开始删除;当count<0时, lrem会从列表后边开始删除;当count=0时, lrem删除所有值为value的元素

lsetlset key index value将列表index位置的元素设置成value的值

ltrimltrim key start end对列表进行修剪,只保留start到end区间

rpoplpushrpoplpush key1 key2从key1列表右侧弹出并插入到key2列表左侧

brpoplpushbrpoplpush key1 key2从key1列表右侧弹出并插入到key2列表左侧,会阻塞

linsertlinsert key BEFORE/AFTER pivot value将value插入到列表,且位于值pivot之前或之后

命令执行

127.0.0.1:6379> lpush name2 zhangsan lisi wangwu

(integer) 3

127.0.0.1:6379> lpop name2

"wangwu"

127.0.0.1:6379> rpush name3 zhangsan lisi wangwu

(integer) 3

127.0.0.1:6379> rpop name3

"wangwu"

127.0.0.1:6379> lpushx name2 niuqi

(integer) 3

127.0.0.1:6379> lrange name2 0 5

1) "niuqi"

2) "lisi"

3) "zhangsan"

127.0.0.1:6379> rpushx name3 niuqi

(integer) 3

127.0.0.1:6379> lrange name3 0 5

1) "zhangsan"

2) "lisi"

3) "niuqi"

127.0.0.1:6379> blpop name2 1

1) "name2"

2) "niuqi"

127.0.0.1:6379> brpop name3 1

1) "name3"

2) "niuqi"

127.0.0.1:6379> llen name2

(integer) 2

127.0.0.1:6379> lindex name2 0

"lisi"

127.0.0.1:6379> lindex name2 1

"zhangsan"

3、set集合

3.1、应用场景

Set集合,就是表示value唯一,并且无需的集合。

存储各种不需要顺序的数据集合。比如用户随机随机抽奖

3.2、Set集合命令

命令罗列

命令帮助描述

saddsadd key v1 v2 n3 ... vn为集合添加新成员

sremsrem key mem1 mem2 ...memn删除集合中指定成员

smembersrsmembers key从获得集合中所有元素

spopspop key返回集合中一个随机元素,并将该元素删除

srandmembersrandmember key将返回集合中一个随机元素,不会删除该元素

scardscard key获得集合中元素的数量

sismembersismember key member判断元素是否在集合内

sintersinter key1 key2 key3求多集合的交集

sdiffsdiffff key1 key2 key3求多集合的差集

sunionsunion key1 key2 key3求多集合的并集

命令操作

127.0.0.1:6379> sadd name4 zhangsan lisi wangwu

(integer) 3

127.0.0.1:6379> srem zhangsan

(error) ERR wrong number of arguments for 'srem' command

127.0.0.1:6379> srem name4 zhangsan

(integer) 1

127.0.0.1:6379> smembers name4

1) "lisi"

2) "wangwu"

127.0.0.1:6379> spop name4

"lisi"

127.0.0.1:6379> srandmember name4

"wangwu"

127.0.0.1:6379> scard name4

(integer) 1

127.0.0.1:6379> sismember name4 wangwu

(integer) 1

127.0.0.1:6379> sismember name4 wangwu

(integer) 1

# 定义两个集合 求交集,差集,并集

127.0.0.1:6379> sadd name5 zhangsan lisi

(integer) 2

127.0.0.1:6379> sadd name6 lisi wangwu

(integer) 2

127.0.0.1:6379> sinter name5 name6

1) "lisi"

127.0.0.1:6379> sdiff name5 name6

1) "zhangsan"

127.0.0.1:6379> sunion name5 name6

1) "lisi"

2) "wangwu"

3) "zhangsan"

4、sortedset有序集合(zset)

4.1、应用场景

sortedset是一个有序集合,元素本身跟set一样,是不重复的,为每一个元素添加了一个分数(score)根据分数的不同可以进行排序。分数可以重复。

有序列表被广泛使用在各种排行榜业务上:比如销量排行,用户点击率排行等

4.2、sortedset命令

命令罗列

命令帮助描述

zaddzadd key score1 v1 score2 v2 score1v3 ... scoren vn为有序集合添加新成员

zremzrem key mem1 mem2 ...memn删除有序集合中指定成员

zcardzcard key获得有序集合中的元素数量

zcountzcount key min max返回集合中score值在[min,max]区间的元素数量

zincrbyzincrby key increment member在集合的member分值上加increment

zscorezscore key member获得集合中member的分值

zrankzrank key member获得集合中member的排名(按分值从小到大)

zrevrankzrevrank key member获得集合中member的排名(按分值从大到小)

zrangezrange key start end获得集合中指定区间成员,按分数递增排序

zrevrangezrevrange key start end获得集合中指定区间成员,按分数递减排序

命令操作

127.0.0.1:6379> zadd test:001 20 zhangsan 50 lisi 30 wangwu 90 niuqi 

(integer) 4

127.0.0.1:6379> zcount test:001 0 2

(integer) 0

127.0.0.1:6379> zcount test:001 20 30

(integer) 2

127.0.0.1:6379> zcard test:001

(integer) 4

127.0.0.1:6379> zrem test:001 wangwu

(integer) 1

127.0.0.1:6379> zincrby test:001 10 zhangsan

"30"

127.0.0.1:6379> zscore test:001 zhangsan

"30"

127.0.0.1:6379> zrank test:001 zhangsan

(integer) 0

127.0.0.1:6379> zrank test:001 niuqi

(integer) 2

127.0.0.1:6379> zrevrank test:001 niuqi

(integer) 0

127.0.0.1:6379> zrevrank test:001 zhangsan

(integer) 2

127.0.0.1:6379> zrange test:001 0 5

1) "zhangsan"

2) "lisi"

3) "niuqi"

127.0.0.1:6379> zrevrange test:001 0 5

1) "niuqi"

2) "lisi"

3) "zhangsan"

5、hash散列表

5.1、应用场景

hash就是要存储一个key对应多个值。比如以key的用户ID,value为用户整个对象的缓存为例,这种数据就很适合使用hash存储。

5.2、hash命令

命令罗列

命令帮助描述

hsethset key field value赋值,不区别新增或修改

hmsethmset key field1 value1 field2 value2批量赋值

hsetnxhsetnx key field value获得有序集合中的元素数量

hexistshexists key filed查看某个field是否存在

hgethget key field获取一个字段值

hmgethmget key field1 field2 ...获取所有

hgetallhgetall key获得集合中member的排名(按分值从小到大)

hdelhdel key field1 field2删除指定字段

hincrbyhincrby key field increment指定字段自增increment

hlenhlen key获得字段数量

命令操作

# 其实直接使用hset多个key value也是可以的

127.0.0.1:6379> hset user:001 id 001 name zhangsan

(integer) 2

127.0.0.1:6379> hget user:001 id

"001"

127.0.0.1:6379> hget user:001 name

"zhangsan"

127.0.0.1:6379> hmset user:001 age 20 sex 1

OK

127.0.0.1:6379> hsetnx user:001 age 30

(integer) 0

127.0.0.1:6379> hexists user:001 age

(integer) 1

127.0.0.1:6379> hget user:001 age

"20"

# 使用hget多个就会报错

127.0.0.1:6379> hget user:001 age name

(error) ERR wrong number of arguments for 'hget' command

127.0.0.1:6379> hmget user:001 age name

1) "20"

2) "zhangsan"

127.0.0.1:6379> hgetall user

(empty list or set)

127.0.0.1:6379> hgetall user:001

1) "id"

2) "001"

3) "name"

4) "zhangsan"

5) "age"

6) "20"

7) "sex"

8) "1"

6、bitmap位图

bitmap是进行按位操作的,可以极大的节省空间,如果需要小空间存储大量值的时候可以使用它,并且存储的值很简单,就是1bit即可存储。

比如:用户每月签到,客户以用户id为key, 日期作为偏移量,1 表示签到

命令罗列

命令帮助描述

setbitsetbit key offffset value设置key在offffset处的bit值(只能是0或者1)。

getbitgetbit key offffset获得key在offffset处的bit值

bitcountbitcount key获得key的bit位为1的个数

bitposbitpos key value返回第一个被设置为bit值的索引值

bitopbitop and[or/xor/not] destkey key [key …]对多个key 进行逻辑运算后存入destkey中

命令操作

# 本月用户签到了四天

127.0.0.1:6379> setbit user:sign:001 20220801 1

(integer) 0

127.0.0.1:6379> setbit user:sign:001 20220803 1

(integer) 0

127.0.0.1:6379> setbit user:sign:001 20220809 1

(integer) 0

127.0.0.1:6379> setbit user:sign:001 20220820 1

(integer) 0

# 查看20220801是否签到了 1表示签到了 0表示没有签到

127.0.0.1:6379> getbit user:sign:001 20220801

(integer) 1

127.0.0.1:6379> getbit user:sign:001 20220802

(integer) 0

# 统计用户签到的次数

127.0.0.1:6379> bitcount user:sign:001

(integer) 4

# 查看第一次签到的时间

127.0.0.1:6379> bitpos user:sign:001 1

(integer) 20220801

7、geo地理位置类型

7.1、应用场景

geo是Redis用来处理位置信息的。在Redis3.2中正式使用。

应用场景:

记录地理位置

计算距离

查找"附近的人"

7.2、geo地理位置命令

命令罗列

命令帮助描述

geoaddgeoadd key 经度 纬度 成员名称1 经度1 纬度1 成员名称2添加地理坐标

geohashgeohash key 成员名称1 成员名称2返回标准的geohash串

geoposgeopos key 成员名称1 成员名称2返回成员经纬度

geodistgeodist key 成员1 成员2 单位计算成员间距离

georadiusbymembergeoradiusbymember key 成员 值单位 count 数asc[desc]根据成员查找附近的成员

# 添加坐标

127.0.0.1:6379> geoadd user:addr 116.21 40.00 zhangsan 116.23 49.9 lisi

(integer) 2

# 获取坐标的hash

127.0.0.1:6379> geohash user:addr zhangsan lisi

1) "wx4es3v8ck0"

2) "y8feuuh0e60"

# 获取坐标的经纬度

127.0.0.1:6379> geopos user:addr zhangsan

1) 1) "116.21000200510025024"

  2) "39.99999991084916218"

# 计算两个用户的距离 单位米

127.0.0.1:6379> geodist user:addr zhangsan lisi

"1101141.4665"

# 计算两个用户的距离 单位千米

127.0.0.1:6379> geodist user:addr zhangsan lisi km

"1101.1415"

# 计算张三1200km之内的人的经纬度,距离,由近到远排出顺序

127.0.0.1:6379> georadiusbymember user:addr zhangsan 1200 km withcoord withdist count 3 asc

1) 1) "zhangsan"

  2) "0.0000"

  3) 1) "116.21000200510025024"

      2) "39.99999991084916218"

2) 1) "lisi"

  2) "1101.1415"

  3) 1) "116.23000055551528931"

      2) "49.89999975254306719"

8、stream数据流类型

8.1、应用场景

stream是Redis5.0后新增的数据结构,用于可持久化的消息队列。

应用场景,没有使用第三方消息队列,但是使用了redis,redis实现了消息队列功能,但是没有专门左中间件的成熟。所以需要谨慎选择。学习一下还是不错的。

8.2、stream类型命令

命令罗列

命令帮助描述

xaddxadd key id <*> field1 value1将指定消息数据追加到指定队列(key)中,*表示最新生成的id(当前时间+序列号)

xreadxread [COUNT count] [BLOCKmilliseconds] STREAMS key[key ...] ID [ID ...]从消息队列中读取,COUNT:读取条数,BLOCK:阻塞读(默认不阻塞)key:队列名称 id:消息id

xrangexrange key start end [COUNT]读取队列中给定ID范围的消息 COUNT:返回消息条数(消息id从小到大)

xrevrangexrevrange key start end [COUNT]读取队列中给定ID范围的消息 COUNT:返回消息条数(消息id从大小到大)

xdelxdel key id删除队列的消息

xgroupxgroup create key groupname id创建一个新的消费组

xgroupxgroup destory key groupname删除指定消费组

xgroupxgroup delconsumer key groupname cname删除指定消费组中的某个消费者

xgroupxgroup setid key id修改指定消息的最大id

xreadgroupxreadgroup group groupname consumer COUNT streams key从队列中的消费组中创建消费者并消费数据(consumer不存在则创建)

命令操作

# 创建消息

127.0.0.1:6379> xadd topic:001 * name zhangsan age 20

"1661008860267-0"

127.0.0.1:6379> xadd topic:001 * name wangwu age 24 name lisi age 35

"1661008909085-0"

# 查看消息

127.0.0.1:6379> xrange topic:001 - +

1) 1) "1661008860267-0"

  2) 1) "name"

      2) "zhangsan"

      3) "age"

      4) "20"

2) 1) "1661008909085-0"

  2) 1) "name"

      2) "wangwu"

      3) "age"

      4) "24"

      5) "name"

      6) "lisi"

      7) "age"

      8) "35"

# 读取一个消息

127.0.0.1:6379> xread count 1 streams topic:001 0

1) 1) "topic:001"

  2) 1) 1) "1661008860267-0"

        2) 1) "name"

            2) "zhangsan"

            3) "age"

            4) "20"

# 创建一个消费组

127.0.0.1:6379> xgroup create topic:001 group1 0

OK

# 使用消费组消费数据

127.0.0.1:6379> xreadgroup group group1 user1 count 1 streams topic:001 >

1) 1) "topic:001"

  2) 1) 1) "1661008860267-0"

        2) 1) "name"

            2) "zhangsan"

            3) "age"

            4) "20"

# 使用消费组消费数据 继续消费 总共两条

127.0.0.1:6379> xreadgroup group group1 user1 count 1 streams topic:001 >

1) 1) "topic:001"

  2) 1) 1) "1661008909085-0"

        2) 1) "name"

            2) "wangwu"

            3) "age"

            4) "24"

            5) "name"

            6) "lisi"

            7) "age"

            8) "35"

# 消费完了,没有啦

127.0.0.1:6379> xreadgroup group group1 user1 count 1 streams topic:001 >

(nil)

9、小结

redis的功能之所以这么强大,也与它的各种数据类型有关,不同的业务场景可以使用不同的数据类型,从而更加高效的实现需求。

QR Code
微信扫一扫,欢迎咨询~

联系我们
武汉格发信息技术有限公司
湖北省武汉市经开区科技园西路6号103孵化器
电话:155-2731-8020 座机:027-59821821
邮件:tanzw@gofarlic.com
Copyright © 2023 Gofarsoft Co.,Ltd. 保留所有权利
遇到许可问题?该如何解决!?
评估许可证实际采购量? 
不清楚软件许可证使用数据? 
收到软件厂商律师函!?  
想要少购买点许可证,节省费用? 
收到软件厂商侵权通告!?  
有正版license,但许可证不够用,需要新购? 
联系方式 155-2731-8020
预留信息,一起解决您的问题
* 姓名:
* 手机:

* 公司名称:

姓名不为空

手机不正确

公司不为空