1. 程式人生 > 其它 >7353. 【2021.11.06NOIP提高A組模擬】qaq (qaq)

7353. 【2021.11.06NOIP提高A組模擬】qaq (qaq)

Redis(二)

本次部落格主要介紹 Redis 的 value 最常見的五種資料結構,它們分別是:String、Hash、List、Set、Sorted Set

String

redis裡面的String是以位元組儲存的,如果你的客戶端是utf-8編碼,那麼上傳上去的字串就是按utf-8進行編碼

redis的String裡面除了儲存資料以外,還儲存了型別和長度。型別包括:字串、數值以及bitmap

字串

有最基本的6種操作,它們分別是:set、get、append、setrange、getrange、strlen

# 設定字串,以下命令執行完畢之後,hello=world
set hello world

# 獲取字串,獲取hello變數的值
get hello

# 追加字串,以下命令執行完畢之後,hello=worldtest
append hello test

# 字串修改某個位置開始的字串,以下命令執行完畢之後,hello=tttldtest
setrange hello 0 ttt

# 字串獲取某個位置範圍的字串,以下命令執行完畢之後,輸出 ttld
getrange hello 1 4

# 獲取字串長度,以下命令執行完畢,輸出9
strlen hello

數值

redis可以將儲存的字串解析為一個數字,然後當做數值來進行處理,它只有一個操作incr

# 設定字串
set test 9

# 使其加1,執行之後test變為10
incr test

數值型別,在搶購、秒殺、詳情頁、點贊、評論情況下使用,可以解決併發問題,對資料庫的事務操作,完全有 redis 記憶體操作代替

bitmap

字串是有一個個位元組組成的,所以可以進行位操作,這裡一共有四個操作可供選擇:setbit、bitcount、bitpos、bitop,下面演示一下這些操作

# 設定字串
set test a0

# 設定位,a0原來是 0110 0001 0011 0000,將第7位變成0,變成 0110 0000 0011 0000,於是變成了`0
setbit test 7 0

# 獲取1的個數,因為test = 0110 0000 0011 0000 返回結果是4,表示有4個1
bitcount test

# 查詢字串中第一個設定為1或0的bit位。返回1
bitpos test 1 0 -1

# 將兩個二進位制串進行與或非操作
# test1           0110 0001
# test2           0110 0010
# test1 & test2   0110 0000
set test1 a
set test2 b
bitop and dest test1 test2

bitmap 有什麼用呢?

用處:統計使用者登入天數,且視窗隨機

# 我在第1天登入了
setbit hellozjf 1 1

# 我在第7天登入了
setbit hellozjf 7 1

# 我在第364天登入了
setbit hellozjf 364 1

# 查詢我整年登入了多少天,返回值是3,說明我今年登入了3天
bitcount hellozjf

# 查詢我最近一週登入了多少天
bitcount hellozjf -7 -1,返回值是1,說明我最近一週登入了1天

List

redis 裡面的 List 是一個雙向佇列,可以從頭部插入資料、彈出資料,也可以從尾部插入、彈出資料

它擁有的操作為lpushlpoprpushrpoplrange(查詢列表中的元素)、lindex(查詢列表中的元素)、lset(更新某個索引的值)、lrem(刪除元素)

# 插入佇列,k1變成 f e d c b a
lpush k1 a b c d e f

# 查詢列表
lrange k1 0 -1

# 查詢第2個元素,查出 d
lindex k1 2

# 查詢最後一個元素,查出 a
lindex k1 -1

# 設定第三個元素
lset k1 3 xxxxx

hash

value裡面可以儲存一個map,但是它只有一層。hash和sort set是兩個非常常用的型別,需要重點掌握

通過在redis-cli上面執行命令,執行help @hash,可以看到它擁有的操作為hdelhexistshgethgetallhincrbyhincrbyfloathkeyshlenhmgethmsethsetnxhstrlen

# 設定 k1.a=1
hset k1 a 1

# 獲取 k1.a
hget k1 a

# 給 k1.a 增加1,之後k1.a變成2
hincrby k1 a 1

# 給 k1.a 增加0.5,之後k1.a變成2.5
hincrbyfloat k1 a 0.5

# 如果沒有k1.b,則設定10,否則不設定
hsetnx k1 b 10

# 獲取所有的k1下面所有的key和value
hgetall k1

# 判斷某個鍵是否存在
hexists k1 a

……

其實也挺簡單的,說白了就是 key-value 裡面的 value 變成了 key-value

set

set其實和list差不多,只不過set裡面沒有重複的元素,但是它有個缺點就是元素是無序的

在redis-cli上面,執行help @set,可以看到所有的set相關的操作。例如sadd(將元素加入到set裡面)、SREM(將元素從set中移除)、smembers(獲取所有的元素)、sdiff/sdiffstore(兩個set做相減操作/相減結果記錄到另一個變數)、sinter/sinterstore(求兩個set的交集/相交結果記錄到另一個變數)、sunion/sunionstore(兩個set做並集/並集結果記錄到另一個變數)、srandmember(從元素中獲取隨機的幾個元素)、spop(從元素中獲取隨機的幾個元素,然後從set中刪除它們)

sadd k1 a b c
sadd k2 b c d

# 獲取 k1 - k2,結果儲存到 k3,k3變成a
sdiffstore k3 k1 k2

# 獲取 k1 與 k2 的交集,結果儲存到 k4,k4變成b,c
sinterstore k4 k1 k2

# 獲取 k1 與 k2 的並集,結果儲存到 k5,k5變成a,b,c,d
sunionstore k5 k1 k2

# 買彩票,你把幾個數字放進去,然後隨機調出幾個數字。比方說下面就是從10個數字裡面隨機調出3個數字
sadd k6 1 2 3 4 5 6 7 8 9 0
srandmember k6 3

# 年會抽獎,你把人的名字放進去,這個人中獎之後需要移除他的名字。
sadd k7 1 2 3 4 5 6 7 8 9 0
## 抽出4個四等獎
spop k7 4
## 抽出3個三等獎
spop k7 3
## 抽出2個二等獎
spop k7 2
## 抽出1個一等獎
spop k7 1
## 再抽返回null

sorted_set

再set的基礎上面,增加了排序的功能。預設情況下,它在記憶體中是按照權重左小右大的方式進行儲存的,通過ZRANGEZREVRANGE正序獲取倒序獲取結果,它也有差集、並集、交集的功能,但是個人感覺沒啥意義,sorted_set在底層是通過跳錶實現的

在redis-cli中,通過help @sorted_set獲取所有排序set的操作方法

# 往 sorted_set 中新增元素,其中張三權重1,李四權重2
zadd k1 1 張三 2 李四
# 檢視 sorted_set 中的所有記錄,這裡如果中文編碼不正確的話,使用 redis-cli --raw,這樣redis就會將utf8字串翻譯成中文
zrange k1 0 -1 withscores
# 反向檢視 sorted_set 中的所有記錄
zrevrange k1 0 -1 withscores