在前文中我們已經介紹了Redis中有關字符串的大部分命令。在本文中,我們將介紹一下Redis中位操作相關的命令,並簡單介紹6.0版本中新增的STRALGO命令。若需要了解其他的字符串命令,可參考之前的文章:
SETBIT
SETBIT
命令用於設置指定偏移位的二進制值,設置的值必須爲0
或1
。
SETBIT key offset value
使用SETBIT
命令時,偏移量的值必須大於等於0,且小於4294967296(2^32)。若偏移量大於原字符串的長度,則該字符串將增長至能存放偏移量的長度,增長的部分將使用0
填充。
示例
redis> SETBIT mykey 7 1
(integer) 0
redis> GET mykey
"\x01"
redis> SETBIT mykey 7 0
(integer) 1
redis> GET mykey
"\x00"
當偏移量大於字符串長度時,字符串將增長:
redis> SET greeting "hello world"
OK
redis> SETBIT greeting 94 1
(integer) 0
redis> GET greeting
"hello world\x02"
GETBIT
GETBIT
命令用於返回指定指定偏移量的二進制值。
GETBIT key offset
使用GETBIT
命令時若指定的偏移量大於字符串的長度,將認定超出的部分爲連續的0。當鍵值對不存在時,將認定其爲一個空白的字符串,即偏移量大於字符串的長度。與SETBIT
命令不同的是,偏移量超出字符串時不會使字符串增長。
示例
redis> SETBIT mykey 7 1
(integer) 0
redis> GETBIT mykey 7
(integer) 1
redis> SET greeting "hello world"
OK
# 字符h的二進制爲01101000H
redis> GETBIT greeting 0
(integer) 0
redis> GETBIT greeting 1
(integer) 1
# greeting的長度爲88位,獲取超出字符串的長度的位
redis> GETBIT greeting 88
(integer) 0
BITCOUNT
BITCOUNT
命令用於獲取指定範圍內字符串中二進制值爲1
的位數。默認情況下計數範圍爲整個字符串,另外也可手動指定計數開始和結束的位置。不同於上文中介紹的SETBIT
以及GETBIT
命令,BITCOUNT
參數中的偏移量單位爲字節而非位。
BITCOUNT key [start end]
與前文中介紹過的GETRANGE
命令相似,也可以使用負數表示相對於字符串末尾的位置。
示例
redis> SET greeting "hello world"
OK
# 字符h的二進制爲01101000
redis> BITCOUNT greeting 0 0
(integer) 3
# 字符e的二進制爲01100101
redis> BITCOUNT greeting 1 1
(integer) 4
# 字符l的二進制爲01101100
# 字符d的二進制爲01100100
redis> BITCOUNT greeting -2 -1
(integer) 7
redis> BITCOUNT greeting
(integer) 45
# 偏移量end小於start的情況,相當於空字符串
redis> BITCOUNT greeting 3 1
(integer) 0
BITPOS
BITPOS
命令用於獲取在指定範圍中首個二進制值爲0
或1
的位置。當鍵值對不存在時,將認爲是一個空字符串進行搜索。與BITCOUNT
命令相同,BITPOS
命令也可以以字節爲單位指定偏移量,使用負數值表示相對於字符串末尾的位置。
BITPOS key bit [start] [end]
使用BITPOS
命令時,將認定超出字符串長度的部分爲連續的0
。
返回值
BITPOS
命令將返回首個符合條件的二進制值的位置。如當字符串值爲"\xfd"
時(即二進制值11111101
),使用命令BITPOS key 1
將得到結果爲0,使用命令BITPOS key 0
將得到結果爲6。
當查找的值爲二進制值1
,且字符串爲空或不包含1
時,將返回-1
。
當查找的值爲二進制值0
,字符串不爲空且只包含有1
時,將返回字符串後的第一個位的位置。如當字符串值爲"\xff"
時(即二進制值11111111
),使用BITPOS key 0
命令得到的結果爲8。
當同時設置偏移量start
以及end
時,將只會在指定範圍內查找。如當字符串值爲"\xff"
時(即二進制值11111111
),使用BITPOS key 0 0 0
命令得到的結果爲-1。
示例
# 11111111 11111101
redis> SET mykey "\xff\xfd"
OK
redis> BITPOS mykey 1
(integer) 0
redis> BITPOS mykey 0
(integer) 14
# 在第一個字節中尋找
redis> BITPOS mykey 0 0 0
(integer) -1
BITOP
BITOP
命令用於對多個值(除NOT
操作外)執行位運算操作,並將結果保存至指定的鍵值對中。BITOP
命令將返回結果字符串的長度,其值等於輸入中最長字符串的長度。
BITOP operation destkey key [key ...]
BITOP
命令支持與(AND
)、或(OR
)、異或(XOR
)以及非(NOT
)四個位運算操作,其使用方式爲:
AND
與操作,使用方式爲BITOP AND destkey srckey1 srckey2 ...
OR
或操作,使用方式爲BITOP OR destkey srckey1 srckey2 ...
XOR
異或操作,使用方式爲BITOP XOR destkey srckey1 srckey2 ...
NOT
非操作,使用方式爲BITOP NOT destkey srckey
當輸入的字符串長度不同時,將使用0
填充至與最長長度相同。若輸入的鍵不存在則認定爲一個空白字符串,並以0填充至與最長長度相同。
示例
在下面的示例中,我們將使用到下面幾個值作爲演示的源值:
# 10101010
redis> SET key1 "\xaa"
OK
# 01010101
redis> SET key2 "\x55"
OK
# 11110000
redis> SET key3 "\xf0"
OK
# 01010101 01010101
redis> SET key4 "\x5555"
OK
與(AND)操作:
# 10101010 & 01010101 = 00000000
redis> BITOP AND result key1 key2
(integer) 1
redis> GET result
"\x00"
或(OR)操作:
# 10101010 | 01010101 = 11111111
redis> BITOP OR result key1 key2
(integer) 1
redis> GET result
"\xff"
異或(XOR)操作:
# 10101010 ^ 11110000 = 01011010
redis> BITOP XOR result key1 key3
(integer) 1
# 字符Z二進制值爲 01011010
redis> GET result
"Z"
或(OR)操作:
# !10101010 = 01010101
redis> BITOP NOT result key1
(integer) 1
# 字符U二進制值爲 01010101
redis> GET result
"U"
不同長度的字符串進行位運算:
# key1的值將以0填充爲 10101010 00000000
# 10101010 00000000 | 01010101 01010101 = 11111111 00000000
redis> BITOP OR result key1 key4
(integer) 2
redis> GET result
"\xffU"
BITFIELD
使用BITFIELD
將字符串看成二進制位數組,並對其中存儲不同長度的整數進行操作。例如設置偏移量爲1234的5位有符號整數的值,或是獲取偏移量爲4567的31位無符號整數的值。同時,BITFIELD
命令也提供了INCRBY
子命令對值進行加/減操作,並提供了設置以處理溢出的情況。
BITFIELD key [GET type offset] [SET type offset value] [INCRBY type offset increment] [OVERFLOW WRAP|SAT|FAIL]
BITFIELD
命令可通過傳遞多個命令對多個位域進行操作,並以數組的形式返回各命令執行的結果。例如下面的示例中,對mykey
鍵中偏移量爲100的5位有符號整數進行自增量爲1的自增操作,並獲取偏移量爲0的4位無符號整數的值:
redis> BITFIELD mykey INCRBY i5 100 1 GET u4 0
1) (integer) 1
2) (integer) 0
BITFIELD
命令提供了下列支持的子命令:
GET <type> <offset>
返回指定位域的值,若超出字符串的長度,超出部分將爲0。SET <type> <offset> <value>
設置指定位域的值,並返回舊值。若超出字符串的長度,超出部分將以0填充。INCRBY <type> <offset> <increment>
對指定位域的值進行自增操作(通過使用負的自增值進行減法的操作),並返回最新的值。若超出字符串的長度,超出部分將以0填充。
另外,BITFIELD
命令還支持OVERFLOW
子命令,用於設置發生溢出時執行的操作。
OVERFLOW [WRAP|SAT|FAIL]
OVERFLOW
命令具有下列三個行爲的設置,在未顯式聲明的情況下,默認的溢出行爲爲WRAP
。
WRAP
環繞(wrap around)模式,也就是C語言中的標準行爲。即當上溢出時將從該類型最小的值開始計算,下溢出時從該類型最大的值開始計算。例如對值爲-128的8位有符號整數做減一的操作,將得到127。SAT
發生溢出時將保持數值爲該類型的邊界值。如對值爲120的8位有符號整數做加10的操作將得到127,在後續繼續做加法操作值仍將保持在127。FAIL
若將發生溢出,則將不執行INCRBY
操作,並返回nil
。
對於BITFIELD
命令中的<type>
參數,需要傳遞位域的類型及大小。位域支持有符號整數和無符號整數兩種類型,分別使用符號i
以及u
表示。在類型符號後,需要聲明位域的大小,例如i32
代表32位有符號整數,u15
代表15位無符號整數。由於Redis的協議原因,位域支持的最大大小分別爲64位有符號整數及63位無符號整數。
BITFIELD
命令提供了兩種方式設置偏移量:
- 即直接使用不帶前綴的數值,它表示以0開始從字符串起始位置計算偏移量,例如
200
表示字符串中的第201位。 - 以
#
作爲前綴的數值,它將與類型的長度相乘計算出實際的偏移量。例如對於命令BITFIELD mystring SET i8 #0 100 SET i8 #1 200
,兩個子命令的實際偏移量分別爲0和8。
示例
# 01111111
redis> BITFIELD mykey SET i8 0 127
1) (integer) 0
# 5位有符號整形中,二進制值11111表示-1
# 5位無符號整形中,二進制值11111表示31
redis> BITFIELD mykey GET i5 3 GET u5 3
1) (integer) -1
2) (integer) 31
redis> BITFIELD mykey INCRBY u8 0 10 INCRBY i8 0 -15
1) (integer) 137
2) (integer) 122
通過OVERFLOW
控制溢出的情況:
redis> BITFIELD overflow-test SET i8 0 120
(integer) 0
# 使用FAIL使發生溢出時不執行操作
redis> BITFIELD overflow-test OVERFLOW FAIL INCRBY i8 0 10
1) (nil)
# 使用SAT使發生溢出時保持在邊界值
redis> BITFIELD overflow-test OVERFLOW SAT INCRBY i8 0 10
1) (integer) 127
# 使用WRAP使發生溢出時值按環繞模式改變
redis> BITFIELD overflow-test OVERFLOW WRAP INCRBY i8 0 1
1) (integer) -128
結束語
STRALGO
命令是6.0版本新增加的命令,用於執行一些複雜的字符串操作算法。STRALGO
可能可以被用於DNA以及RNA序列的分析中。在本文中我們僅對STRALGO
命令進行簡單的介紹。
STRALGO algorithm argument [argument ...]
在當前最新版本中(6.0.5),僅支持了LCS算法(longest common substring,最長公共子串),其使用方式爲:
STRALGO LCS [KEYS ...] [STRINGS ...] [LEN] [IDX] [MINMATCHLEN <len>] [WITHMATCHLEN]
以下爲STRALGO
命令使用的示例:
redis> STRALGO LCS STRINGS salvatore sanfilippo
"salo"
關於STRALGO
命令更多的使用方法,可以參考Redis文檔中的STRALGO
頁面。
至此,我們已經介紹了Redis中字符串相關所有命令,在接下去的文章中,我們將繼續介紹Redis中的其他類型命令。若需要對了解關於字符串命令的更多內容,可以參考Redis文檔中的字符串相關命令文檔。
歡迎大家關注我的公衆號“風紙”,或是掃下面的二維碼關注👇