Redis支持多种数据类型,比如String、hash、list、Set、SortedSet、Streams、Bitmap、Hyperloglog、Geo(物理位置)等等,在官网也给出了说明,本博客就挑一些比较常有的数据类型说说,本文例子基于Redisson实现

String

简单介绍

在Redis中,所有的数据都是key-value的数据结构存储的,那么在Redis中这个string类型的value值只能存储String类型的数据?其实不然,redis中string类型的value值是可以支持多种类型的,比如String、Number、Float、Bits等等,但是最大还是只能存储512M。Redis中key也是string类型存储的,所以最大也只能存储512M

常见命令

setget命令就不演示了,下面给出一些常有命令

批量设置多个key

  1. mset tkey1 tvalue tkey2 111

批量获取多个key值

  1. mget tkey1 tkey2

获取长度

  1. strlen tkey

字符串后面追加内容

  1. append tkey tstring

获取指定范围的字符

  1. # 取0~3之间的字符,返回1tst
  2. getrange tkey 0 3

key进行递增(整数)

  1. # 返回1
  2. incr ikey
  3. # 递增指定大小的值,返回124
  4. incrby ikey 124

key进行递增(浮点数)

  1. # 设置初始浮点数值
  2. set fkey 1.2
  3. # 在原来基础上递增2.4,返回3.6
  4. incryfloat fkey 2.4

加上key过期时间

  1. expire tkey 10

分布式锁实现,set if not exists,可以使用setnx单个命令,也可以使用set结合nx命令来实现

  1. # set tkey过期时间10秒,nx:如果键不存在时设置
  2. set tkey aaa ex 10 nx
  3. # setnx命令,相当于set和nx命令一起用
  4. setnx tkey aaa

EX : 设置指定的到期时间(以秒为单位)。

PX : 设置指定的到期时间(以毫秒为单

NX : 仅在键不存在时设置键。

XX : 只有在键已存在时才设置。

String 更多指令请参考官网文档:https://redis.io/commands/?group=string

应用场景

对于Redis String类型的应用场景也比较多,比如很常有的做缓存处理,也可以用于分布式锁、分布式ID

分布式锁的实现主要依赖于命令setnx

分布式ID主要是利用incr这个命令

基于Redis实现一个分布式ID生成器

  1. package com.example.redis.common.handlers;
  2. import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
  3. import org.springframework.data.redis.core.RedisTemplate;
  4. import org.springframework.stereotype.Component;
  5. import javax.annotation.Resource;
  6. /**
  7. * <pre>
  8. * Redis分布式ID生成器
  9. * </pre>
  10. *
  11. * <pre>
  12. * 修改记录
  13. * 修改后版本: 修改人: 修改日期: 2023/11/07 14:18 修改内容:
  14. * </pre>
  15. */
  16. @Component
  17. public class RedisIdentifierGenerator implements IdentifierGenerator {
  18. @Resource
  19. private RedisTemplate redisTemplate;
  20. @Override
  21. public Number nextId(Object entity) {
  22. String key = entity.getClass().getName();
  23. return redisTemplate.opsForValue().increment(key);
  24. }
  25. }

Hash

简单介绍

Hash哈希,数据类型也是一种比较常见的数据结构,相对于Redis的string类型而言,其实就是多了一层key(field),所以说只要string类型适用的场景,hash都是支持的

常见命令

hash设置key为hkey,field为a的值

  1. hset hkey a aaaa

获取hkey的field值

  1. hget hkey a

设置多个field值

  1. hmset hkey a 1 b 2 c 3 d 4

获取多个field值

  1. hmget hkey a b c d

获取key所有的field

  1. hkeys hkey

获取key所有field的值

  1. hvals hkey

获取key所有fileld和值

  1. hgetall hkey

给key某个字段field添加值

  1. hincrby hkey a 10

对于Hash的更多命令,请参考:https://redis.io/commands/?group=hash

应用场景

对于hash的应用场景,其实只要redis string类型适用的,hash都是适用的,不过hash这种特殊的数据结构,还是适用于一些特殊场景的

  • 存储一个对象类的数据,这个对象的多个字段就对应hash的field
  • 存储一些统计类的数据,比如访问量、点击量等等

如图,如果要统计博客的pv、uv还有评论数量(evaluation_count),随着博客数量的增加存储到数据库里,后面肯定会查询比较慢,所以可以使用redis进行缓存

使用Redisson来写一个例子:

  1. @Resource
  2. private RedissonClient redissonClient;
  3. @Test
  4. void contextLoads() throws ExecutionException, InterruptedException {
  5. RMap<Object, Object> redissonClientMap = redissonClient.getMap("recordMap");
  6. Map<String,Integer> map = new HashMap<>();
  7. map.put("pv" , 1000);
  8. map.put("uv" , 1500);
  9. map.put("evaluation_count",30)
  10. redissonClientMap.putAll(map);
  11. System.out.println(redissonClientMap.addAndGet("pv", 2));
  12. }

List

简单介绍

redis中的数据类型存储有序的字符串列表,元素是可以重复,列表的最大长度为2^32-1个元素(4294967295),即每个列表超过40亿个元素

常见命令

左右添加元素

  1. # 左边添加元素
  2. lpush queueList a
  3. lpush queueList b c
  4. # 右边添加元素
  5. rpush queueList d e

左右弹出第一条

  1. # 左边弹出一个元素
  2. lpop queueList
  3. # 右边弹出一个元素
  4. rpop queueList

左右弹出一个元素,并且设置超时,直到无数据弹出或者超时

  1. blpop queueList 10
  2. brpop queueList 10

应用场景

  • 微信公众号、微博等消息流列表

    1. RDeque<Object> recordList = redissonClient.getDeque("recordList");
    2. recordList.addFirst("1.新闻1");
    3. recordList.addFirst("2.新闻2");
    4. recordList.addFirst("3.新闻3");
    5. IntStream.range(0,3).forEach(a->{
    6. System.out.println(recordList.poll());
    7. });
  • 消息队列,使用redis也可以实现消息队列,比如使用rpush/lpop实现简单队列;blpop或者是brpop来实现阻塞读取队列;补充说明,同时streampub/sub(订阅发布模式)、sortedSet等等也是可以实现的

    不过还是不建议使用Redis来实现消息队列,因为我们已经有成熟的MQ框架,使用redis实现队列有可能有下面的问题:

    • 存在内存,可能会有数据丢失,不能重复消费
    • 消费后不能回应,没有ack确认机制

Set

简单介绍

Redis中的Set类型是无序集合,最大存储数量为2^32-1,大概有40亿左右,添加、删除元素的时间复杂度都是O(1)

常见命令

添加一个或者多个元素

  1. sadd skey a b c d e f g h

获取所有的元素

  1. smembers skey

获取集合元素的个数

  1. scard skey

随机获取一个元素

  1. srandmember skey

随机弹出一个元素

  1. spop skey

弹出指定的元素

  1. # 如果两个元素都有,返回2
  2. srem skey a g

检查元素是否存在

  1. # 元素存在返回1
  2. sismember skey e

获取前一个集合有,而后面一个集合没有的元素

  1. sdiff skey skey1

获取集合的交集

  1. sinter skey skey1

获取集合的并集

  1. sunion skey skey1

Set的更多命令请参考:https://redis.io/commands/?group=set

应用场景

  • 抽奖程序,利用spopstandmember随机弹出元素

    1. RSet<String> recordSet = redissonClient.getSet("recordSet");
    2. List<String> members = Lists.newArrayList("alice", "tim","tom" , "风清扬", "jack" );
    3. recordSet.addAll(members);
    4. RFuture<Set<String>> threeSet = recordSet.removeRandomAsync(3
    5. );
    6. RFuture<Set<String>> twoSet = recordSet.removeRandomAsync(2
    7. );
    8. RFuture<Set<String>> oneSet = recordSet.removeRandomAsync(1
    9. );
    10. System.out.println("三等奖:"+threeSet.get());
    11. System.out.println("二等奖:"+twoSet.get());
    12. System.out.println("一等奖:"+oneSet.get());
  • 集合交集(sinter)、并集(sunion)的场景,可以实现共同关注等场景

    1. RSet<Object> tom = redissonClient.getSet("tom");
    2. tom.addAll(Lists.newArrayList("令狐冲","james","风清扬"));
    3. RSet<Object> jack = redissonClient.getSet("jack");
    4. jack.addAll(Lists.newArrayList("令狐冲","tim","jack"));
    5. System.out.println("共同关注的人:"+tom.readIntersectionAsync("jack").get());
  • sadd 集合存储,实现点赞、签到的业务场景

Sorted Set(Zset)

简单介绍

相对于set来说,sorted set是一种有序的set,排序是根据每个元素的score排序的,score相同时根据key的ASCII码排序

常见命令

批量添加元素

  1. zadd z1 10 a 20 b 30 c 40 d 50 e 60 f 70 g 80 h 90 i

根据分数从低到高

  1. zrange z1 0 -1 withscore

根据分数从高到低

  1. zrevrange z1 0 -1 withscores

根据分数范围取值

  1. zrangebyscore z1 20 30

移除元素

  1. zrem z1 i

获取有序集合个数

  1. zcard z1

给某个元素加分值

  1. zincrby z1 20 a

获取范围内的个数

  1. zcount z1 50 60

返回指定元素的索引值

  1. # 假如d元素排在第4位,索引值就返回3
  2. zrank z1 d

获取元素的分数

  1. zscore z1 h

Sorted Set的更多命令请参考:https://redis.io/commands/?group=sorted_set

应用场景

  • 排行榜

    1. RScoredSortedSet<String> school = redissonClient.getScoredSortedSet("school");
    2. school.add(60, "tom");
    3. school.add(60, "jack");
    4. school.add(60, "tim");
    5. school.addScore("tom", 20);
    6. school.addScore("jack", 10);
    7. school.addScore("tim", 30);
    8. RFuture<Collection<ScoredEntry<String>>> collectionRFuture = school.entryRangeReversedAsync(0, -1);
    9. Iterator<ScoredEntry<String>> iterator = collectionRFuture.get().iterator();
    10. System.out.println("成绩从高到低排序");
    11. while(iterator.hasNext()) {
    12. ScoredEntry<String> next = iterator.next();
    13. String value = next.getValue();
    14. System.out.println(value);
    15. }
    16. RFuture<Collection<ScoredEntry<String>>> collectionRFuture1 = school.entryRangeReversedAsync(0, 2);
    17. Iterator<ScoredEntry<String>> iterator1 = collectionRFuture1.get().iterator();
    18. System.out.println("成绩前三名");
    19. while (iterator1.hasNext()) {
    20. System.out.println(iterator1.next().getValue());
    21. }

Bitmap

简单介绍

位图不是实际的数据类型,而是String类型中定义的一种面向位的操作,所以这个位图的最大存储量也是512M。可以容纳最少2^32不同的位,可以在不同的位置设置0或者1

常见命令

设置位的值

  1. # 将位2设置为1
  2. setbit permit 2 1

获取位的值

  1. getbit permit 2

获取key的为1的个数

  1. # 获取位为1的总数
  2. bitcount permit

获取0或者1的第一位

  1. # 获取key permit 位为1的第一个位置
  2. bitpos permit 1

获取多个bitmap的位操作,比如&|

  1. # 获取bkey和permit这两个的&运算,并且赋值给hbit
  2. bitop AND hbit bkey permit

应用场景

  • 实时的数据统计

    比如:人员的考勤打卡记录,例如学生tom每次来上课就将相关的位记录位1

假如当月的第一天、第五天、第十天都来了

  1. setbit tom 1 1
  2. setbit tom 5 1
  3. setbit tom 10 1

如何每月考勤,统计一下这个用户当月来了几天

  1. bitcount tom

也可以应用于统计一个网站一天有多少用户访问,例如用户ID为123、124、125的用户访问了csdn

  1. setbit csdn:2023-11-08 123 1
  2. setbit csdn:2023-11-08 124 1
  3. setbit csdn:2023-11-08 125 1
  4. ...
  5. # 统计一下当天的访问次数
  6. bitcount csdn:2023-11-08
  • 存储用户权限,比如用1来表示有权限,0表示没权限,使用位图可以节省很大的存储空间

附录

Redis命令查询网站:https://redis.io/commands/

Redis系列之常见数据类型应用场景的更多相关文章

  1. Redis系列(2)之数据类型

    Redis系列(2)之数据类型 <Redis系列(1)之安装>中介绍了Redis支持以下几种数据类型,那么本节主要介绍学习下这几种数据类型的基本操作 字符串类型,string 散列类型,h ...

  2. Redis全方位详解--数据类型使用场景和redis分布式锁的正确姿势

    一.Redis数据类型 1.string string是Redis的最基本数据类型,一个key对应一个value,每个value最大可存储512M.string一半用来存图片或者序列化的数据. 2.h ...

  3. Redis系列---操作命令及数据类型

    本章将简单介绍下,Redis里面常用的数据类型以及我们常用到的一些命令,let's go 准备环境: Redis  详细见上一个章节 我们接下来操作的命令用的是Redis自带的客户端工具,在安装red ...

  4. Redis系列之----Redis的数据类型及使用场景

       Redis是一个开源的.高性能的.基于键值对的缓存与存储系统,能够提供多种不同的键值数据类型来适应不同场景下的缓存和存储需求.    Redis中所有的数据都存储在内存中,因此读写速度非常快,相 ...

  5. Redis常见的应用场景解析

    Redis是一个key-value存储系统,现在在各种系统中的使用越来越多,大部分情况下是因为其高性能的特性,被当做缓存使用,这里介绍下Redis经常遇到的使用场景. Redis特性 一个产品的使用场 ...

  6. Redis系列(二):Redis的数据类型及命令操作

    原文链接(转载请注明出处):Redis系列(二):Redis的数据类型及命令操作 Redis 中常用命令 Redis 官方的文档是英文版的,当然网上也有大量的中文翻译版,例如:Redis 命令参考.这 ...

  7. 《【面试突击】— Redis篇》--Redis都有哪些数据类型?分别在哪些场景下使用比较合适?

    能坚持别人不能坚持的,才能拥有别人不能拥有的.关注编程大道公众号,让我们一同坚持心中所想,一起成长!! <[面试突击]— Redis篇>--Redis都有哪些数据类型?分别在哪些场景下使用 ...

  8. Redis系列(二)—— 数据类型及其使用

    Redis数据类型及其使用 参考:http://www.cnblogs.com/jackluo/p/3173436.html Redis支持五种数据类型:string(字符串),hash(哈希),li ...

  9. redis的五种常见数据类型的常用指令

      一.String字符串,key-value 应用场景:string是redis的最基本数据类型,key-value格式,一个key对应一个值的情况下 1.设置key = value:set key ...

  10. 3.redis 都有哪些数据类型?分别在哪些场景下使用比较合适?

    作者:中华石杉 面试题 redis 都有哪些数据类型?分别在哪些场景下使用比较合适? 面试官心理分析 除非是面试官感觉看你简历,是工作 3 年以内的比较初级的同学,可能对技术没有很深入的研究,面试官才 ...

随机推荐

  1. SpringBoot整合WebService(实用版)

    SpringBoot整合WebService 简介 WebService就是一种跨编程语言和跨操作系统平台的远程调用技术 此处就不赘述WebService相关概念和原理了,可以参考:https://b ...

  2. 使用 virt-install 命令创建虚拟机

    实践 参考文档:官方手册 这个命令适用于创建第一个虚拟机,后面如果再增加,修改xml文件或者使用clone命令就可以了. centos.sh #!/bin/bash name='centos7' is ...

  3. 号外号外!首届开源 AI 游戏挑战赛圆满结束!

    北京时间 7 月 8 日到 7 月 10 日, 我们举办了 首届开源 AI 游戏开发挑战赛.这是一场激动人心的赛事活动,游戏开发者在紧迫的 48 小时内使用 AI 创造.创新有创意的游戏. 本次赛事活 ...

  4. git: 解决每次操作git时都要输入账户、密码

    解决方案 $ git config --global credential.helper store 使用该命令即可解决问题

  5. 用python selenium提取网页中的所有<a>标签中的超级链接地址

    urls = driver.find_elements_by_xpath("//a") for url in urls: print(url.get_attribute(" ...

  6. bzip2: (stdin) is not a bzip2 file.

    用tar -zxvf dir.tar.gz命令解压即可.

  7. 助力618-Y的混沌实践之路

    一.写在前面 1.混沌是什么? 混沌工程(Chaos Engineering)的概念由 Netflix 在 2010 年提出,通过主动向系统中引入异常状态,并根据系统在各种压力下的行为表现确定优化策略 ...

  8. tcp3次握手

    tcp3次握手 1,三次握手流程图 2,三握手过程 当pc1想和pc2建立起连接时 pc1将连接信息写入报文 2.1,报文的序号(seq=x) 同步位(请求建立连接关系: SYN=1 ACK=0 控制 ...

  9. 一款开源免费、更符合现代用户需求的论坛系统:vanilla

    对于个人建站来说,WordPress相信很多读者都知道了.但WordPress很多时候我们还是用来建立自主发布内容的站点为主,适用于个人博客.企业主站等.虽然有的主题可以把WordPress变为论坛, ...

  10. 清理MySQL的binlog日志

    前言 MySQL的binlog是以二进制形式打印的日志,没设置自动删除的话,时间长了就会占用大量存储空间.删除MySQL的binlog日志有两种方法:自动删除和手动删除. 自动删除 永久生效:修改My ...