Redis 數據類型及應用場景

1、 redis 特色

  • 全部數據存儲在內存中,高速讀寫
  • 提供豐富多樣的數據類型:string、 hash、 set、 sorted set、bitmap、hyperloglog
  • 提供了 AOF 和 RDB 兩種數據的持久化保存方式,保證了 Redis 重啓後數據不丟失
  • Redis 的全部操做都是原子性的,還支持對幾個操做合併後的原子性操做,支持事務

 一般咱們都把數據存到關係型數據庫中,但爲了提高應用的性能,咱們應該把訪頻率高且不會常常變更的數據緩存到內存中。。Redis 沒有像 MySQL 這類關係型數據庫那樣強大的查詢功能,須要考慮如何把關係型數據庫中的數據,合理的對應到緩存的 key-value 數據結構中。redis

2、 設計 Redis Key

分段設計法

  使用冒號把 key 中要表達的多種含義分開表示,步驟以下:數據庫

  1. 把表名轉化爲 key 前綴
  2. 主鍵名(或其餘經常使用於搜索的字段)
  3. 主鍵值
  4. 要存儲的字段。

eg. 用戶表(user)json

id name email
1 zj 156577812@qq.com
2 ai 156577813@qq.com

這個簡單的表可能常常會有這個的需求:>根據用戶 id 查詢用戶郵箱地址,能夠選擇把郵箱地址這個數據存到 redis 中:緩存

set user:id:1:email 156577812@qq.com;
set user:id:2:email 156577812@qq.com;

3、 String數據類型的應用場景

1. 簡介

  string 類型是 Redis 中最基本的數據類型,最經常使用的數據類型,甚至被不少玩家當成 redis 惟一的數據類型去使用。string 類型在 redis 中是二進制安全(binary safe)的,這意味着 string 值關心二進制的字符串,不關心具體格式,你能夠用它存儲 json 格式或 JPEG 圖片格式的字符串。
  安全

2. 數據模型

  string 類型是基本的 Key-Value 結構,Key 是某個數據在 Redis 中的惟一標識,Value 是具體的數據。數據結構

Key Value
‘name’ ‘redis’
‘type’ ‘string’

3. 應用場景

(1) 存儲 MySQL 中某個字段的值

把 key 設計爲 表名:主鍵名:主鍵值:字段名
eg.性能

set user:id:1:email 156577812@qq.com
(2) 存儲對象

string 類型支持任何格式的字符串,應用最多的就是存儲 json 或其餘對象格式化的字符串。(這種場景下推薦使用 hash 數據類型)優化

set user:id:1 '[{"id":1,"name":"zj","email":"156577812@qq.com"},{"id":1,"name":"zj","email":"156577812@qq.com"}]'
(3) 生成自增 id

當 redis 的 string 類型的值爲整數形式時,redis 能夠把它當作是整數同樣進行自增(incr)自減(decr)操做。因爲 redis 全部的操做都是原子性的,因此沒必要擔憂多客戶端鏈接時可能出現的事務問題。spa

4、hash 數據類型的應用場景

1. 簡介

  hash 類型很像一個關係型數據庫的數據表,hash 的 Key 是一個惟一值,Value 部分是一個 hashmap 的結構。
  設計

2. 數據模型

  假設有一張數據庫表以下:

id name type
1 redis hash

  若是要用 redis 的 hash 結構存儲,數據模型以下:

clipboard.png

  hash數據類型在存儲上述類型的數據時具備比 string 類型更靈活、更快的優點,具體的說,使用 string 類型存儲,必然須要轉換和解析 json 格式的字符串,即使不須要轉換,在內存開銷方面,仍是 hash 佔優點。
  

3. 應用場景

hash 類型十分適合存儲對象類數據,相對於在 string 中介紹的把對象轉化爲 json 字符串存儲,hash 的結構能夠任意添加或刪除‘字段名’,更加高效靈活。

hmset user:1 name zj email 156577812@qq.com

5、list 數據類型的應用場景

1. 簡介

  list 是按照插入順序排序的字符串鏈表,能夠在頭部和尾部插入新的元素(雙向鏈表實現,兩端添加元素的時間複雜度爲 O(1))。插入元素時,若是 key 不存在,redis 會爲該 key 建立一個新的鏈表,若是鏈表中全部的元素都被移除,該 key 也會從 redis 中移除。

2. 數據模型

clipboard.png

  常見操做時用 lpush 命令在 list 頭部插入元素, 用 rpop 命令在 list 尾取出數據。
  

3. 應用場景

(1) 消息隊列

  redis 的 list 數據類型對於大部分使用者來講,是實現隊列服務的最經濟,最簡單的方式。
  

(2) 「最新內容」

由於 list 結構的數據查詢兩端附近的數據性能很是好,因此適合一些須要獲取最新數據的場景,好比新聞類應用的 「最近新聞」。
  

4.優化建議

(1) list 是鏈表結構,全部若是在頭部和尾部插入數據,性能會很是高,不受鏈表長度的影響;但若是在鏈表中插入數據,性能就會愈來愈差。

6、set 數據類型的應用場景

1. 簡介

  set 數據類型是一個集合(沒有排序,不重複),能夠對 set 類型的數據進行添加、刪除、判斷是否存在等操做(時間複雜度是 O(1) )
  set 集合不容許數據重複,若是添加的數據在 set 中已經存在,將只保留一份。
  set 類型提供了多個 set 之間的聚合運算,如求交集、並集、補集,這些操做在 redis 內部完成,效率很高。

2. 數據模型

clipboard.png

3. 應用場景

  set 類型的特色是——不重複且無序的一組數據,而且具備豐富的計算功能,在一些特定的場景中能夠高效的解決通常關係型數據庫不方便作的工做。

1. 「共同好友列表」

  社交類應用中,獲取兩我的或多我的的共同好友,兩我的或多我的共同關注的微博這樣相似的功能,用 MySQL 的話操做很複雜,能夠把每一個人的好友 id 存到集合中,獲取共同好友的操做就能夠簡單到一個取交集的命令就搞定。

// 這裏爲了方便閱讀,把 id 替換成姓名
sadd user:wade james melo paul kobe
sadd user:james wade melo paul kobe
sadd user:paul wade james melo kobe
sadd user:melo wade james paul kobe

// 獲取 wade 和 james 的共同好友
sinter user:wade user:james
/* 輸出:
 *      1) "kobe"
 *      2) "paul"
 *      3) "melo"
 */
 
 // 獲取香蕉四兄弟的共同好友
 sinter user:wade user:james user:paul user:melo
 /* 輸出:
 *      1) "kobe"
 */
 
 /*
     相似的需求還有不少 , 必須把每一個標籤下的文章 id 存到集合中,能夠很容易的求出幾個不一樣標籤下的共同文章;
 把每一個人的愛好存到集合中,能夠很容易的求出幾我的的共同愛好。 
 */

7、sorted set 數據類型的應用場景

1.簡介

  在 set 的基礎上給集合中每一個元素關聯了一個分數,往有序集合中插入數據時會自動根據這個分數排序。

2.應用場景

  在集合類型的場景上加入排序就是有序集合的應用場景了。好比根據好友的「親密度」排序顯示好友列表。

// 用元素的分數(score)表示與好友的親密度
zadd user:kobe 80 james 90 wade  85 melo  90 paul

// 根據「親密度」給好友排序
zrevrange user:kobe 0 -1

/**
 * 輸出:
 *      1) "wade"
 *      2) "paul"
 *      3) "melo"
 *      4) "james"
 */
 
// 增長好友的親密度
zincrby user:kobe 15 james

// 再次根據「親密度」給好友排序
zrevrange user:kobe 0 -1

/**
 * 輸出:
 *      1) "james"
 *      2) "wade"
 *      3) "paul"
 *      2) "melo"
 */
 
 //相似的需求還出如今根據文章的閱讀量或點贊量對文章列表排序
相關文章
相關標籤/搜索