1. 程式人生 > >二Redis 字串(string)

二Redis 字串(string)

一
Redis 中最簡單的資料結構,它既可以儲存文字(比如 "hello world"),又可以儲存數字(比如整數10086 和浮點數 3.14),還可以儲存二進位制資料(比如 10010100)。Redis 為這幾種型別的值分別設定了相應的操作命令,讓使用者可以針對不同的值做不同的處理。
為字串鍵設定值、獲取字串鍵的值、獲取字串值的長度,等等。

2.1為字串鍵設定值
SET key value
將字串鍵 key 的值設定為 value ,命令返回 OK 表示設定成功
如果字串鍵 key 已經存在,那麼用新值覆蓋原來的舊值
複雜度為 O(1)
redis> SET msg "hello world"
redis> SET msg "goodbye"      # 覆蓋原來的值 "hello world"
SET key value [NX|XX] SET 命令還支援可選的 NX 選項和 XX 選項:
• 如果給定了 NX 選項,那麼命令僅在鍵 key 不存在的情況下,才進行設定操作;如果鍵 key 已經存在,那麼 SET ... NX 命令不做動作(不會覆蓋舊值)。
• 如果給定了 XX 選項,那麼命令僅在鍵 key 已經存在的情況下,才進行設定操作;如果鍵 key 不存在,那麼 SET ... XX 命令不做動作(一定會覆蓋舊值)。
在給定 NX 選項和 XX 選項的情況下,SET 命令在設定成功時返回 OK ,設定失敗時返回 nil 。
redis> SET nx-str "this will fail" XX     # 鍵不存在,指定 XX 選項導致設定失敗
(nil)
redis> SET nx-str "this will success" NX  # 鍵不存在,所以指定 NX 選項是可行的
OK
redis> SET nx-str "this will fail" NX     # 鍵已經存在,所以指定 NX 選項導致設定失敗
(nil)
redis> SET nx-str "this will success again!" XX  # 鍵存在,指定 NX 選項是可行的
OK
2.2 獲取字串的值 GET key
返回字串鍵 key 儲存的值。 複雜度為 O(1) 。
redis> SET msg "hello world" OK
redis> GET msg
hello world
redis> SET number 10086 
OK
redis> GET number 10086
2.3快取程式的 API 及其實現

2.4僅在鍵不存在的情況下進行設定
SETNX key value
僅在鍵 key 不存在的情況下,將鍵 key 的值設定為 value ,效果和 SET key value NX 一樣。 NX 的意思為“Not eXists”(不存在)。
鍵不存在並且設定成功時,命令返回 1 ;因為鍵已經存在而導致設定失敗時,命令返回 0
複雜度為 O(1) 。
redis> SETNX new-key "i am a new key!"
1
redis> SETNX new-key "another new key here!" 0
redis> GET new-key # 鍵的值沒有改變
i am a new key!
2.5同時設定或獲取多個字串鍵的值

2.6追加內容到字串末尾
APPEND key value
將值 value 推入到字串鍵 key 已儲存內容的末尾。 O(N), 其中 N 為被推入值的長度。
redis> SET myPhone "nokia" OK
redis> APPEND myPhone "-1110" (integer) 10
redis> GET myPhone "nokia-1110"
2.7返回值的長度
STRLEN key
返回字串鍵 key 儲存的值的長度。
因為 Redis 會記錄每個字串值的長度,所以獲取該值的複雜度為 O(1) 。
redis> SET msg "hello" OK
redis> STRLEN msg (integer) 5
redis> APPEND msg " world" (integer) 11
redis> STRLEN msg (integer) 11

三索引
字串的索引(index)以 0 為開始,從字串的開頭向字串的結尾依次遞增,字串第一個字元的索 引為 0 ,字串最後一個字元的索引 為 N-1 ,其中 N 為字串的長度。
除了(正數)索引之外,字串 還有負數索引:負數索引以 -1 為開始,從字串的結尾向字串的開頭 依次遞減,字串的最後一個字元的索引 為 -N ,其中 N 為字串的長度。

範圍設定
SETRANGE key index value
從索引 index 開始,用 value 覆寫(overwrite)給定鍵 key 所儲存的字串值。只接受正數索引。
命令返回覆寫之後,字串 值的長度。複雜度為 O(N), N 為 value 的長度。 
redis> SET msg "hello"
OK
redis> SETRANGE msg 1 
"appy" (integer) 5
redis> GET msg "happy"

範圍取值 GETRANGE key start end
返回鍵 key 儲存的字串值中,位於 start 和 end 兩個索引之間的內容(閉區間,start 和 end 會被包括 在內)。和 SETRANGE 只接受正數索引不同, GETRANGE 的索引可以是正數或者 負數。
複雜度為 O(N) , N 為被選中內容的長度。 redis> SET msg "hello world"
OK
redis> GETRANGE msg 0 4 "hello"
redis> GETRANGE msg -5 -1 "world"
四設定和獲取數字
INCRBY key increment : 將 key 所儲存的值加上增量 increment ,命 令返回操作執行之後,鍵 key 的當前值。O(1)
DECRBY key decrement : 將 key 所儲存的值減去減量 decrement ,命 令返回操作執行之後,鍵 key 的當前值。O(1)
如果執行 INCRBY 或者 DECRBY 時,鍵 key 不存在,那麼命令會將 鍵 key 的 值初始化為 0 ,然後再執行增加或者減少操作。
redis> INCRBY num 100 # 鍵 num 不存在,命令先將 num 的值初始化為 0 ,然後再執行加 100 操作
(integer) 100
redis> INCRBY num 25  # 將值再加上 25
(integer) 125
redis> DECRBY num 10  # 將值減少 10
(integer) 115
redis> DECRBY num 50  # 將值減少 50
(integer) 65


增一和減一
NCR key : 等同於執行 INCRBY key 1  : O(1)
DECR key : 等同於執行 DECRBY key 1 : O(1)
redis> SET num 10 
OK
redis> INCR num 
(integer) 11
redis> DECR num 
(integer) 10

五計數器 API 及其實現

c = Counter('page-counter', redis_client) # 建立一個名為 page-counter 的計數器 
c.incr() # => 1
c.incr() # => 2
設定和獲取二進位制資料
SET,GET,SETNX,APPEND等命令同樣可以用於設定二進位制資料
#因為Redis自帶的客戶端redis-cli沒辦法方便的設定二進位制資料
import redis
r=redis.Redis()
r.set('bits',0b10010100) #將字串bits的值設定為二進位制10010100
bin(int(r.get('bits'))) #獲取字串鍵bits儲存的二進位制值(需要進行轉換)
r.append('bits', 0b111) #將ob111(也就是十進位制的7) 推入到bits已有二進位制位的末尾
bin(int(r.get('bits'))) #推入之前的值為0b10010100=148
#推入之後的值為0b10111001111=1487


六二進位制位的索引
6.1 和儲存文字時一樣,字串鍵在儲存二進位制位時,索引也是從 0 開始的。
但是和儲存文字時,索引從左到右依次遞增不同,當字串鍵儲存的是二進位制位時,二進位制位的索引會 從左到右依次 遞減。

6.2設定二進位制位的值
SETBIT key index value
將給定索引上的二進位制位的值設定為 value ,命令返回被設定的位原來儲存的舊值。
複雜度為 O(1) 。
redis> SETBIT bits 2 1
(integer) 0

6.3獲取二進位制位的值
GETBIT key index 返回給定索引上的二進位制位的值。 複雜度為 O(1) 。
redis> GETBIT bits 7     #(integer) 1
redis> GETBIT bits 6     #(integer) 0
redis> GETBIT bits 4     #(integer) 1
7儲存中文時的注意事項
STRLEN、SETRANGE 和 GETRANGE 不適用於中文
一個英文字元只需要使用 單個位元組來儲存,而一箇中文字元卻需要使用多個位元組來儲存

TRLEN、SETRANGE 和 GETRANGE 都是為英文設定的,它們只會在字元為單個位元組的情況下正常工作,而一旦我們儲存的是類似中文這樣的多位元組字元那麼這三個命令就不再適用了。
STRLEN示例
redis-cli --raw # 在 redis-cli 中使用中文時,必須開啟 --raw 選項,才能正常顯示中文
redis> SET msg "世界你好" # 設定四個中文字元
redis> SET msg "世界你好" # 設定四個中文字元
世界你好
redis> STRLEN msg # 這裡 STRLEN 顯示了“世界你好”的位元組長度為 12 位元組
12                 #但我們真正想知道的是 msg 鍵裡面包含多少個字元

SETRANGE 和 GETRANGE 示例
SETRANGE 和 GETRANGE 的情況也是類似的:因為這兩個命令所使用的索引是根據字 節而不是字元來編排的,
所以呼叫 SETRANGE或者GETRANGE來處理中文,得不到我們想要的結果。

redis> SET msg "世界你好"
redis> GETRANGE msg 2 3
redis> SETRANGE msg 2 "歡迎你"
redis> GET msg

 

 

#coding: utf-8
class Cache:
    def __init__(selfself,client):
        self.client = client

    def put(self,name, content):
        self.client.set(name,content)

    def get(selfself,name):
        return self.client.get(name)


# encoding: utf-8
class Counter:
    def __init__(self, key, client):
        self.key = key
        self.client = client

    def incr(self, n=1):
        counter = self.client.incr(self.key, n)
        return int(counter)

    def decr(self, n=1):
        counter = self.client.decr(self.key, n)
        return int(counter)

    def reset(self, n=0):
        counter = self.client.getset(self.key, n)
        if counter is None:
            counter = 0
        return int(counter)

    def get(self):
        counter = self.client.get(self.key)
        if counter is None:

# coding: utf-8
class IdGenerator:
    def __init__(self, key, client):
        self.key = key
        self.client = client

    def init(self, n):
        self.client.set(self.key, n)

    def gen(self):
        new_id = self.client.incr(self.key)
        return int(new_id)



# encoding: utf-8
class OnlineCount:
    def __init__(self, when, client):
        self.when = when
        self.client = client

    def include(self, user_id):
        return self.client.setbit(self.when, user_id, 1)

    def result(self):
        return self.client.bitcount(self.when)