自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Redis 八種常用數(shù)據(jù)類型常用命令和應(yīng)用場(chǎng)景

數(shù)據(jù)庫(kù) Redis
String 是一種二進(jìn)制安全的數(shù)據(jù)類型,可以用來(lái)存儲(chǔ)任何類型的數(shù)據(jù)比如字符串、整數(shù)、浮點(diǎn)數(shù)、圖片(圖片的 base64 編碼或者解碼或者圖片的路徑)、序列化后的對(duì)象。

夯實(shí)基礎(chǔ),通過(guò)這篇文章帶著大家簡(jiǎn)單回顧一下 Redis 中的 8 種常用數(shù)據(jù)類型:

  • 5 種基礎(chǔ)數(shù)據(jù)類型:String(字符串)、List(列表)、Set(集合)、Hash(散列)、Zset(有序集合)。
  • 3 種特殊數(shù)據(jù)類型:HyperLogLog(基數(shù)統(tǒng)計(jì))、Bitmap (位圖)、Geospatial (地理位置)。

Redis 5 種基本數(shù)據(jù)類型

Redis 共有 5 種基本數(shù)據(jù)類型:String(字符串)、List(列表)、Set(集合)、Hash(散列)、Zset(有序集合)。

這 5 種數(shù)據(jù)類型是直接提供給用戶使用的,是數(shù)據(jù)的保存形式,其底層實(shí)現(xiàn)主要依賴這 8 種數(shù)據(jù)結(jié)構(gòu):簡(jiǎn)單動(dòng)態(tài)字符串(SDS)、LinkedList(雙向鏈表)、Dict(哈希表/字典)、SkipList(跳躍表)、Intset(整數(shù)集合)、ZipList(壓縮列表)、QuickList(快速列表)。

Redis 5 種基本數(shù)據(jù)類型對(duì)應(yīng)的底層數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)如下表所示:

String

List

Hash

Set

Zset

SDS

LinkedList/ZipList/QuickList

Dict、ZipList

Dict、Intset

ZipList、SkipList

Redis 3.2 之前,List 底層實(shí)現(xiàn)是 LinkedList 或者 ZipList。Redis 3.2 之后,引入了 LinkedList 和 ZipList 的結(jié)合 QuickList,List 的底層實(shí)現(xiàn)變?yōu)?QuickList。從 Redis 7.0 開始, ZipList 被 ListPack 取代。

你可以在 Redis 官網(wǎng)上找到 Redis 數(shù)據(jù)類型/結(jié)構(gòu)非常詳細(xì)的介紹:

  • Redis Data Structures[1]
  • Redis Data types tutorial[2]

未來(lái)隨著 Redis 新版本的發(fā)布,可能會(huì)有新的數(shù)據(jù)結(jié)構(gòu)出現(xiàn),通過(guò)查閱 Redis 官網(wǎng)對(duì)應(yīng)的介紹,你總能獲取到最靠譜的信息。

圖片圖片

String(字符串)

介紹

String 是 Redis 中最簡(jiǎn)單同時(shí)也是最常用的一個(gè)數(shù)據(jù)類型。

String 是一種二進(jìn)制安全的數(shù)據(jù)類型,可以用來(lái)存儲(chǔ)任何類型的數(shù)據(jù)比如字符串、整數(shù)、浮點(diǎn)數(shù)、圖片(圖片的 base64 編碼或者解碼或者圖片的路徑)、序列化后的對(duì)象。

圖片圖片

雖然 Redis 是用 C 語(yǔ)言寫的,但是 Redis 并沒有使用 C 的字符串表示,而是自己構(gòu)建了一種 簡(jiǎn)單動(dòng)態(tài)字符串(Simple Dynamic String,SDS)。相比于 C 的原生字符串,Redis 的 SDS 不光可以保存文本數(shù)據(jù)還可以保存二進(jìn)制數(shù)據(jù),并且獲取字符串長(zhǎng)度復(fù)雜度為 O(1)(C 字符串為 O(N)),除此之外,Redis 的 SDS API 是安全的,不會(huì)造成緩沖區(qū)溢出。

常用命令

命令

介紹

SET key value

設(shè)置指定 key 的值

SETNX key value

只有在 key 不存在時(shí)設(shè)置 key 的值

GET key

獲取指定 key 的值

MSET key1 value1 key2 value2 ……

設(shè)置一個(gè)或多個(gè)指定 key 的值

MGET key1 key2 ...

獲取一個(gè)或多個(gè)指定 key 的值

STRLEN key

返回 key 所儲(chǔ)存的字符串值的長(zhǎng)度

INCR key

將 key 中儲(chǔ)存的數(shù)字值增一

DECR key

將 key 中儲(chǔ)存的數(shù)字值減一

EXISTS key

判斷指定 key 是否存在

DEL key(通用)

刪除指定的 key

EXPIRE key seconds(通用)

給指定 key 設(shè)置過(guò)期時(shí)間

更多 Redis String 命令以及詳細(xì)使用指南,請(qǐng)查看 Redis 官網(wǎng)對(duì)應(yīng)的介紹:https://redis.io/commands/?group=string 。

基本操作:

> SET key value
OK
> GET key
"value"
> EXISTS key
(integer) 1
> STRLEN key
(integer) 5
> DEL key
(integer) 1
> GET key
(nil)

批量設(shè)置:

> MSET key1 value1 key2 value2
OK
> MGET key1 key2 # 批量獲取多個(gè) key 對(duì)應(yīng)的 value
1) "value1"
2) "value2"

計(jì)數(shù)器(字符串的內(nèi)容為整數(shù)的時(shí)候可以使用):

> SET number 1
OK
> INCR number # 將 key 中儲(chǔ)存的數(shù)字值增一
(integer) 2
> GET number
"2"
> DECR number # 將 key 中儲(chǔ)存的數(shù)字值減一
(integer) 1
> GET number
"1"

設(shè)置過(guò)期時(shí)間(默認(rèn)為永不過(guò)期):

> EXPIRE key 60
(integer) 1
> SETEX key 60 value # 設(shè)置值并設(shè)置過(guò)期時(shí)間
OK
> TTL key
(integer) 56

應(yīng)用場(chǎng)景

需要存儲(chǔ)常規(guī)數(shù)據(jù)的場(chǎng)景

  • 舉例:緩存 Session、Token、圖片地址、序列化后的對(duì)象(相比較于 Hash 存儲(chǔ)更節(jié)省內(nèi)存)。
  • 相關(guān)命令:SET、GET。

需要計(jì)數(shù)的場(chǎng)景

  • 舉例:用戶單位時(shí)間的請(qǐng)求數(shù)(簡(jiǎn)單限流可以用到)、頁(yè)面單位時(shí)間的訪問(wèn)數(shù)。
  • 相關(guān)命令:SET、GET、 INCR、DECR 。

分布式鎖

利用 SETNX key value 命令可以實(shí)現(xiàn)一個(gè)最簡(jiǎn)易的分布式鎖(存在一些缺陷,通常不建議這樣實(shí)現(xiàn)分布式鎖)。

List(列表)

介紹

Redis 中的 List 其實(shí)就是鏈表數(shù)據(jù)結(jié)構(gòu)的實(shí)現(xiàn)。我在 線性數(shù)據(jù)結(jié)構(gòu) :數(shù)組、鏈表、棧、隊(duì)列[3] 這篇文章中詳細(xì)介紹了鏈表這種數(shù)據(jù)結(jié)構(gòu),我這里就不多做介紹了。

許多高級(jí)編程語(yǔ)言都內(nèi)置了鏈表的實(shí)現(xiàn)比如 Java 中的 LinkedList,但是 C 語(yǔ)言并沒有實(shí)現(xiàn)鏈表,所以 Redis 實(shí)現(xiàn)了自己的鏈表數(shù)據(jù)結(jié)構(gòu)。Redis 的 List 的實(shí)現(xiàn)為一個(gè) 雙向鏈表,即可以支持反向查找和遍歷,更方便操作,不過(guò)帶來(lái)了部分額外的內(nèi)存開銷。

圖片圖片

常用命令

命令

介紹

RPUSH key value1 value2 ...

在指定列表的尾部(右邊)添加一個(gè)或多個(gè)元素

LPUSH key value1 value2 ...

在指定列表的頭部(左邊)添加一個(gè)或多個(gè)元素

LSET key index value

將指定列表索引 index 位置的值設(shè)置為 value

LPOP key

移除并獲取指定列表的第一個(gè)元素(最左邊)

RPOP key

移除并獲取指定列表的最后一個(gè)元素(最右邊)

LLEN key

獲取列表元素?cái)?shù)量

LRANGE key start end

獲取列表 start 和 end 之間 的元素

更多 Redis List 命令以及詳細(xì)使用指南,請(qǐng)查看 Redis 官網(wǎng)對(duì)應(yīng)的介紹:https://redis.io/commands/?group=list 。

通過(guò) RPUSH/LPOP 或者 LPUSH/RPOP實(shí)現(xiàn)隊(duì)列:

> RPUSH myList value1
(integer) 1
> RPUSH myList value2 value3
(integer) 3
> LPOP myList
"value1"
> LRANGE myList 0 1
1) "value2"
2) "value3"
> LRANGE myList 0 -1
1) "value2"
2) "value3"

通過(guò) RPUSH/RPOP或者LPUSH/LPOP 實(shí)現(xiàn)棧:

> RPUSH myList2 value1 value2 value3
(integer) 3
> RPOP myList2 # 將 list的最右邊的元素取出
"value3"

我專門畫了一個(gè)圖方便大家理解 RPUSH , LPOP , lpush , RPOP 命令:

圖片圖片

通過(guò) LRANGE 查看對(duì)應(yīng)下標(biāo)范圍的列表元素:

> RPUSH myList value1 value2 value3
(integer) 3
> LRANGE myList 0 1
1) "value1"
2) "value2"
> LRANGE myList 0 -1
1) "value1"
2) "value2"
3) "value3"

通過(guò) LRANGE 命令,你可以基于 List 實(shí)現(xiàn)分頁(yè)查詢,性能非常高!

通過(guò) LLEN 查看鏈表長(zhǎng)度:

> LLEN myList
(integer) 3

應(yīng)用場(chǎng)景

信息流展示

  • 舉例:最新文章、最新動(dòng)態(tài)。
  • 相關(guān)命令:LPUSH、LRANGE。

消息隊(duì)列

List 可以用來(lái)做消息隊(duì)列,只是功能過(guò)于簡(jiǎn)單且存在很多缺陷,不建議這樣做。

相對(duì)來(lái)說(shuō),Redis 5.0 新增加的一個(gè)數(shù)據(jù)結(jié)構(gòu) Stream 更適合做消息隊(duì)列一些,只是功能依然非常簡(jiǎn)陋。和專業(yè)的消息隊(duì)列相比,還是有很多欠缺的地方比如消息丟失和堆積問(wèn)題不好解決。

Hash(哈希)

介紹

Redis 中的 Hash 是一個(gè) String 類型的 field-value(鍵值對(duì)) 的映射表,特別適合用于存儲(chǔ)對(duì)象,后續(xù)操作的時(shí)候,你可以直接修改這個(gè)對(duì)象中的某些字段的值。

Hash 類似于 JDK1.8 前的 HashMap,內(nèi)部實(shí)現(xiàn)也差不多(數(shù)組 + 鏈表)。不過(guò),Redis 的 Hash 做了更多優(yōu)化。

圖片圖片

常用命令

命令

介紹

HSET key field value

設(shè)置指定哈希表中指定字段的值

HSETNX key field value

只有指定字段不存在時(shí)設(shè)置指定字段的值

HMSET key field1 value1 field2 value2 ...

同時(shí)將一個(gè)或多個(gè) field-value (域-值)對(duì)設(shè)置到指定哈希表中

HGET key field

獲取指定哈希表中指定字段的值

HMGET key field1 field2 ...

獲取指定哈希表中一個(gè)或者多個(gè)指定字段的值

HGETALL key

獲取指定哈希表中所有的鍵值對(duì)

HEXISTS key field

查看指定哈希表中指定的字段是否存在

HDEL key field1 field2 ...

刪除一個(gè)或多個(gè)哈希表字段

HLEN key

獲取指定哈希表中字段的數(shù)量

HINCRBY key field increment

對(duì)指定哈希中的指定字段做運(yùn)算操作(正數(shù)為加,負(fù)數(shù)為減)

更多 Redis Hash 命令以及詳細(xì)使用指南,請(qǐng)查看 Redis 官網(wǎng)對(duì)應(yīng)的介紹:https://redis.io/commands/?group=hash 。

模擬對(duì)象數(shù)據(jù)存儲(chǔ):

> HMSET userInfoKey name "guide" description "dev" age 24
OK
> HEXISTS userInfoKey name # 查看 key 對(duì)應(yīng)的 value中指定的字段是否存在。
(integer) 1
> HGET userInfoKey name # 獲取存儲(chǔ)在哈希表中指定字段的值。
"guide"
> HGET userInfoKey age
"24"
> HGETALL userInfoKey # 獲取在哈希表中指定 key 的所有字段和值
1) "name"
2) "guide"
3) "description"
4) "dev"
5) "age"
6) "24"
> HSET userInfoKey name "GuideGeGe"
> HGET userInfoKey name
"GuideGeGe"
> HINCRBY userInfoKey age 2
(integer) 26

應(yīng)用場(chǎng)景

對(duì)象數(shù)據(jù)存儲(chǔ)場(chǎng)景

  • 舉例:用戶信息、商品信息、文章信息、購(gòu)物車信息。
  • 相關(guān)命令:HSET (設(shè)置單個(gè)字段的值)、HMSET(設(shè)置多個(gè)字段的值)、HGET(獲取單個(gè)字段的值)、HMGET(獲取多個(gè)字段的值)。

Set(集合)

介紹

Redis 中的 Set 類型是一種無(wú)序集合,集合中的元素沒有先后順序但都唯一,有點(diǎn)類似于 Java 中的 HashSet 。當(dāng)你需要存儲(chǔ)一個(gè)列表數(shù)據(jù),又不希望出現(xiàn)重復(fù)數(shù)據(jù)時(shí),Set 是一個(gè)很好的選擇,并且 Set 提供了判斷某個(gè)元素是否在一個(gè) Set 集合內(nèi)的重要接口,這個(gè)也是 List 所不能提供的。

你可以基于 Set 輕易實(shí)現(xiàn)交集、并集、差集的操作,比如你可以將一個(gè)用戶所有的關(guān)注人存在一個(gè)集合中,將其所有粉絲存在一個(gè)集合。這樣的話,Set 可以非常方便的實(shí)現(xiàn)如共同關(guān)注、共同粉絲、共同喜好等功能。這個(gè)過(guò)程也就是求交集的過(guò)程。

圖片圖片

常用命令

命令

介紹

SADD key member1 member2 ...

向指定集合添加一個(gè)或多個(gè)元素

SMEMBERS key

獲取指定集合中的所有元素

SCARD key

獲取指定集合的元素?cái)?shù)量

SISMEMBER key member

判斷指定元素是否在指定集合中

SINTER key1 key2 ...

獲取給定所有集合的交集

SINTERSTORE destination key1 key2 ...

將給定所有集合的交集存儲(chǔ)在 destination 中

SUNION key1 key2 ...

獲取給定所有集合的并集

SUNIONSTORE destination key1 key2 ...

將給定所有集合的并集存儲(chǔ)在 destination 中

SDIFF key1 key2 ...

獲取給定所有集合的差集

SDIFFSTORE destination key1 key2 ...

將給定所有集合的差集存儲(chǔ)在 destination 中

SPOP key count

隨機(jī)移除并獲取指定集合中一個(gè)或多個(gè)元素

SRANDMEMBER key count

隨機(jī)獲取指定集合中指定數(shù)量的元素

更多 Redis Set 命令以及詳細(xì)使用指南,請(qǐng)查看 Redis 官網(wǎng)對(duì)應(yīng)的介紹:https://redis.io/commands/?group=set 。

基本操作:

> SADD mySet value1 value2
(integer) 2
> SADD mySet value1 # 不允許有重復(fù)元素,因此添加失敗
(integer) 0
> SMEMBERS mySet
1) "value1"
2) "value2"
> SCARD mySet
(integer) 2
> SISMEMBER mySet value1
(integer) 1
> SADD mySet2 value2 value3
(integer) 2
  • mySet : value1、value2 。
  • mySet2:value2、value3 。

求交集:

> SINTERSTORE mySet3 mySet mySet2
(integer) 1
> SMEMBERS mySet3
1) "value2"

求并集:

> SUNION mySet mySet2
1) "value3"
2) "value2"
3) "value1"

求差集:

> SDIFF mySet mySet2 # 差集是由所有屬于 mySet 但不屬于 A 的元素組成的集合
1) "value1"

應(yīng)用場(chǎng)景

需要存放的數(shù)據(jù)不能重復(fù)的場(chǎng)景

  • 舉例:網(wǎng)站 UV 統(tǒng)計(jì)(數(shù)據(jù)量巨大的場(chǎng)景還是 HyperLogLog更適合一些)、文章點(diǎn)贊、動(dòng)態(tài)點(diǎn)贊等場(chǎng)景。
  • 相關(guān)命令:SCARD(獲取集合數(shù)量) 。

圖片圖片

需要獲取多個(gè)數(shù)據(jù)源交集、并集和差集的場(chǎng)景

  • 舉例:共同好友(交集)、共同粉絲(交集)、共同關(guān)注(交集)、好友推薦(差集)、音樂(lè)推薦(差集)、訂閱號(hào)推薦(差集+交集) 等場(chǎng)景。
  • 相關(guān)命令:SINTER(交集)、SINTERSTORE (交集)、SUNION (并集)、SUNIONSTORE(并集)、SDIFF(差集)、SDIFFSTORE (差集)。

圖片圖片

需要隨機(jī)獲取數(shù)據(jù)源中的元素的場(chǎng)景

  • 舉例:抽獎(jiǎng)系統(tǒng)、隨機(jī)點(diǎn)名等場(chǎng)景。
  • 相關(guān)命令:SPOP(隨機(jī)獲取集合中的元素并移除,適合不允許重復(fù)中獎(jiǎng)的場(chǎng)景)、SRANDMEMBER(隨機(jī)獲取集合中的元素,適合允許重復(fù)中獎(jiǎng)的場(chǎng)景)。

Sorted Set(有序集合)

介紹

Sorted Set 類似于 Set,但和 Set 相比,Sorted Set 增加了一個(gè)權(quán)重參數(shù) score,使得集合中的元素能夠按 score 進(jìn)行有序排列,還可以通過(guò) score 的范圍來(lái)獲取元素的列表。有點(diǎn)像是 Java 中 HashMap 和 TreeSet 的結(jié)合體。

圖片圖片

常用命令

命令

介紹

ZADD key score1 member1 score2 member2 ...

向指定有序集合添加一個(gè)或多個(gè)元素

ZCARD KEY

獲取指定有序集合的元素?cái)?shù)量

ZSCORE key member

獲取指定有序集合中指定元素的 score 值

ZINTERSTORE destination numkeys key1 key2 ...

將給定所有有序集合的交集存儲(chǔ)在 destination 中,對(duì)相同元素對(duì)應(yīng)的 score 值進(jìn)行 SUM 聚合操作,numkeys 為集合數(shù)量

ZUNIONSTORE destination numkeys key1 key2 ...

求并集,其它和 ZINTERSTORE 類似

ZDIFFSTORE destination numkeys key1 key2 ...

求差集,其它和 ZINTERSTORE 類似

ZRANGE key start end

獲取指定有序集合 start 和 end 之間的元素(score 從低到高)

ZREVRANGE key start end

獲取指定有序集合 start 和 end 之間的元素(score 從高到底)

ZREVRANK key member

獲取指定有序集合中指定元素的排名(score 從大到小排序)

更多 Redis Sorted Set 命令以及詳細(xì)使用指南,請(qǐng)查看 Redis 官網(wǎng)對(duì)應(yīng)的介紹:https://redis.io/commands/?group=sorted-set 。

基本操作:

> ZADD myZset 2.0 value1 1.0 value2
(integer) 2
> ZCARD myZset
2
> ZSCORE myZset value1
2.0
> ZRANGE myZset 0 1
1) "value2"
2) "value1"
> ZREVRANGE myZset 0 1
1) "value1"
2) "value2"
> ZADD myZset2 4.0 value2 3.0 value3
(integer) 2
  • myZset : value1(2.0)、value2(1.0) 。
  • myZset2:value2 (4.0)、value3(3.0) 。

獲取指定元素的排名:

> ZREVRANK myZset value1
0
> ZREVRANK myZset value2
1

求交集:

> ZINTERSTORE myZset3 2 myZset myZset2
1
> ZRANGE myZset3 0 1 WITHSCORES
value2
5

求并集:

> ZUNIONSTORE myZset4 2 myZset myZset2
3
> ZRANGE myZset4 0 2 WITHSCORES
value1
2
value3
3
value2
5

求差集:

> ZDIFF 2 myZset myZset2 WITHSCORES
value1
2

應(yīng)用場(chǎng)景

需要隨機(jī)獲取數(shù)據(jù)源中的元素根據(jù)某個(gè)權(quán)重進(jìn)行排序的場(chǎng)景

  • 舉例:各種排行榜比如直播間送禮物的排行榜、朋友圈的微信步數(shù)排行榜、王者榮耀中的段位排行榜、話題熱度排行榜等等。
  • 相關(guān)命令:ZRANGE (從小到大排序)、 ZREVRANGE (從大到小排序)、ZREVRANK (指定元素排名)。

圖片圖片

需要存儲(chǔ)的數(shù)據(jù)有優(yōu)先級(jí)或者重要程度的場(chǎng)景 比如優(yōu)先級(jí)任務(wù)隊(duì)列。

  • 舉例:優(yōu)先級(jí)任務(wù)隊(duì)列。
  • 相關(guān)命令:ZRANGE (從小到大排序)、 ZREVRANGE (從大到小排序)、ZREVRANK (指定元素排名)。

總結(jié)

數(shù)據(jù)類型

說(shuō)明

String

一種二進(jìn)制安全的數(shù)據(jù)類型,可以用來(lái)存儲(chǔ)任何類型的數(shù)據(jù)比如字符串、整數(shù)、浮點(diǎn)數(shù)、圖片(圖片的 base64 編碼或者解碼或者圖片的路徑)、序列化后的對(duì)象。

List

Redis 的 List 的實(shí)現(xiàn)為一個(gè)雙向鏈表,即可以支持反向查找和遍歷,更方便操作,不過(guò)帶來(lái)了部分額外的內(nèi)存開銷。

Hash

一個(gè) String 類型的 field-value(鍵值對(duì)) 的映射表,特別適合用于存儲(chǔ)對(duì)象,后續(xù)操作的時(shí)候,你可以直接修改這個(gè)對(duì)象中的某些字段的值。

Set

無(wú)序集合,集合中的元素沒有先后順序但都唯一,有點(diǎn)類似于 Java 中的 HashSet 。

Zset

和 Set 相比,Sorted Set 增加了一個(gè)權(quán)重參數(shù) score,使得集合中的元素能夠按 score 進(jìn)行有序排列,還可以通過(guò) score 的范圍來(lái)獲取元素的列表。有點(diǎn)像是 Java 中 HashMap 和 TreeSet 的結(jié)合體。

Redis 3 種特殊的數(shù)據(jù)類型

除了 5 種基本的數(shù)據(jù)類型之外,Redis 還支持 3 種特殊的數(shù)據(jù)類型:Bitmap、HyperLogLog、GEO。

Bitmap (位圖)

介紹

根據(jù)官網(wǎng)介紹:

Bitmaps are not an actual data type, but a set of bit-oriented operations defined on the String type which is treated like a bit vector. Since strings are binary safe blobs and their maximum length is 512 MB, they are suitable to set up to 2^32 different bits.

Bitmap 不是 Redis 中的實(shí)際數(shù)據(jù)類型,而是在 String 類型上定義的一組面向位的操作,將其視為位向量。由于字符串是二進(jìn)制安全的塊,且最大長(zhǎng)度為 512 MB,它們適合用于設(shè)置最多 2^32 個(gè)不同的位。

Bitmap 存儲(chǔ)的是連續(xù)的二進(jìn)制數(shù)字(0 和 1),通過(guò) Bitmap, 只需要一個(gè) bit 位來(lái)表示某個(gè)元素對(duì)應(yīng)的值或者狀態(tài),key 就是對(duì)應(yīng)元素本身 。我們知道 8 個(gè) bit 可以組成一個(gè) byte,所以 Bitmap 本身會(huì)極大的節(jié)省儲(chǔ)存空間。

你可以將 Bitmap 看作是一個(gè)存儲(chǔ)二進(jìn)制數(shù)字(0 和 1)的數(shù)組,數(shù)組中每個(gè)元素的下標(biāo)叫做 offset(偏移量)。

圖片圖片

常用命令

命令

介紹

SETBIT key offset value

設(shè)置指定 offset 位置的值

GETBIT key offset

獲取指定 offset 位置的值

BITCOUNT key start end

獲取 start 和 end 之前值為 1 的元素個(gè)數(shù)

BITOP operation destkey key1 key2 ...

對(duì)一個(gè)或多個(gè) Bitmap 進(jìn)行運(yùn)算,可用運(yùn)算符有 AND, OR, XOR 以及 NOT

Bitmap 基本操作演示:

# SETBIT 會(huì)返回之前位的值(默認(rèn)是 0)這里會(huì)生成 7 個(gè)位
> SETBIT mykey 7 1
(integer) 0
> SETBIT mykey 7 0
(integer) 1
> GETBIT mykey 7
(integer) 0
> SETBIT mykey 6 1
(integer) 0
> SETBIT mykey 8 1
(integer) 0
# 通過(guò) bitcount 統(tǒng)計(jì)被被設(shè)置為 1 的位的數(shù)量。
> BITCOUNT mykey
(integer) 2

應(yīng)用場(chǎng)景

需要保存狀態(tài)信息(0/1 即可表示)的場(chǎng)景

  • 舉例:用戶簽到情況、活躍用戶情況、用戶行為統(tǒng)計(jì)(比如是否點(diǎn)贊過(guò)某個(gè)視頻)。
  • 相關(guān)命令:SETBIT、GETBIT、BITCOUNT、BITOP。

HyperLogLog(基數(shù)統(tǒng)計(jì))

介紹

HyperLogLog 是一種有名的基數(shù)計(jì)數(shù)概率算法 ,基于 LogLog Counting(LLC)優(yōu)化改進(jìn)得來(lái),并不是 Redis 特有的,Redis 只是實(shí)現(xiàn)了這個(gè)算法并提供了一些開箱即用的 API。

Redis 提供的 HyperLogLog 占用空間非常非常小,只需要 12k 的空間就能存儲(chǔ)接近2^64個(gè)不同元素。這是真的厲害,這就是數(shù)學(xué)的魅力么!并且,Redis 對(duì) HyperLogLog 的存儲(chǔ)結(jié)構(gòu)做了優(yōu)化,采用兩種方式計(jì)數(shù):

  • 稀疏矩陣:計(jì)數(shù)較少的時(shí)候,占用空間很小。
  • 稠密矩陣:計(jì)數(shù)達(dá)到某個(gè)閾值的時(shí)候,占用 12k 的空間。

Redis 官方文檔中有對(duì)應(yīng)的詳細(xì)說(shuō)明:

圖片圖片

基數(shù)計(jì)數(shù)概率算法為了節(jié)省內(nèi)存并不會(huì)直接存儲(chǔ)元數(shù)據(jù),而是通過(guò)一定的概率統(tǒng)計(jì)方法預(yù)估基數(shù)值(集合中包含元素的個(gè)數(shù))。因此, HyperLogLog 的計(jì)數(shù)結(jié)果并不是一個(gè)精確值,存在一定的誤差(標(biāo)準(zhǔn)誤差為 0.81% )。

圖片圖片

HyperLogLog 的使用非常簡(jiǎn)單,但原理非常復(fù)雜。HyperLogLog 的原理以及在 Redis 中的實(shí)現(xiàn)可以看這篇文章:HyperLogLog 算法的原理講解以及 Redis 是如何應(yīng)用它的[4] 。

再推薦一個(gè)可以幫助理解 HyperLogLog 原理的工具:Sketch of the Day: HyperLogLog — Cornerstone of a Big Data Infrastructure[5] 。

除了 HyperLogLog 之外,Redis 還提供了其他的概率數(shù)據(jù)結(jié)構(gòu),對(duì)應(yīng)的官方文檔地址:https://redis.io/docs/data-types/probabilistic/ 。

常用命令

HyperLogLog 相關(guān)的命令非常少,最常用的也就 3 個(gè)。

命令

介紹

PFADD key element1 element2 ...

添加一個(gè)或多個(gè)元素到 HyperLogLog 中

PFCOUNT key1 key2

獲取一個(gè)或者多個(gè) HyperLogLog 的唯一計(jì)數(shù)。

PFMERGE destkey sourcekey1 sourcekey2 ...

將多個(gè) HyperLogLog 合并到 destkey 中,destkey 會(huì)結(jié)合多個(gè)源,算出對(duì)應(yīng)的唯一計(jì)數(shù)。

HyperLogLog 基本操作演示:

> PFADD hll foo bar zap
(integer) 1
> PFADD hll zap zap zap
(integer) 0
> PFADD hll foo bar
(integer) 0
> PFCOUNT hll
(integer) 3
> PFADD some-other-hll 1 2 3
(integer) 1
> PFCOUNT hll some-other-hll
(integer) 6
> PFMERGE desthll hll some-other-hll
"OK"
> PFCOUNT desthll
(integer) 6

應(yīng)用場(chǎng)景

數(shù)量量巨大(百萬(wàn)、千萬(wàn)級(jí)別以上)的計(jì)數(shù)場(chǎng)景

  • 舉例:熱門網(wǎng)站每日/每周/每月訪問(wèn) ip 數(shù)統(tǒng)計(jì)、熱門帖子 uv 統(tǒng)計(jì)、
  • 相關(guān)命令:PFADD、PFCOUNT 。

Geospatial (地理位置)

介紹

Geospatial index(地理空間索引,簡(jiǎn)稱 GEO) 主要用于存儲(chǔ)地理位置信息,基于 Sorted Set 實(shí)現(xiàn)。

通過(guò) GEO 我們可以輕松實(shí)現(xiàn)兩個(gè)位置距離的計(jì)算、獲取指定位置附近的元素等功能。

圖片圖片

常用命令

命令

介紹

GEOADD key longitude1 latitude1 member1 ...

添加一個(gè)或多個(gè)元素對(duì)應(yīng)的經(jīng)緯度信息到 GEO 中

GEOPOS key member1 member2 ...

返回給定元素的經(jīng)緯度信息

GEODIST key member1 member2 M/KM/FT/MI

返回兩個(gè)給定元素之間的距離

GEORADIUS key longitude latitude radius distance

獲取指定位置附近 distance 范圍內(nèi)的其他元素,支持 ASC(由近到遠(yuǎn))、DESC(由遠(yuǎn)到近)、Count(數(shù)量) 等參數(shù)

GEORADIUSBYMEMBER key member radius distance

類似于 GEORADIUS 命令,只是參照的中心點(diǎn)是 GEO 中的元素

基本操作:

> GEOADD personLocation 116.33 39.89 user1 116.34 39.90 user2 116.35 39.88 user3
3
> GEOPOS personLocation user1
116.3299986720085144
39.89000061669732844
> GEODIST personLocation user1 user2 km
1.4018

通過(guò) Redis 可視化工具查看 personLocation ,果不其然,底層就是 Sorted Set。

GEO 中存儲(chǔ)的地理位置信息的經(jīng)緯度數(shù)據(jù)通過(guò) GeoHash 算法轉(zhuǎn)換成了一個(gè)整數(shù),這個(gè)整數(shù)作為 Sorted Set 的 score(權(quán)重參數(shù))使用。

圖片圖片

獲取指定位置范圍內(nèi)的其他元素:

> GEORADIUS personLocation 116.33 39.87 3 km
user3
user1
> GEORADIUS personLocation 116.33 39.87 2 km
> GEORADIUS personLocation 116.33 39.87 5 km
user3
user1
user2
> GEORADIUSBYMEMBER personLocation user1 5 km
user3
user1
user2
> GEORADIUSBYMEMBER personLocation user1 2 km
user1
user2

GEORADIUS 命令的底層原理解析可以看看阿里的這篇文章:Redis 到底是怎么實(shí)現(xiàn)“附近的人”這個(gè)功能的呢?[6] 。

移除元素:

GEO 底層是 Sorted Set ,你可以對(duì) GEO 使用 Sorted Set 相關(guān)的命令。

> ZREM personLocation user1
1
> ZRANGE personLocation 0 -1
user3
user2
> ZSCORE personLocation user2
4069879562983946

應(yīng)用場(chǎng)景

需要管理使用地理空間數(shù)據(jù)的場(chǎng)景

  • 舉例:附近的人。
  • 相關(guān)命令: GEOADD、GEORADIUS、GEORADIUSBYMEMBER 。

總結(jié)

數(shù)據(jù)類型

說(shuō)明

Bitmap

你可以將 Bitmap 看作是一個(gè)存儲(chǔ)二進(jìn)制數(shù)字(0 和 1)的數(shù)組,數(shù)組中每個(gè)元素的下標(biāo)叫做 offset(偏移量)。通過(guò) Bitmap, 只需要一個(gè) bit 位來(lái)表示某個(gè)元素對(duì)應(yīng)的值或者狀態(tài),key 就是對(duì)應(yīng)元素本身 。我們知道 8 個(gè) bit 可以組成一個(gè) byte,所以 Bitmap 本身會(huì)極大的節(jié)省儲(chǔ)存空間。

HyperLogLog

Redis 提供的 HyperLogLog 占用空間非常非常小,只需要 12k 的空間就能存儲(chǔ)接近2^64個(gè)不同元素。不過(guò),HyperLogLog 的計(jì)數(shù)結(jié)果并不是一個(gè)精確值,存在一定的誤差(標(biāo)準(zhǔn)誤差為 0.81% )。

Geospatial index

Geospatial index(地理空間索引,簡(jiǎn)稱 GEO) 主要用于存儲(chǔ)地理位置信息,基于 Sorted Set 實(shí)現(xiàn)。

參考資料

[1]Redis Data Structures: https://redis.com/redis-enterprise/data-structures/

[2]Redis Data types tutorial: https://redis.io/docs/manual/data-types/data-types-tutorial/

[3]線性數(shù)據(jù)結(jié)構(gòu) :數(shù)組、鏈表、棧、隊(duì)列: https://javaguide.cn/cs-basics/data-structure/linear-data-structure.html

[4]HyperLogLog 算法的原理講解以及 Redis 是如何應(yīng)用它的: https://juejin.cn/post/6844903785744056333

[5]Sketch of the Day: HyperLogLog — Cornerstone of a Big Data Infrastructure: http://content.research.neustar.biz/blog/hll.html

[6]Redis 到底是怎么實(shí)現(xiàn)“附近的人”這個(gè)功能的呢?: https://juejin.cn/post/6844903966061363207

責(zé)任編輯:武曉燕 來(lái)源: JavaGuide
相關(guān)推薦

2023-11-20 13:52:00

Redis數(shù)據(jù)庫(kù)

2023-11-13 08:31:25

SpringRedis存儲(chǔ)

2014-07-25 10:55:36

Linux命令

2011-03-16 10:07:00

2014-01-02 09:57:56

PostgreSQL命令

2011-01-19 17:00:09

Postfix常用命令

2021-06-15 09:20:08

Redis數(shù)據(jù)類型

2024-11-04 06:20:00

Redis單線程

2010-03-29 10:16:39

CentOS常用命令

2022-04-10 23:38:33

Redis數(shù)據(jù)結(jié)構(gòu)開發(fā)

2011-03-31 16:09:56

Mysql數(shù)據(jù)庫(kù)

2020-09-28 15:14:31

Linux常用命令實(shí)用命令

2022-09-06 07:56:36

ZookeeperAPI

2024-12-30 08:29:05

2009-12-22 14:47:24

Linux常用命令

2010-04-01 18:10:32

CentOS常用命令

2010-04-07 11:21:28

Oracle常用命令

2010-05-28 18:28:51

MySQL常用命令

2011-03-15 09:59:57

2015-07-22 17:32:22

mysql常用命令
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)