【Redis】五種數據類型及其使用場景

Redis 數據類型

五種類型與類比java的模型

  • string --> String
  • hash --> Hashmap
  • list --> LinkList
  • set --> HashSet
  • sorted_set --> TreeSet

String類型

redis 數據存儲格式

  • redis自身是一個Map類型的存儲方式,其中所有的數據都是採用key:value的形式存儲
  • 我們討論的數據類型指的是存儲的數據的類型,也就是value部分的類型,key部分永遠都是字符串

String基本信息

存儲的數據:單個數據,最簡單的數據存儲類型,也是最常用的數據存儲類型
存儲數據的格式:一個存儲空間保存一個數據
存儲內容:通常使用字符串,如果字符串以整數的形式展示,可以作爲數字操作使用(但是仍是字符串)

常用命令

  • 添加/修改數據
set key value
  • 獲取數據
get key
  • 刪除數據
del key

在這裏插入圖片描述

  • 添加/修改多個數據
mset key1 valueq key2 value2 …
  • 獲取多個數據
mget key1 key2 …

在這裏插入圖片描述

  • 獲取數據字符個數(字符串長度)
strlen key
  • 追加信息到原始信息後部(如果原始信息存在就追加,否則新建)
append key value

在這裏插入圖片描述

String類型作爲數值時的增減

業務場景1

大型企業級應用中,分表操作是基本操作,使用多張表存儲同類型數據,但是對應的主鍵id必須保證統一性,不能重複。
Oracle數據庫具有sequence設定,可以解決該問題,但是MySQL數據庫並不具有類似的機制,那麼如何解決?

解決方案

  • 設置數值數據增加指定範圍的值
incr key 			//自增1
incrby key increment  //增加指定數值
incrbyfloat key increment  //增加一個浮點數

在這裏插入圖片描述

  • 設置數值數據減少指定範圍的值
decr key 			//自減1
decrby key increment //減少指定數值

在這裏插入圖片描述

String作爲數值操作時的注意事項
  1. string在redis內部存儲默認就是一個字符串,當遇到增減類操作incr,decr時會轉成數值型進行計算
  2. redis所有的操作都是原子性的,採用單線程處理所有業務,命令是一個一個執行的,因此無需考慮併發帶來的數據影響。
  3. 按數值進行操作的數據,如果原始數據不能轉成數值,或超過了redis數值上線範圍,將會報錯。9223372036854775807 (java中long型數據最大值,Long.MAX_VALUE)

String 數據時效性設置

業務場景2

場景一:“某某綜藝”,啓動海選投票,只能通過微信投票,每個微信號每4個小時只能投1票。

場景二:電商商家開啓熱門商品推薦,熱門商品不能一直處於熱門期,每種商品熱門期維持3天,3天后自動取消熱門

場景三:新聞網站會出現熱點新聞,熱點新聞最大的特徵是對時效性,如何自動控制熱點新聞的時效性

解決思路

給用戶設置一個唯一的id,併爲其設置一個有效時長,當時間已經超過設定時間後將id刪除。

解決方案

設置數據具有指定的聲明週期

redis 控制數據的生命週期,通過數據是否失效控制業務行爲,適用於所有具有時效性限定控制的操作:

setex key seconds value //增加、修改鍵值對併爲其設定生命週期
psetex key milliseconds value //功能與上面一直,秒的單位不同

示例

String 類型的注意事項

數據操作成功與否的反饋

1、表示運行結果是否成功
 (integer)0 –> false 失敗
 (integer)1 –> true 成功

2、表示運行結果值
 (integer)3 –> 3 3個
 (integer)1 –> 1 1個
 數據未獲取到

(nil)等同於null

String類型之高熱度數據訪問加速

業務場景3

主頁高頻訪問信息顯示控制,例如微博大V主頁顯示粉絲數與微博數量,這些數據就是熱度數據,不斷髮生變化,這些數據如何放入Redis?
在這裏插入圖片描述

解決方案

兩種實現方式:

  • 在Redis中爲大V用戶設定用戶信息,以用戶主鍵和屬性值作爲key,後臺設定時間定時刷新即可。

    • user: id :5765898790:focuss:3050
    • user: id :5765898790:fans:117492300
    • user: id :5765898790:blogs:117744
  • 在Redis中以json格式存儲大V用戶,定時刷新。

    • set user: id :5765898790 {id:5765898790,focuss:3050,fans:117492300,blogs:117744}
數據庫中的熱點數據key命名慣例:

在這裏插入圖片描述

hash類型

String類型存儲的困惑
對象類數據的存儲如果具有較爲頻繁的更新需求,操作會顯得笨重,存容易,改麻煩。
爲了區別與Redis中的鍵值對的稱呼,hash中的鍵成爲field,而key特徵Redis的鍵。
在這裏插入圖片描述
hash類型
新的存儲需求:對一系列存儲的數據進行編組,方便管理,典型應用存儲對象信息
需要的內存結構:一個存儲空間保存多少個鍵值對數據
hash類型:底層使用哈希表結構實現數據存儲

基本操作

  • 添加/修改數據

hset key field value

  • 獲取數據

hget key field
hgetall key

  • 刪除數據

hdel key field1 [field2]

實例:
在這裏插入圖片描述

  • 添加/修改多個數據

hmset key field1 value1 field2 calue2

  • 獲取多個數據

hmget key field1 field2 …

  • 獲取哈希表中字段的數量

hlen key

  • 獲取哈希表中是否存在指定的字段

hexists key field

在這裏插入圖片描述

hash類型數據擴展操作

獲取哈希表中所有的字段名和字段值

hkeys key //字段名
hvals key //字段值

在這裏插入圖片描述

設置指定字段的數值數據增加指定範圍的值

hincrby key field increment //指定數值增長指定的數
hincrbyfloat key field increment

user1年齡增加2歲,再增加0.5歲:
在這裏插入圖片描述

hash類型數據操作的注意事項

  • hash類型下的value只能存儲字符串,不允許存儲其他類型數據,不存在嵌套現象。如果數據未獲取到,對應的值爲(nil)
  • 每個hash可以存儲232-1個鍵值對
  • hash類型十分貼近對象的數據存儲形式,並且可以靈活添加刪除對象屬性。但hash設計不是爲了存儲大量對象的,切記不可濫用,更不可以將hash作爲對象列表使用
  • hgetall操作可以獲取全部屬性,如果內部fiekd過多,遍歷整體數據效率就會很低,有可能成爲數據訪問瓶頸。

hash類型應用場景購物車

業務場景:電商網站購物車的設計與實現。
在這裏插入圖片描述

解決方案:

在這裏插入圖片描述
例如創建一個購物車:
在這裏插入圖片描述
當前僅僅是將數據存儲到redis中,並沒有起到加速的所用,因爲我們僅僅查詢到了用戶的id和商品的id,顯示的時候顯示的用戶名和商品的名稱,商品信息還需要二次查詢數據庫。

  • 每條購物車中的商品記錄保存成兩條field

  • field1 專用於保存購買數量
    1、命名格式:商品id:nums
    2、保存數據:數值

  • field2 專用於保存購物車中顯示的信息,包含文字描述,圖片地址,所屬商家信息等等
    1、命名格式:商品id:info
    2、保存數據:json
    在這裏插入圖片描述
    但是出現很多用戶都將同一個商品假如購物車,就會出現大量的重複信息,例如商品信息重複:
    在這裏插入圖片描述
    因此我們可以將商品的信息單獨的保存成一個哈希。

創建數據,如果有則不再創建,如果沒有則創建

hsetnx key field value

在這裏插入圖片描述

Hash實現搶購,限購發放優惠券,激活碼等

在這裏插入圖片描述

解決方案

  • 以商家id作爲key
  • 將參與搶購的商品id作爲field
  • 將參與搶購的商品數量作爲對應的value
  • 搶購時使用降至的方式控制產品數量

list

數據存儲需求:存儲多個數據,並對數據進入存儲空間的順序進行區分
需要的存儲數據:一個存儲空間保存多個數據,且通過數據可以體現進入順序
list類型:保存多個數據,底層使用雙向鏈表存儲結構實現
在這裏插入圖片描述

  • 添加/修改數據

lpush key value1 [value2] …
rpush key value1 [value2] …

在這裏插入圖片描述

  • 獲取數據

lrange key start stop //獲取從左數第start到stop個元素,從0開始
lindex key index //查詢第i個元素
llen key //list的長度
在這裏插入圖片描述

  • 獲取並移除數據

lpop key //獲取並刪除左邊第一個元素
rpop key //獲取並刪除右邊第一個元素

list 類型數組擴展操作
  • 規定時間內獲取並移除數據

blpop key1 [key2] timeout
brpop key1 [key2] timeout

阻塞式獲取,在規定時間內獲取這個值,規定時間內如果還沒有的時候可以等,直到有值就可以獲取到獲取超時獲取爲空。
開兩個客戶端,一個設置15s內獲取list1中的值,此時list1位空一直等待(阻塞),在15秒內另一個客戶端存入到list1中數據,此時就被獲取到。
在這裏插入圖片描述

業務場景

微信朋友圈點贊,要求按照點贊順序顯示點贊好友信息。
如果取消點贊,移除對應好友信息。
在這裏插入圖片描述

解決方案

  • 移除指定數據

lrem key count value //count爲移除的數量,value爲移除哪個值

在這裏插入圖片描述

list類型數據操作注意事項

  • list 中保存的數據都是string類型的,數據總容量式是有限的,最多232-1個元素(4294967295)
  • list具有索引的概念,但是操作數據時候通常以隊列的形式進行入隊出隊操作,或以棧的形式進入棧出棧的操作
  • 獲取全部數據操作結束索引設置爲-1
  • list 可以對數據進行分頁操作,通過第一頁的信息來自list,第2頁及更多的信息通過數據庫的形式加載

list類型應用場景

業務場景-最新消息的展示

  • twitter、新浪微博、騰訊微博中個人用於的關注列表需要按照用戶的關注順序進行展示,粉絲列表需要將最近關注的粉絲列在前面
    在這裏插入圖片描述
  • 新聞、資訊類網站如何將最新的新聞或資訊按照發生的事件順序展示
  • 企業運營過程中,系統將產生出大量的運營數據,如何保障墮胎服務器操作日誌的統一順序輸出?

解決方案

  • 依賴list的數據具有順序的特徵對信息進行管理
  • 使用隊列模型解決多路信息彙總合併的問題
  • 使用棧模型解決最新消息的問題

Set

  • 新的存儲需求:存儲大量的數據,在查詢方面提供更高的效率
  • 需要的存儲結構:能夠保存大量的數據,搞笑的內部存儲機制,便於查詢
  • set類型:與hash存儲結構完全相同,僅存儲鍵,不存儲值(nil),並且值式不允許重複的。也就是隻有鍵沒有值的hash

Set的基本操作

  • 添加數據

sadd key menber1 [member2]

  • 獲取全部數據

smembers key

  • 刪除數據

srem key member1 [member2]

  • 獲取集合數據總量

scard key

  • 判斷集合中是否包含指定數據

sismember key member

在這裏插入圖片描述

set類型數據的擴展操作

業務場景-隨機操作數據

每位用戶首次使用進入頭條時候會設置3項愛好的內容,但是後期爲了增加用戶的活躍度,興趣點,必須讓用戶對其他信息類別逐漸產生興趣,增加客戶留存度,如何實現?

業務分析

  • 系統分析出各個分類的最新或最熱點信息條目並組織成set集合
  • 隨機挑選其中部分信息
  • 配合用戶關注信息分類中的熱點信息組織展示的全信息集合

解決方案

  • 隨機獲取集合中指定數量的數據

srandmember key [count]

  • 隨機獲取集合中的某個數據並將該數據移出集合

spop key

在這裏插入圖片描述

redis應用於隨機推薦類信息檢索,例如熱點歌單推薦,熱點新聞推薦,熱點旅遊線路,應用APP推薦,大V推薦等。

業務場景-共同好友

在這裏插入圖片描述
例如:
在這裏插入圖片描述

解決方案

  • 求兩個集合的交、並、差集

sinter key1 [key2] //交集
sunion key1 [key2] //並集
sdiff key1 [key2] //差集(key1有但是key2沒有的)

  • 求兩個集合的交、並、差集並存儲到指定集合中

sinterstore destination key1 [key2]
sunionstore destination key1 [key2]
sdiffstore destination key1 [key2]

  • 將指定數據從原始集合移動到目標集合中

smove source destination member

redis應用於同類信息的關聯搜索,二度關聯搜索,深度關聯搜索

  • 顯示共同關注(一度)
  • 顯示共同好友(一度)
  • 由用戶A出發,獲取到好友用戶B的好友信息列表(一度)
  • 由用戶A出發,獲取到好友用戶B的購物清單列表(二度)
  • 由用戶A出發,獲取到好友用戶B的遊戲充值列表(二度)

Set類型數據操作的注意事項

set類型不允許數據重複,如果添加的數據在set中已經存在,將只保留一份
set雖然與hash的存儲結構相同,但是無法啓用hash中存儲值的空間

業務場景-同類型不重複數據的合併操作

在這裏插入圖片描述

解決方案

依賴set集合數據不重複的特徵,依賴set集合hash存儲結構特徵完成數據過濾與快速查詢

  • 根據用戶id獲取用戶所有角色
  • 根據用戶所有角色獲取用戶所有操作權限放入set集合
  • 根據用戶所有覺得獲取用戶所有數據全選放入set集合

兩種方法,其中第二種耦合度太高:
在這裏插入圖片描述

set業務場景-訪問量統計去重

在這裏插入圖片描述

解決方案

針對不同的統計類型有不同的數據存儲方式:

  • 利用set集合的數據去重特徵,記錄各種訪問數據
  • 建立string類型數據,利用incr統計日訪問量(PV)
  • 建立set模型,記錄不同cookie數量(UV)
  • 建立set模型,記錄不用IP數量(IP)

set業務場景-黑白名單

在這裏插入圖片描述

解決方案

  • 基於經營戰略設定問題用戶發現、鑑別規則
  • 週期性更行滿足規則的用戶黑名單,加入set集合
  • 用戶行爲信息達到後與黑名單進行比比對,確認行爲去向
  • 黑名單過濾IP地址:應用於開放遊客訪問權限的信息源
  • 黑名單過濾設備信息:應用於限定訪問設備的信息源
  • 黑名單過濾用戶:應用於基於訪問權限的信息源

sorted_set類型

  • 新的存儲需求:根據排序有利於數據的有效顯示,需要提供一種可以根據自身特徵進行排序的方式。
  • 需要的存儲結構:新的存儲模型,可以保存可排序的數據。
  • sorted_set類型:在set的存儲結構基礎上添加可排序字段。

在這裏插入圖片描述
score只存儲其順序。

sorted_set類型數據的基本操作

  • 添加數據

zadd key score1 member1 [score2 member2]

  • 獲取全部數據

zrange key start stop [WITHSCORES]//按照從小到大的順序,加上WITHSCORES,就會帶上scores一起顯示
zrevrange key start stop [WITHSCORES]//按照從大到小的順序

  • 刪除數據

zrem key member [member …]

在這裏插入圖片描述

  • 按條件獲取數據
//查詢scores在某個範圍內的值
zrangebyscore key min max [WITHSCORES] [LIMIT]
//查詢key某個索引範圍內的值
zrevrangebyscore key max min [WITHSCORES]
  • 條件刪除
zremrangebyrank key start stop
zremrangebyscore key min max

注意:

  • min與max用於限定搜索查詢的條件
  • start與stop用於限定查詢範圍,作用於索引,表示開始和結束索引
  • offset與count用於限定查詢範圍,作用於查詢結果,表示開始位置和數據總量

獲取集合數據總量

zcard key //獲取總量
zcount key min max //獲取某一個範圍的總量

  • 集合交、並存儲操作

zinterstore destination numkeys key [key …] //求和
zunionstore destination numkeys key [key …]
在這裏插入圖片描述

sorted_set 類型數據的擴展操作

業務場景- 建立排序依據

在這裏插入圖片描述
在這裏插入圖片描述

解決方案

  • 獲取數據對應的索引(排名)

zrank key member //正數第幾位
zrevrank key member //倒數第幾位

在這裏插入圖片描述

  • score 值獲取與修改

zscore key member //獲取
zincrby key increment member //score遞增 increment

sorted_set 類型數據操作的注意事項

  • score 保存的數據存儲空間是64位
  • score保存的數據也可以是一個雙精度的double值,基於雙精度浮點數的特徵,可能會丟失精度,使用時侯要慎重
  • sorted_set底層存儲還是基於set結構的,因此數據不能重複,如果重複添加相同的數據,score值將被反覆覆蓋,保留最後一次修改的結果

業務場景-會員短期體驗之過期失效

在這裏插入圖片描述

解決方案

  • 對於基於時間線限定的任務處理,將處理時間記錄爲score值,利用排序功能區分處理的先後順序
  • 記錄下一個要處理的事件,當對比系統時間發現當然仍後到期後移除redis中的記錄,並記錄下一個要處理的時間
  • 當新任務加入時,判定並更新當前下一個要處理的任務時間
  • 爲提升sorted_set的性能,通常將任務根據特徵存儲成若干個sorted_set.例如1小時內,1天內,年度等,操作時逐漸提升,將即將操作的若干個任務納入到1小時內處理隊列中
  • time命令獲取當前系統時間

數據類型實踐案例

按次調用-計數器在這裏插入圖片描述

如何實現這個每分鐘只能調用10次呢?

解決方案

  • 設計計數器,記錄調用次數,用於控制業務執行次數。以用戶id作爲key,使用此時作爲value
  • 在調用前獲取次數,判斷是否超過限定次數,不超過次數的情況下,每次調用計數+1,業務調用失敗,不遞增
  • 爲了計數器設置生命週期爲指定週期,例如10次/分鐘,自動清空週期內使用次數。

解決方案改良

在這裏插入圖片描述
利用可以存儲的最大值是9223372036854775807,超過這個值就會拋出異常的特性。假如一分鐘只能訪問5次,可以將初始值設置爲9223372036854775802,每次訪問都加1,訪問5次後這個數就會溢出異常。
在這裏插入圖片描述

微信會話

在這裏插入圖片描述

解決方案

  • 依賴list的數據具有順序的特徵對消息進行管理,將list結構作爲棧使用
    對指定與普通會話分別創建獨立的list分別管理
  • 當某個list中接收到用戶消息後,將消息發送方的id從list的一側加入list(此處設定左側)
  • 多個相同id發出的消息反覆入棧會出現問題,在入棧之前無論是否具有當前id對應得消息,先刪除對應id
  • 推送消息時先推送頂置會話list,再推送普通會話list,推送完成的list清除所有數據
  • 消息的數量,也就是微信用戶對話數量採用計數器的思想另行記錄,伴隨list操作同步更新

應用總結

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章