Redis——用戶簽到BitMap,UV統計

目錄

BitMap

使用場景

1.?用戶簽到系統

2.?用戶行為標記

3.?布隆過濾器(Bloom Filter)

BitMap介紹?

Redis中的使用?

Redis功能示例

添加:?

獲取:

批量獲取:

?java中實現

?統計本月連續簽到次數

?UV統計

?UV 統計的核心需求

使用?HyperLogLog

UV 統計的常見場景

場景 1:每日 UV 統計

場景 2:月度 UV 統計


BitMap

使用場景

在開發中,Bitmap?經常被用于以下場景:

1.?用戶簽到系統

場景描述
用戶每天簽到一次,系統需要記錄用戶每月的簽到情況,并支持快速查詢連續簽到天數、總簽到天數等。

實現方式

  • 使用一個?Bitmap,每一位代表一天(1表示簽到,0表示未簽到)。

  • 例如,用戶ID為1的用戶在2023年10月的簽到記錄可以用一個31位的?Bitmap?表示。

優點

  • 存儲空間極小:一個月的簽到記錄只需要4字節(32位)。

  • 查詢效率高:可以通過位運算快速計算連續簽到天數、總簽到天數等。


2.?用戶行為標記

場景描述
系統需要標記用戶是否完成了某些行為(例如是否閱讀了某篇文章、是否參與了某個活動等)。

實現方式

  • 使用一個?Bitmap,每一位代表一個行為(1表示完成,0表示未完成)。

  • 例如,用戶ID為1的用戶完成了行為A、B、D,可以用?0b1101?表示。

優點

  • 節省存儲空間:一個用戶的所有行為標記可以用一個整數表示。

  • 支持快速查詢:通過位運算可以快速判斷用戶是否完成了某個行為。


3.?布隆過濾器(Bloom Filter)

場景描述
布隆過濾器是一種概率型數據結構,用于快速判斷某個元素是否存在于一個集合中(可能存在誤判,但不會漏判)。

實現方式

  • 使用一個?Bitmap?作為布隆過濾器的底層存儲結構。

  • 通過多個哈希函數將元素映射到?Bitmap?的不同位置,并將這些位置標記為1。

優點

  • 空間效率極高:適合海量數據的去重和查詢。

  • 查詢速度快:時間復雜度為 O(1)。

BitMap介紹?

?

?如果是使用表來儲存,需要耗費大量的內存,數據庫壓力山大

因此我們換一種方式來存儲,一個月最多有31天,因此,如果某一天簽到了,那么對應的位為1,沒有則為0。這種方式只需要31bit,也就是8字節,大大節省了空間。

Redis中的使用?

Redis功能示例
添加:?

儲存為11100111

獲取:

批量獲取:

u2中的u表示儲存的為無符號,2表示只截取兩個比特位,截取結果為11,轉化為十進制就是3

?java中實現

    public Result sign() {// 獲取登錄用戶Long userId = UserHolder.getUser().getId();// 獲取日期LocalDateTime now = LocalDateTime.now();// 拼接用戶和日期變成keyString keySuffix = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));
//        String key = "sign:"+userId+keySuffix;String key = USER_SIGN_KEY+userId+keySuffix;// 獲取今天是本月的第幾天int dayOfMonth = now.getDayOfMonth();// 寫入Redis setbit key offset 1stringRedisTemplate.opsForValue().setBit(key,dayOfMonth-1,true); // 注意這里需要減一因為在儲存中字節是從0開始的return Result.ok();}

?統計本月連續簽到次數

    @Overridepublic Result signCount() {// 獲取登錄用戶Long userId = UserHolder.getUser().getId();// 獲取日期LocalDateTime now = LocalDateTime.now();// 拼接用戶和日期變成keyString keySuffix = now.format(DateTimeFormatter.ofPattern(":yyyyMM"));
//        String key = "sign:"+userId+keySuffix;String key = USER_SIGN_KEY+userId+keySuffix;// 獲取今天是本月的第幾天int dayOfMonth = now.getDayOfMonth();//獲取本月為止的所有的簽到記錄,返回的是一個十進制的數字 BITFIELD key GET udayOfMonth 0List<Long> result = stringRedisTemplate.opsForValue().bitField(key,BitFieldSubCommands.create().get(BitFieldSubCommands.BitFieldType.unsigned(dayOfMonth)) // 子命令.valueAt(0));if(result == null || result.isEmpty()){return Result.ok(0);}//  為什么需要 get(0)?get(0) 是從 List<Long> 中獲取第一個元素。//  stringRedisTemplate.opsForValue().bitField(...) 返回的是一個 List<Long>,//  即使你只請求了一個值,它也會以列表的形式返回。//  因此,result.get(0) 獲取的是這個列表中的第一個元素,也就是你請求的簽到記錄的值。Long num = result.get(0);if(num == null || num == 0){return  Result.ok(0);}// 遍歷循環int cnt = 0;while(cnt < dayOfMonth){if ((num & 1) == 0) {break;}cnt++;// 把數字右移一位,拋棄最后一個bit位,繼續下一個bit位num >>>=1;}return Result.ok(cnt);}

?UV統計

在 Redis 中,UV(Unique Visitor)統計?是指統計某個時間段內訪問某個資源的獨立用戶數量。UV 統計是許多應用場景(如網站訪問量統計、廣告點擊統計等)中的核心需求。Redis 提供了多種數據結構和方法來實現高效的 UV 統計。

以下是 Redis 中 UV 統計的相關知識點介紹:

?UV 統計的核心需求

  • 去重:同一個用戶在同一時間段內的多次訪問只算作一次。

  • 高效存儲:需要支持海量用戶的統計。

  • 快速查詢:能夠快速獲取某個時間段內的 UV 數據。

使用?HyperLogLog

原理

  • HyperLogLog 是一種概率算法,用于估算大量數據的基數(去重后的數量)。

  • 它通過極小的存儲空間(每個 HyperLogLog 鍵只需要 12 KB)來統計 UV。

命令

  • PFADD key user_id:將用戶 ID 添加到 HyperLogLog 中。

  • PFCOUNT key:獲取 UV 的估算值。

優點

  • 存儲空間極小,適合海量用戶的 UV 統計。

  • 查詢速度快。

缺點

  • 結果是估算值,存在一定的誤差(標準誤差約為 0.81%)

    UV 統計的常見場景

    場景 1:每日 UV 統計

    需求

    • 統計每天的獨立訪問用戶數。

    實現

    • 使用?HyperLogLog,每天創建一個新的鍵(例如?uv:2023-10-01),將當天的用戶 ID 添加到鍵中。

    • 每天結束時,使用?PFCOUNT?獲取當天的 UV 值。

    場景 2:月度 UV 統計

    需求

    • 統計每月的獨立訪問用戶數。

    實現

    • 使用?HyperLogLog,將整個月的用戶 ID 添加到同一個鍵中(例如?uv:2023-10)。

    • 每月結束時,使用?PFCOUNT?獲取當月的 UV 值。

    本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
    如若轉載,請注明出處:http://www.pswp.cn/diannao/70735.shtml
    繁體地址,請注明出處:http://hk.pswp.cn/diannao/70735.shtml
    英文地址,請注明出處:http://en.pswp.cn/diannao/70735.shtml

    如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

    相關文章

    【數據庫】【MySQL】索引

    MySQL中索引的概念 索引&#xff08;MySQL中也叫做"鍵&#xff08;key&#xff09;"&#xff09;是一種數據結構&#xff0c;用于存儲引擎快速定找到記錄。 簡單來說&#xff0c;它類似于書籍的目錄&#xff0c;通過索引可以快速找到對應的數據行&#xff0c;而無需…

    【SpringBoot AI 集成DeepSeek 大模型API調用】

    當DeepSeek開始盛行&#xff0c;提供強大的大語言模型&#xff0c;界面調用不能滿足我們的需要&#xff0c;同時提供API接口供我們在服務中調用&#xff0c;來實現各種AI場景。 我們通過將DeepSeek的AI能力與SpringBoot AI相結合&#xff0c;實現智能聊天、問答機器人&#xf…

    Linux 性能更好的ftp客戶端 lftp 使用詳解

    簡介 LFTP 是一個命令行 FTP 客戶端&#xff0c;支持多種文件傳輸協議&#xff0c;包括 FTP、FTPS、HTTP、HTTPS和SFTP 。它以其通過鏡像、后臺操作和腳本支持等特性有效管理復雜傳輸的能力而聞名。 安裝 Ubuntu/Debian sudo apt update sudo apt install lftpCentOS/RHEL/…

    汽車智能制造企業數字化轉型SAP解決方案總結

    一、項目實施概述 項目階段劃分&#xff1a; 藍圖設計階段主數據管理方案各模塊藍圖設計方案下一階段工作計劃 關鍵里程碑&#xff1a; 2022年6月6日&#xff1a;項目啟動會2022年12月1日&#xff1a;系統上線 二、總體目標 通過SAP實施&#xff0c;構建研產供銷協同、業財一…

    【深度學習】矩陣的理解與應用

    一、矩陣基礎知識 1. 什么是矩陣&#xff1f; 矩陣是一個數學概念&#xff0c;通常表示為一個二維數組&#xff0c;它由行和列組成&#xff0c;用于存儲數值數據。矩陣是線性代數的基本工具之一&#xff0c;廣泛應用于數學、物理學、工程學、計算機科學、機器學習和數據分析等…

    <網絡> UDP協議

    目錄 傳輸層 再談端口號 端口號范圍劃分 認識知名端口號 兩個問題 netstat與iostat pidof UDP協議 UDP協議格式 UDP數據封裝&#xff1a; UDP數據分用&#xff1a; UDP協議的特點 面向數據報 UDP的緩沖區 UDP使用注意事項 基于UDP的應用層協 傳輸層 在學習HTTP等應用層協議時&…

    大模型面試基礎問題

    1.1.1 最主流的開源模型&#xff1f; ChatGLM-6B[1] prefix LM LLaMA-7B[2] causal LM 1.1.2 prefix LM和causal LM的區別&#xff1f; 1.1.2.1 Prefix LM Prefix LM&#xff0c;即前綴語言模型&#xff0c;該結構是Google的T5模型論文起的名字&#xff0c;望文知義來說&…

    your HTTP request connection start duration too long

    If your HTTP request connection start duration is taking more than 7 seconds, here are some possible causes and troubleshooting steps: Possible Causes: Network Latency – Slow internet or network congestion.DNS Resolution Delay – Slow DNS lookup affecti…

    Python天梯賽系統備考-字符串篇

    知識點拆解 1. 切片技巧 定義 通過 [start:end:step] 語法截取字符串的子序列 start&#xff1a;起始索引&#xff08;包含&#xff0c;默認0&#xff09; end&#xff1a;結束索引&#xff08;不包含&#xff0c;默認末尾&#xff09; step&#xff1a;步長&#xff0…

    國標28181協議在智聯視頻超融合平臺中的接入方法

    一. 國標28181介紹 國標 28181 協議全稱是《安全防范視頻監控聯網系統信息傳輸、交換、控制技術要求》&#xff0c;是國內視頻行業最重要的國家標準&#xff0c;目前有三個版本&#xff1a; 2011 年&#xff1a;推出 GB/T 28181-2011 版本&#xff0c;為安防行業的前端設備、平…

    深入探究 C 語言內存函數:memcpy、memmove、memset 和 memcmp

    一&#xff0c;常見的內存函數 在 C 語言的編程世界里&#xff0c;對內存的高效操作至關重要。C 標準庫為我們提供了一系列強大的內存操作函數&#xff0c;其中 memcpy、memmove、memset 和 memcmp 這四個函數是處理內存數據的得力助手。接下來&#xff0c;讓我們深入了解它們…

    Java 集合

    Java 集合 在 Java 編程中&#xff0c;集合框架&#xff08;java.util 包&#xff09;是處理一組對象的強大工具。與數組不同&#xff0c;集合提供了更靈活的數據存儲和操作方式。本文將詳細介紹 Java 集合框架的核心接口、常用實現類及其應用場景&#xff0c;幫助你更好地理解…

    go基本語法

    跟Java比較學習。 hello word 示例代碼 test1.go文件&#xff1a; // 包路徑 package main// 導入模塊&#xff0c;下面兩種都行 import ("fmt" ) import "log"// main方法 func main() {log.Print("hello word !!!")fmt.Print("hello …

    【Docker】如何在Linux、Windows、MacOS中安裝Docker

    Linux安裝Docker 在終端中執行一鍵安裝腳本命令安裝docker sudo curl -fsSL https://gitee.com/tech-shrimp/docker_installer/releases/download/latest/linux.sh | bash -s docker --mirror Aliyun1.1 配置docker鏡像源 在終端執行 一行命令&#xff0c;編輯配置文件 sudo …

    2.24力扣-回溯電話號碼的字母組合

    17. 電話號碼的字母組合 - 力扣&#xff08;LeetCode&#xff09; class Solution {List<String> ans new LinkedList<>();StringBuilder temp new StringBuilder();public List<String> letterCombinations(String digits) {if(digitsnull || digits.leng…

    Cocos Creator Shader入門實戰(一):材質和Effect的了解

    引擎版本&#xff1a;3.8.5 環境&#xff1a; Windows 簡介 在Cocos Creator中&#xff0c;游戲炫彩繽紛的效果是借助著色器(Shader)來實現的。 Cocos主要基于OpenGL ES&#xff0c;而Shader的編寫則是在可編程渲染管線中基于修改&#xff1a;頂點著色器(Vertex) 和 片段著色…

    akka現有的分布式定時任務框架總結

    根據你的需求&#xff0c;以下是一些基于 Akka 實現的分布式定時任務框架&#xff0c;以及相關的 GitHub 項目推薦&#xff1a; 1. Openjob Openjob 是一個基于 Akka 架構的新一代分布式任務調度框架&#xff0c;支持多種定時任務、延時任務、工作流設計&#xff0c;采用無中…

    微信小程序地圖map全方位解析

    微信小程序地圖map全方位解析 微信小程序的 <map> 組件是一個功能強大的工具&#xff0c;可以實現地圖展示、定位、標注、路徑規劃等多種功能。以下是全方位解析微信小程序地圖組件的知識點&#xff1a; 一、地圖組件基礎 1. 引入 <map> 組件 在頁面的 .wxml 文…

    Python的PyTorch+CNN深度學習技術在人臉識別項目中的應用

    人臉識別技術是一種基于人臉特征進行身份識別的生物識別技術&#xff0c;其核心原理包括人臉檢測、人臉對齊、特征提取、特征匹配、身份識別。 一、應用場景 安防&#xff1a;門禁、監控。 金融&#xff1a;刷臉支付、身份驗證。 社交&#xff1a;自動標注、美顏。 醫療&am…

    《數據庫索引設計與優化》譯本錯誤糾正(1)

    今天在學習《數據庫索引設計與優化》第十一章第198頁的時候遇到一個問題&#xff0c;即參數的文字描述與實際不符。我看的是從網絡上找到的譯本&#xff0c;許多喜歡白嫖的朋友可能也會像我一樣遇到這種問題。 可以看到&#xff0c;上面對參數Z的描述是&#xff1a;Z上一次索引…