日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

Redis系列之常见数据类型应用场景

發布時間:2023/11/16 windows 44 coder
生活随笔 收集整理的這篇文章主要介紹了 Redis系列之常见数据类型应用场景 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄
  • String
    • 簡單介紹
    • 常見命令
    • 應用場景
  • Hash
    • 簡單介紹
    • 常見命令
    • 應用場景
  • List
    • 簡單介紹
    • 常見命令
    • 應用場景
  • Set
    • 簡單介紹
    • 常見命令
    • 應用場景
  • Sorted Set(Zset)
    • 簡單介紹
    • 常見命令
    • 應用場景
  • Bitmap
    • 簡單介紹
    • 常見命令
    • 應用場景
  • 附錄

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/

總結

以上是生活随笔為你收集整理的Redis系列之常见数据类型应用场景的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。