Redis基本數據類型之String

Redis中的Key

  • Redis中的key是二進制安全的,可以使用任意二進制序列作爲key,即如字符串或者圖片的內容都可以作爲key,注意:空字符串在Redis中也被認爲是有效的key。
  • key不宜過長,一是從存儲角度來講比較耗費內存,而且在查找key時對key進行比較將會增加開銷。
  • 推薦使用中劃線或冒號將描述字段分隔,整體作爲key,如:“student:id”、“student:age”。
  • key的最大容量爲512M

基本命令

  1. 獲得一個符合匹配規則的鍵名列表
> keys pattern [? / * /[] ]

其中pattern爲正則表達式,返回符合相應規則的key的列表

  1. 判斷一個鍵是否存在
> exiests key
  1. 獲取key所對應的value的數據結構類型
> type key

基本數據類型-String

1. 基本賦值、取值操作

1.1 賦值

> set user:name eric
OK

set命令可以帶參數,
NX:只在key不存在時,才進行賦值操作;
XX:只在key已存在時,才進行賦值操作。

1.2 批量賦值

mset命令用於set多個key的value

> mset user:name eric user:age 18
OK

1.3 取值

> get user:name
"eric"

1.4 批量取值

mget命令用於批量取值,參數爲多個key,返回value列表

> mget user:name user:age
1) "eric"
2) "18"

2. 字符串操作

2.1 字符串拼接

> append user:name 1122
(integer) 8
> get user:name 
"eric1122"

2.2 字符串截取

命令getrange key start end,獲取開始結束索引之間的子字符串

> getrange user:name 1 6
"ric112"

2.3 獲取長度

strlen命令用戶獲取key對應的value的長度

> strlen user:name
integer) 8 
> strlen user:age
(integer) 2

3. 數值操作

注意到上述創建的key中的value的類型是相同的,都是string,如下:

> type user:name
string
> type user:age
string

但是使用OBJECT ENCODING命令進一步查看value的編碼類型:

> object encoding user:name
"raw"
> object encoding user:age
"int"

string類型針對以int爲編碼格式的value支持數值操作。

3.1 增加

incr key ,對key的value增加1
incrby key increment,增加指定的整數

> incr user:age
(integer) 19
> incrby user:age 10
(integer) 29
> get user:age
"29"

3.2 減少(與加類似)

3.3 二進制安全

爲什麼說Redis是二進制安全的?我們先來看下面的例子:

> set num 99
OK
> strlen num
(integer) 2

此時,如果將num自增1,再使用strlen來獲取num的長度,結果會是什麼呢?

> incr num
(integer) 100
> strlen num
???

此時num的value爲100,那麼此時獲取這個value的長度,結果是多少呢?
答案是:3

如果把num加1000呢?此時value的長度是多少?

> incrby num 1000
(integer) 1100
> get num 
"1100"
> strlen num
???

num的value是1100,編碼類型爲int,那麼長度是多少?java中整型長度爲4個字節,Redis中是怎樣的?1100由幾個字節能夠表示?

程序運行的答案是:4
爲什麼?
因爲Redis是二進制安全的,所謂二進制安全就是指傳輸給我的數據的二進制是什麼樣,我就按什麼樣保存,不會對數據進行再編碼、序列化等操作。本質上數據都以字節數組的形式存儲與獲取,這也就意味着不會有溢出或者亂碼問題。
所以“100”這個字符串的長度爲3,“1100”的長度就是4。

4.Bitmap

Bitmap不是一個實際的數據類型,只是一系列位操作的命令,Redis將Bitmap歸屬於String類型。因爲String最大長度爲512M,所以Bitmap最多能表示232位。

4.1 賦值與取值

setbit和getbit命令用來設置/獲取二進制的具體某位的值,命令格式如下:
setbit/getbit key [offset value]
其中offset爲二進制的具體位數,value是將該位置爲1或0。

> setbit key 1 1
(integer) 1
> getbit key 1 
(integer) 1
> get key 
"@"
> strlen key
(integer) 1

上述setbit命令將一個字節的第1位賦值爲1,此時key對應的value爲01000000,getbit命令獲取該二進制數的第1位,爲1;01000000對應的ASSIC碼爲“@”,即value爲“@”。

此時,執行以下命令:

> setbit key 9 1
(integer) 0
> strlen key
(integer) 2

將第9位置爲1,Redis會自動向後補一個字節,變爲兩個字節(即01000000 01000000),value的第9位即第二個字節的第1位被置爲1。故現在value的長度爲2。

4.2 Bit位統計

命令: bitcount key [start end]用來統計value中有多少位爲“1”;
其中start代表開始字節的索引值,end代表結束字節的索引值(注意此處爲字節的索引,而不是二進制位的索引)。
如下:

#此時key的值爲 01000000 01000000
> bitcount key 0 1
(integer) 2
> bitcount key 1 1
(integer) 1

第一條命令從第0個字節開始到第1個字節結束,統計“1”的個數,結果爲2;
第二條命令其實就是統計第1個字節中“1”的個數,所以結果爲1。

4.3 Bit位查找

命令:bitpos key bit [start end]用來查找指定字節範圍中第一個bit位的索引;
其中,bit爲需要查找的值可爲0或1,start、end分別代表查找範圍中的開始、結束字節的索引。
如下:

#key的值爲 01000000 01000000
> bitpos key 1 1 1
(integer) 9
> bitpos key 1 0 1
(integer) 1

第1個字節中第一個“1”的位索引爲9,第0個到第1個字節範圍內第一個“1”的位索引爲1。

4.4 Bit位操作

命令:bitop operation destkey key [key …]

#創建k1,將第1位和第7位分別置爲1,即01000001,即字符“A”
> setbit k1 1 1
(integer) 0
> setbit k1 7 1
(integer) 0
> get k1
"A"
#創建k2,將第1位和第6位分別置爲1,即01000010,即字符“B”
> setbit k2 1 1
(integer) 0
> setbit k2 6 1
(integer) 0
> get k2
"B" 

(1)與操作–and

#將k1和k2相與,結果應爲:01000000,即字符“@”,結果保存至destkey
> bitop and andkey k1 k2
(integer) 1
> get andkey 
"@"

(2)或操作–or

#將k1和k2相與,結果應爲:01000011,即字符“C”,結果保存至destkey
> bitop or orkey k1 k2
(integer) 1
> get orkey 
"C"

簡單應用場景

Redis針對數據提供了上述的各種運算方法,客戶端進行處理時,直接調用Redis的數據處理方法即可,同時數據又是存儲在Redis內部的,這種行爲被稱爲“計算向數據移動”。

數值計算操作應用場景

一個典型的場景就是秒殺,用戶通過訪多個客戶端進行商品秒殺,可以抽象爲:客戶端通過Redis進行數值的自增,增加到商品的最大數量時,秒殺結束。
因爲Redis的業務處理過程是單線程的,所以多個客戶端的請求不會存在線程安全問題,也就不會出現商品過買的問題。
類似場景還有,統計多客戶端用戶訪問服務端的次數,比如記錄用戶操作日誌等業務。

Bitmap應用場景

假設有以下需求:電信運營商給用戶提供了掌上營業廳服務,現在局方想要統計每個用戶在一年內的掌上營業廳登錄情況,在哪些天登錄了,一共有多少天登錄?
方案一:使用數據庫,記錄每一個用戶的登錄情況。用戶每登錄一次,則增加一條記錄,記錄包含登錄當天的日期。然後一年中一共有多少天登錄通過SQL語句來查詢。
問題:一個用戶在一年中有多少天登錄,就會產生多少條記錄,這裏還要注意到電信運營商的用戶數基本是千萬級的,這樣這張表就會變的龐大無比,本方案不可行。
方案二:使用Redis的Bitmap來存儲用戶登錄信息

#用戶eric分別在第2天、第4天和第365天登錄了系統,將登錄信息存儲到Bitmap中
> setbit eric 1 1
(integer) 0

> setbit eric 3 1
(integer) 0

> setbit eric 364 1
(integer) 0

此時用於存儲用戶eric登錄信息的數據大小爲:

> strlen eric
(integer) 46

46字節
每個用戶使用46個字節就可以統計其一年的登錄情況,與數據庫的方案相比,更具有可行性。
獲取用戶登錄情況:

# Redis提供了雙向索引,-1代表最後一個元素
> bitcount eric 0 -1
(integer) 3

當然,實際場景下如果確實有千萬級以上的活躍用戶,系統壓力也還是很大的,這裏的例子僅僅是對方案一數據庫存儲進行優化。

小結

本文大致介紹了Redis中key的概念和幾個關於key的命令,然後着重介紹了Redis基本數據類型中的String,分爲字符串、數值、和Bitmap。分別列舉了針對各數據類型的處理命令,突出了計算向數據移動的特點。最後還介紹了幾個實用場景,經過本次介紹,想必大家對Redis的String有了一個基本的瞭解了吧。

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