W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
Redis 是一個鍵值對(key-value pair)數(shù)據(jù)庫服務器, 服務器中的每個數(shù)據(jù)庫都由一個 redis.h/redisDb
結構表示, 其中, redisDb
結構的dict
字典保存了數(shù)據(jù)庫中的所有鍵值對, 我們將這個字典稱為鍵空間(key space):
typedef struct redisDb {
// ...
// 數(shù)據(jù)庫鍵空間,保存著數(shù)據(jù)庫中的所有鍵值對
dict *dict;
// ...
} redisDb;
鍵空間和用戶所見的數(shù)據(jù)庫是直接對應的:
舉個例子, 如果我們在空白的數(shù)據(jù)庫中執(zhí)行以下命令:
redis> SET message "hello world"
OK
redis> RPUSH alphabet "a" "b" "c"
(integer) 3
redis> HSET book name "Redis in Action"
(integer) 1
redis> HSET book author "Josiah L. Carlson"
(integer) 1
redis> HSET book publisher "Manning"
(integer) 1
那么在這些命令執(zhí)行之后, 數(shù)據(jù)庫的鍵空間將會是圖 IMAGE_DB_EXAMPLE 所展示的樣子:
alphabet
是一個列表鍵, 鍵的名字是一個包含字符串 "alphabet"
的字符串對象, 鍵的值則是一個包含三個元素的列表對象。book
是一個哈希表鍵, 鍵的名字是一個包含字符串 "book"
的字符串對象, 鍵的值則是一個包含三個鍵值對的哈希表對象。message
是一個字符串鍵, 鍵的名字是一個包含字符串 "message"
的字符串對象, 鍵的值則是一個包含字符串 "hello world"
的字符串對象。因為數(shù)據(jù)庫的鍵空間是一個字典, 所以所有針對數(shù)據(jù)庫的操作 —— 比如添加一個鍵值對到數(shù)據(jù)庫, 或者從數(shù)據(jù)庫中刪除一個鍵值對, 又或者在數(shù)據(jù)庫中獲取某個鍵值對, 等等, 實際上都是通過對鍵空間字典進行操作來實現(xiàn)的, 以下幾個小節(jié)將分別介紹數(shù)據(jù)庫的添加、刪除、更新、取值等操作的實現(xiàn)原理。
添加一個新鍵值對到數(shù)據(jù)庫, 實際上就是將一個新鍵值對添加到鍵空間字典里面, 其中鍵為字符串對象, 而值則為任意一種類型的 Redis 對象。
舉個例子, 如果鍵空間當前的狀態(tài)如圖 IMAGE_DB_EXAMPLE 所示, 那么在執(zhí)行以下命令之后:
redis> SET date "2013.12.1"
OK
鍵空間將添加一個新的鍵值對, 這個新鍵值對的鍵是一個包含字符串 "date"
的字符串對象, 而鍵值對的值則是一個包含字符串 "2013.12.1"
的字符串對象, 如圖 IMAGE_DB_AFTER_ADD_NEW_KEY 所示。
刪除數(shù)據(jù)庫中的一個鍵, 實際上就是在鍵空間里面刪除鍵所對應的鍵值對對象。
舉個例子, 如果鍵空間當前的狀態(tài)如圖 IMAGE_DB_EXAMPLE 所示, 那么在執(zhí)行以下命令之后:
redis> DEL book
(integer) 1
鍵 book
以及它的值將從鍵空間中被刪除, 如圖 IMAGE_DB_AFTER_DEL 所示。
對一個數(shù)據(jù)庫鍵進行更新, 實際上就是對鍵空間里面鍵所對應的值對象進行更新, 根據(jù)值對象的類型不同, 更新的具體方法也會有所不同。
舉個例子, 如果鍵空間當前的狀態(tài)如圖 IMAGE_DB_EXAMPLE 所示, 那么在執(zhí)行以下命令之后:
redis> SET message "blah blah"
OK
鍵 message
的值對象將從之前包含 "hello world"
字符串更新為包含 "blah blah"
字符串, 如圖 IMAGE_DB_UPDATE_CAUSE_SET 所示。
再舉個例子, 如果我們繼續(xù)執(zhí)行以下命令:
redis> HSET book page 320
(integer) 1
那么鍵空間中 book
鍵的值對象(一個哈希對象)將被更新, 新的鍵值對 page
和 320
會被添加到值對象里面, 如圖 IMAGE_UPDATE_BY_HSET 所示。
對一個數(shù)據(jù)庫鍵進行取值, 實際上就是在鍵空間中取出鍵所對應的值對象, 根據(jù)值對象的類型不同, 具體的取值方法也會有所不同。
舉個例子, 如果鍵空間當前的狀態(tài)如圖 IMAGE_DB_EXAMPLE 所示, 那么當執(zhí)行以下命令時:
redis> GET message
"hello world"
GET 命令將首先在鍵空間中查找鍵 message
, 找到鍵之后接著取得該鍵所對應的字符串對象值, 之后再返回值對象所包含的字符串 "helloworld"
, 取值過程如圖 IMAGE_FETCH_VALUE_VIA_GET 所示。
再舉一個例子, 當執(zhí)行以下命令時:
redis> LRANGE alphabet 0 -1
1) "a"
2) "b"
3) "c"
LRANGE 命令將首先在鍵空間中查找鍵 alphabet
, 找到鍵之后接著取得該鍵所對應的列表對象值, 之后再返回列表對象中包含的三個字符串對象的值, 取值過程如圖 IMAGE_FETCH_VALUE_VIA_LRANGE 所示。
除了上面列出的添加、刪除、更新、取值操作之外, 還有很多針對數(shù)據(jù)庫本身的 Redis 命令, 也是通過對鍵空間進行處理來完成的。
比如說, 用于清空整個數(shù)據(jù)庫的 FLUSHDB 命令, 就是通過刪除鍵空間中的所有鍵值對來實現(xiàn)的。
又比如說, 用于隨機返回數(shù)據(jù)庫中某個鍵的 RANDOMKEY 命令, 就是通過在鍵空間中隨機返回一個鍵來實現(xiàn)的。
另外, 用于返回數(shù)據(jù)庫鍵數(shù)量的 DBSIZE 命令, 就是通過返回鍵空間中包含鍵值對的數(shù)量來實現(xiàn)的。
類似的命令還有 EXISTS 、 RENAME 、 KEYS , 等等, 這些命令都是通過對鍵空間進行操作來實現(xiàn)的。
當使用 Redis 命令對數(shù)據(jù)庫進行讀寫時, 服務器不僅會對鍵空間執(zhí)行指定的讀寫操作, 還會執(zhí)行一些額外的維護操作, 其中包括:
keyspace_hits
屬性和 keyspace_misses
屬性中查看。key
的閑置時間。Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: