Redis系列之常見數據類型應用場景

来源:https://www.cnblogs.com/mzq123/archive/2023/11/08/17818581.html
-Advertisement-
Play Games

目錄String簡單介紹常見命令應用場景Hash簡單介紹常見命令應用場景List簡單介紹常見命令應用場景Set簡單介紹常見命令應用場景Sorted Set(Zset)簡單介紹常見命令應用場景Bitmap簡單介紹常見命令應用場景附錄 Redis支持多種數據類型,比如String、hash、list、S ...


目錄
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

mset tkey1 tvalue tkey2 111

批量獲取多個key值

mget tkey1 tkey2

獲取長度

strlen tkey

字元串後面追加內容

append tkey tstring

獲取指定範圍的字元

# 取0~3之間的字元,返回1tst
getrange tkey 0 3

key進行遞增(整數)

# 返回1
incr ikey
# 遞增指定大小的值,返回124
incrby ikey 124

key進行遞增(浮點數)

# 設置初始浮點數值
set fkey 1.2
# 在原來基礎上遞增2.4,返回3.6
incryfloat fkey 2.4

加上key過期時間

expire tkey 10

分散式鎖實現,set if not exists,可以使用setnx單個命令,也可以使用set結合nx命令來實現

# set tkey過期時間10秒,nx:如果鍵不存在時設置
set tkey aaa ex 10 nx
# setnx命令,相當於set和nx命令一起用
setnx tkey aaa

EX : 設置指定的到期時間(以秒為單位)。

PX : 設置指定的到期時間(以毫秒為單

NX : 僅在鍵不存在時設置鍵。

XX : 只有在鍵已存在時才設置。

String 更多指令請參考官網文檔:https://redis.io/commands/?group=string

應用場景

對於Redis String類型的應用場景也比較多,比如很常有的做緩存處理,也可以用於分散式鎖、分散式ID

分散式鎖的實現主要依賴於命令setnx

分散式ID主要是利用incr這個命令

基於Redis實現一個分散式ID生成器

package com.example.redis.common.handlers;

import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * <pre>
 *      Redis分散式ID生成器
 * </pre>
 *
 * <pre>
 * 修改記錄
 *    修改後版本:     修改人:  修改日期: 2023/11/07 14:18  修改內容:
 * </pre>
 */
@Component
public class RedisIdentifierGenerator implements IdentifierGenerator {

    @Resource
    private RedisTemplate redisTemplate;

    @Override
    public Number nextId(Object entity) {
        String key = entity.getClass().getName();
        return redisTemplate.opsForValue().increment(key);
    }

}

Hash

簡單介紹

Hash哈希,數據類型也是一種比較常見的數據結構,相對於Redis的string類型而言,其實就是多了一層key(field),所以說只要string類型適用的場景,hash都是支持的

常見命令

hash設置key為hkey,field為a的值

hset hkey a aaaa

獲取hkey的field值

hget hkey a

設置多個field值

hmset hkey a 1 b 2 c 3 d 4

獲取多個field值

hmget hkey a b c d

獲取key所有的field

hkeys hkey

獲取key所有field的值

hvals hkey

獲取key所有fileld和值

hgetall hkey

在這裡插入圖片描述

給key某個欄位field添加值

hincrby hkey a 10

在這裡插入圖片描述

對於Hash的更多命令,請參考:https://redis.io/commands/?group=hash

應用場景

對於hash的應用場景,其實只要redis string類型適用的,hash都是適用的,不過hash這種特殊的數據結構,還是適用於一些特殊場景的

  • 存儲一個對象類的數據,這個對象的多個欄位就對應hash的field
  • 存儲一些統計類的數據,比如訪問量、點擊量等等

如圖,如果要統計博客的pv、uv還有評論數量(evaluation_count),隨著博客數量的增加存儲到資料庫里,後面肯定會查詢比較慢,所以可以使用redis進行緩存

在這裡插入圖片描述

使用Redisson來寫一個例子:

  @Resource
    private RedissonClient redissonClient;

    @Test
    void contextLoads() throws ExecutionException, InterruptedException {
        RMap<Object, Object> redissonClientMap = redissonClient.getMap("recordMap");
        Map<String,Integer> map = new HashMap<>();
        map.put("pv" , 1000);
        map.put("uv" , 1500);
        map.put("evaluation_count",30)
        redissonClientMap.putAll(map);
        System.out.println(redissonClientMap.addAndGet("pv", 2));
    }   

List

簡單介紹

redis中的數據類型存儲有序的字元串列表,元素是可以重覆,列表的最大長度為2^32-1個元素(4294967295),即每個列表超過40億個元素

常見命令

左右添加元素

# 左邊添加元素
lpush queueList a
lpush queueList b c

# 右邊添加元素
rpush queueList d e

左右彈出第一條

# 左邊彈出一個元素
lpop queueList
# 右邊彈出一個元素
rpop queueList

左右彈出一個元素,並且設置超時,直到無數據彈出或者超時

blpop queueList 10
brpop queueList 10

應用場景

  • 微信公眾號、微博等消息流列表

    RDeque<Object> recordList = redissonClient.getDeque("recordList");
    recordList.addFirst("1.新聞1");
    recordList.addFirst("2.新聞2");
    recordList.addFirst("3.新聞3");
    IntStream.range(0,3).forEach(a->{
        System.out.println(recordList.poll());
    });
    
  • 消息隊列,使用redis也可以實現消息隊列,比如使用rpush/lpop實現簡單隊列;blpop或者是brpop來實現阻塞讀取隊列;補充說明,同時streampub/sub(訂閱發佈模式)、sortedSet等等也是可以實現的

    不過還是不建議使用Redis來實現消息隊列,因為我們已經有成熟的MQ框架,使用redis實現隊列有可能有下麵的問題:

    • 存在記憶體,可能會有數據丟失,不能重覆消費
    • 消費後不能回應,沒有ack確認機制

Set

簡單介紹

Redis中的Set類型是無序集合,最大存儲數量為2^32-1,大概有40億左右,添加、刪除元素的時間複雜度都是O(1)

常見命令

添加一個或者多個元素

sadd skey a b c d e f g h

獲取所有的元素

smembers skey

獲取集合元素的個數

scard skey

隨機獲取一個元素

srandmember skey

隨機彈出一個元素

spop skey

彈出指定的元素

# 如果兩個元素都有,返回2
srem skey a g

檢查元素是否存在

# 元素存在返回1
sismember skey e

獲取前一個集合有,而後面一個集合沒有的元素

sdiff skey skey1

獲取集合的交集

sinter skey skey1

獲取集合的並集

sunion skey skey1

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

應用場景

  • 抽獎程式,利用spopstandmember隨機彈出元素

    RSet<String> recordSet = redissonClient.getSet("recordSet");
    List<String> members = Lists.newArrayList("alice", "tim","tom" , "風清揚", "jack" );
    recordSet.addAll(members);
    RFuture<Set<String>> threeSet = recordSet.removeRandomAsync(3
                                                               );
    RFuture<Set<String>> twoSet = recordSet.removeRandomAsync(2
                                                             );
    RFuture<Set<String>> oneSet = recordSet.removeRandomAsync(1
                                                             );
    System.out.println("三等獎:"+threeSet.get());
    System.out.println("二等獎:"+twoSet.get());
    System.out.println("一等獎:"+oneSet.get());
    
  • 集合交集(sinter)、並集(sunion)的場景,可以實現共同關註等場景

    RSet<Object> tom = redissonClient.getSet("tom");
    tom.addAll(Lists.newArrayList("令狐沖","james","風清揚"));
    RSet<Object> jack = redissonClient.getSet("jack");
    jack.addAll(Lists.newArrayList("令狐沖","tim","jack"));
    System.out.println("共同關註的人:"+tom.readIntersectionAsync("jack").get());
    
  • sadd 集合存儲,實現點贊、簽到的業務場景

Sorted Set(Zset)

簡單介紹

相對於set來說,sorted set是一種有序的set,排序是根據每個元素的score排序的,score相同時根據key的ASCII碼排序

在這裡插入圖片描述

常見命令

批量添加元素

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

在這裡插入圖片描述

根據分數從低到高

zrange z1 0 -1 withscore

在這裡插入圖片描述

根據分數從高到低

zrevrange z1 0 -1 withscores

根據分數範圍取值

zrangebyscore z1 20 30

移除元素

zrem z1 i

獲取有序集合個數

zcard z1

給某個元素加分值

zincrby z1 20 a

獲取範圍內的個數

zcount z1 50 60

返回指定元素的索引值

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

獲取元素的分數

zscore z1 h

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

應用場景

  • 排行榜

    RScoredSortedSet<String> school = redissonClient.getScoredSortedSet("school");
    school.add(60, "tom");
    school.add(60, "jack");
    school.add(60, "tim");
    school.addScore("tom", 20);
    school.addScore("jack", 10);
    school.addScore("tim", 30);
    RFuture<Collection<ScoredEntry<String>>> collectionRFuture = school.entryRangeReversedAsync(0, -1);
    Iterator<ScoredEntry<String>> iterator = collectionRFuture.get().iterator();
    System.out.println("成績從高到低排序");
    while(iterator.hasNext()) {
        ScoredEntry<String> next = iterator.next();
        String value = next.getValue();
        System.out.println(value);
    }
    RFuture<Collection<ScoredEntry<String>>> collectionRFuture1 = school.entryRangeReversedAsync(0, 2);
    Iterator<ScoredEntry<String>> iterator1 = collectionRFuture1.get().iterator();
    System.out.println("成績前三名");
    while (iterator1.hasNext()) {
        System.out.println(iterator1.next().getValue());
    }
    

Bitmap

簡單介紹

點陣圖不是實際的數據類型,而是String類型中定義的一種面向位的操作,所以這個點陣圖的最大存儲量也是512M。可以容納最少2^32不同的位,可以在不同的位置設置0或者1

常見命令

設置位的值

# 將位2設置為1
setbit permit 2 1

獲取位的值

getbit permit 2

在這裡插入圖片描述

獲取key的為1的個數

# 獲取位為1的總數
bitcount permit

獲取0或者1的第一位

# 獲取key permit 位為1的第一個位置
bitpos permit 1

在這裡插入圖片描述

獲取多個bitmap的位操作,比如&|

# 獲取bkey和permit這兩個的&運算,並且賦值給hbit
bitop AND hbit bkey permit

在這裡插入圖片描述

應用場景

  • 實時的數據統計

    比如:人員的考勤打卡記錄,例如學生tom每次來上課就將相關的位記錄位1

假如當月的第一天、第五天、第十天都來了

setbit tom 1 1
setbit tom 5 1
setbit tom 10 1

如何每月考勤,統計一下這個用戶當月來了幾天

bitcount tom 

也可以應用於統計一個網站一天有多少用戶訪問,例如用戶ID為123、124、125的用戶訪問了csdn

setbit csdn:2023-11-08 123 1
setbit csdn:2023-11-08 124 1
setbit csdn:2023-11-08 125 1
...
# 統計一下當天的訪問次數
bitcount csdn:2023-11-08 
  • 存儲用戶許可權,比如用1來表示有許可權,0表示沒許可權,使用點陣圖可以節省很大的存儲空間

附錄

Redis命令查詢網站:https://redis.io/commands/
在這裡插入圖片描述

IT程式員
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Go 介面-契約介紹 目錄Go 介面-契約介紹一、介面基本介紹1.1 介面類型介紹1.2 為什麼要使用介面1.3 面向介面編程1.4 介面的定義二、空介面2.1 空介面的定義2.2 空介面的應用2.2.1 空介面作為函數的參數2.2.2 空介面作為map的值2.3 介面類型變數2.4 類型斷言三、盡 ...
  • 實踐環境 Python 3.6.2 confluent-kafka 2.2.0 confluent-kafka簡介 Confluent在GitHub上開發和維護的confluent-kafka-python,Apache Kafka®的一個python客戶端,提供了一個與所有brokers>=v0. ...
  • 一:背景 1. 講故事 這段時間分析了幾個和網路故障有關的.NET程式之後,真的越來越體會到電腦基礎課的重要,比如 電腦網路 課,如果沒有對 tcpip協議 的深刻理解,解決這些問題真的很難,因為你只能在高層做黑盒測試,你無法看到 tcp 層面的握手和psh通訊。 這篇我們通過兩個小例子來理解一 ...
  • Span 提供任意記憶體的連續區域的類型安全和記憶體安全表示形式。它是在堆棧而不是托管堆上分配的ref結構,是對任意記憶體塊的抽象 。 1.關於Span 在NET Core 2.1中首次引入 提供對任意記憶體上的連續區域的讀寫視圖 利用索引/迭代來修改範圍內的記憶體 幾乎無開銷 2.和記憶體的關係 Span 表 ...
  • Nexus 是支持 Nuget、Docker、Npm 等多種包的倉庫管理器,可用做私有包的存儲分發,緩存官方包。本篇將手把手教學使用 Nexus 搭建自己的 NuGe t& Docker 私有倉庫。 ...
  • 有的時候我們會對程式進行單元測試, 為了測試的效果以及後期的維護, 我一般會將各個測試拆開, 根據需要測試的類分到各個類型中, 不過在實際操作的時候就出現了一些意想不到的問題, 各個測試的執行是亂序的, 按照我自己寫測試的習慣, 假如我需要測試新寫的增刪改查的功能, 我會將增刪改查分開測試, 會按照 ...
  • 接上篇 docker-bind 的使用搭建了一個 dns 服務,本篇將介紹另外一款 DnsServer 的部署和使用,更專註,更輕量。 ...
  • MongoDB+SignalR+Hangfire+Vue2+百度地圖實現GPS實時定位 一、實現效果 二、安裝MongoDB 可以自行參考菜鳥鏈接:MongoDB 教程 | 菜鳥教程 (runoob.com) 1.下載mongodb資料庫安裝包: 網盤鏈接:https://pan.baidu.com ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...