開啟運維之路之第 6 篇——Redis五種資料型別string、list、hash、set、zset
1、上一篇介紹Redis的基礎,提供2種啟動方式,這裡彙總一下:
①寫 shell 指令碼,執行 shell 指令碼。詳見上一篇文章結尾。
②[[email protected] ~]# cd /usr/local/redis/
[[email protected] redis]# ./bin/redis-server ./redis.conf
校驗是否啟動方式:
[[email protected] redis]# ps -ef | grep -i redis
或者看下能否ping通:
[[email protected] redis]# ./bin/redis-cli
127.0.0.1:6379> ping
PONG
127.0.0.1:6379>
停止服務:[[email protected] redis]# ./bin/redis-cli shutdown
以下字串的學習,都需要進入到 redis 客戶端。命令如上面所述,進入到redis客戶端:
[[email protected] redis]# ./bin/redis-cli
127.0.0.1:6379>
2、Redis資料型別之字串型別——string
string 常用功能:①設定值;②取值;③刪除;④數值增、減;⑤其它擴充套件 (忽略大小寫,SET、set、Set 都可以)
①設定值:set key value 設定指定 key 的值
②取值:get key 獲取指定 key 的值
127.0.0.1:6379> set myKey biandanLoveYou
OK
127.0.0.1:6379> get myKey
"biandanLoveYou"
③刪除:del key 刪除指定 key 的值
127.0.0.1:6379> del myKey
(integer) 1
127.0.0.1:6379> get myKey
(nil)
④數值增、減:
incr key 自增,假如沒有定義,則預設從 0 開始;非數值型別會報錯。
127.0.0.1:6379> incr n
(integer) 1
127.0.0.1:6379> get n
"1"
下面演示數值自增、非數值報錯的例子:
數值自增:
127.0.0.1:6379> set n1 5
OK
127.0.0.1:6379> incr n1
(integer) 6
127.0.0.1:6379> get n1
"6"
非數值自增會報錯:
127.0.0.1:6379> set n2 boy
OK
127.0.0.1:6379> incr n2
(error) ERR value is not an integer or out of range
自減:decr key 假如沒有定義,則預設從 0 開始;非數值型別會報錯。
127.0.0.1:6379> decr m
(integer) -1
127.0.0.1:6379> get m
"-1"
127.0.0.1:6379> decr n1
(integer) 5
127.0.0.1:6379> get n1
"5"
127.0.0.1:6379> decr n2
(error) ERR value is not an integer or out of range
tip:一般設定商品的數量,會存入 redis ,使用者購買1個,自減1。
string 擴充套件命令:
incrby key number 指定增值量;decrby key number 指定減少量;append key str 追加字串。
127.0.0.1:6379> get m
"4"
127.0.0.1:6379> incrby m 5
(integer) 9
127.0.0.1:6379> get m
"9"
127.0.0.1:6379> decrby m 2
(integer) 7
127.0.0.1:6379> get m
"7"
127.0.0.1:6379> get n2
"boy"
127.0.0.1:6379> append n2 girl
(integer) 7
127.0.0.1:6379> get n2
"boygirl"
3、Redis資料型別之列表——list (百度百科上稱之為:雙向列表)
Redis列表是簡單的字串列表,按照插入順序排序。你可以新增一個元素到列表的頭部(左邊)或者尾部(右邊)
一個列表最多可以包含 232 - 1 個元素 (4294967295, 每個列表超過40億個元素)。
可以這樣理解 list :從右邊往左邊開的火車,左邊是車頭,右邊是車尾。
常用命令:兩端新增;兩端彈出;擴充套件命令
①兩端新增:
左邊新增:lpush key value,lpush(left push的意思)注意,是從左端開始新增,下一個新增的元素會排在上一個的左邊,把上一個元素擠在右邊。最後新增的元素,把其它元素都擠在右邊了。一般很少使用從左邊新增。因為左邊預設是車頭。
127.0.0.1:6379> lpush myList1 a b c d haha
(integer) 5
127.0.0.1:6379> lpush myList1 1 2 5 88 90
(integer) 10
注意,每種資料型別都有其新增、獲取、刪除的命令,打比方:不能使用 get 命令來獲取 list
127.0.0.1:6379> get myList1
(error) WRONGTYPE Operation against a key holding the wrong kind of value
要獲取 list 集合,從左邊位置開始獲取,使用:lrange key start stop (left range的意思)其中:start是開始位置,stop是結束位置,-1是長度-1,與Java的for迴圈list一樣。
127.0.0.1:6379> lrange myList1 0 -1
1) "90"
2) "88"
3) "5"
4) "2"
5) "1"
6) "haha"
7) "d"
8) "c"
9) "b"
10) "a"
list 沒有陣列越界的概念,比如 stop 的數值可以比 list 的長度大,這樣會獲取所有的 list 資料:
127.0.0.1:6379> lrange myList1 0 20
127.0.0.1:6379> lrange myList1 0 20
1) "90"
2) "88"
3) "5"
4) "2"
5) "1"
6) "haha"
7) "d"
8) "c"
9) "b"
10) "a"
右端新增(大多數人使用):rpush key value,rpush(right push的意思)如:127.0.0.1:6379> rpush myList1 boy girl
127.0.0.1:6379> lrange myList1 0 -1
1) "90"
2) "88"
3) "5"
4) "2"
5) "1"
6) "haha"
7) "d"
8) "c"
9) "b"
10) "a"
11) "boy"
12) "girl"
②獲取 list 列表的長度:llen key
127.0.0.1:6379> llen myList1
(integer) 12
③通過索引獲取資料:lindex key
127.0.0.1:6379> lindex myList1 2
"5"
④從左端移出並獲取列表的第 1 個元素:lpop key
先建立一個測試的list,新增元素:
127.0.0.1:6379> lpush myList2 11 22 33 boy friend
(integer) 5
127.0.0.1:6379> lrange myList2 0 -1
1) "friend"
2) "boy"
3) "33"
4) "22"
5) "11"
然後執行移出並獲取左端的1個元素(即最後新增的元素,其它元素都被最後一個元素擠在右邊了):
127.0.0.1:6379> lpop myList2
"friend"
127.0.0.1:6379> lrange myList2 0 -1
1) "boy"
2) "33"
3) "22"
4) "11"
結果發現: friend 元素被移出,並且獲取了它。
⑤從右端移出並獲取列表的第 1 個元素:rpop key
127.0.0.1:6379> rpop myList2
"11"
127.0.0.1:6379> lrange myList2 0 -1
1) "boy"
2) "33"
3) "22"
⑥集合的頭部、尾部新增元素:lpushx key value1 value2... rpushx key value1 value2 ...
127.0.0.1:6379> lpushx myList2 good
(integer) 4
127.0.0.1:6379> rpushx myList2 bad
(integer) 5
127.0.0.1:6379> lrange myList2 0 -1
1) "good"
2) "boy"
3) "33"
4) "22"
5) "bad"
⑦從指定方向刪除集合元素: lrem key count value,特別注意這個 count
先新增一個測試的集合 myList3
127.0.0.1:6379> lpush myList3 2 4 6 8 1 8 6 4 2
(integer) 9
127.0.0.1:6379> lrange myList3 0 -1
1) "2"
2) "4"
3) "6"
4) "8"
5) "1"
6) "8"
7) "6"
8) "4"
9) "2"
從左邊開始,刪除 2 個 6:lrem myList3 2 6
127.0.0.1:6379> lrem myList3 2 6
(integer) 2
127.0.0.1:6379> lrange myList3 0 -1
1) "2"
2) "4"
3) "8"
4) "1"
5) "8"
6) "4"
7) "2"
說明:左邊開始,count為正整數;右邊開始,count為負整數。0 表示刪除所有
從右邊開始,刪除 1 個 4:lrem myList3 -1 4
127.0.0.1:6379> lrem myList3 -1 4
(integer) 1
127.0.0.1:6379> lrange myList3 0 -1
1) "2"
2) "4"
3) "8"
4) "1"
5) "8"
6) "2"
刪除所有的 1:lrem myList3 0 1
127.0.0.1:6379> lrem myList3 0 1
(integer) 1
127.0.0.1:6379> lrange myList3 0 -1
1) "2"
2) "4"
3) "8"
4) "8"
5) "2"
⑧設定集合元素的值:lset key index value 。注意索引是從 0 開始。與 Java 的 list 、陣列的集合從 0 開始性質一樣。
127.0.0.1:6379> lset myList3 2 66
OK
127.0.0.1:6379> lrange myList3 0 -1
1) "2"
2) "4"
3) "66"
4) "8"
5) "2"
這樣,原來在第 3 個位置的 8 就變成了 66 。
⑨在指定元素之前、之後新增元素:linsert key before|after pivot value
127.0.0.1:6379> linsert myList3 before 66 boy
(integer) 6
127.0.0.1:6379> linsert myList3 after 4 girl
(integer) 7
127.0.0.1:6379> lrange myList3 0 -1
1) "2"
2) "4"
3) "girl"
4) "boy"
5) "66"
6) "8"
7) "2"
把A集合尾部元素彈出並插入到B集合頭部:rpoplpush sourceList descList
127.0.0.1:6379> rpoplpush myList2 myList3
"bad"
127.0.0.1:6379> lrange myList3 0 -1
1) "bad"
2) "2"
3) "4"
4) "girl"
5) "boy"
6) "66"
7) "8"
8) "2"
4、Redis資料型別之雜湊——hash
Redis hash 是一個string型別的field和value的對映表,hash特別適合用於儲存物件。
Redis 中每個 hash 可以儲存 232 - 1 鍵值對(40多億)。
hash常用命令:賦值、取值、刪除、增加數字、判斷欄位是否存在、獲取hash屬性個數、獲取hash所有屬性名稱。
①賦值、取值:hset key field value ; hget key field
127.0.0.1:6379> hset h1 username biandan
(integer) 1
127.0.0.1:6379> hget h1 username
"biandan"
多個欄位一起設定值、取值:hmset key field1 value1 field2 value2 ... hmget key field1 field2
127.0.0.1:6379> hmset h2 username Hello password 123
OK
127.0.0.1:6379> hmget h2 username password
1) "Hello"
2) "123"
②獲取 hash 中指定 key 的所有欄位和值:hgetall key
127.0.0.1:6379> hgetall h2
1) "username"
2) "Hello"
3) "password"
4) "123"
③刪除屬性,可以一次性刪除多個:hdel key field1 field2 ...
127.0.0.1:6379> hdel h2 username password
(integer) 2
127.0.0.1:6379> hgetall h2
(empty list or set)
④增加數字:hincrby key field count
127.0.0.1:6379> hset h3 age 15
(integer) 1
127.0.0.1:6379> hincrby h3 age 5
(integer) 20
127.0.0.1:6379> hget h3 age
"20"
⑤判斷欄位是否存在:存在 1 ,不存在 0 :hexists key field
127.0.0.1:6379> hexists h3 age
(integer) 1
127.0.0.1:6379> hexists h3 tall
(integer) 0
⑥獲取欄位數量:hlen key
127.0.0.1:6379> hlen h3
(integer) 1
⑦獲取所有屬性名(欄位名):hkeys key
127.0.0.1:6379> hkeys h1
1) "username"
127.0.0.1:6379> hkeys h2
(empty list or set)
⑧獲取所有屬性值:hvals key
127.0.0.1:6379> hvals h1
1) "biandan"
127.0.0.1:6379> hvals h2
(empty list or set)
5、Redis資料型別之集合——set
Redis 的 Set 是 String 型別的無序集合。集合成員是唯一的,這就意味著集合中不能出現重複的資料。
Redis 中集合是通過雜湊表實現的,所以新增,刪除,查詢的複雜度都是 O(1)。
集合中最大的成員數為 232 - 1 (4294967295, 每個集合可儲存40多億個成員)。
set常用命令:
新增/刪除元素,獲取集合中的元素,集合中的並、交、差集運算,擴充套件命令
①新增、獲取、刪除元素:sadd key value1 value2 ... smembers key srem key value1 value2 ...
注意:set 不允許有重複元素出現,不會重複新增重複元素。
127.0.0.1:6379> sadd s1 n b a 1 2 5
(integer) 6
127.0.0.1:6379> smembers s1
1) "b"
2) "n"
3) "1"
4) "a"
5) "5"
6) "2"
127.0.0.1:6379> sadd s1 c b a
(integer) 1
127.0.0.1:6379> smembers s1
1) "c"
2) "a"
3) "b"
4) "1"
5) "n"
6) "5"
7) "2"
127.0.0.1:6379> srem s1 b
(integer) 1
127.0.0.1:6379> smembers s1
1) "c"
2) "a"
3) "1"
4) "n"
5) "5"
6) "2"
②判斷某個元素是否存在,存在 1 ,不存在 0 :sismember key field
127.0.0.1:6379> sismember s1 n
(integer) 1
127.0.0.1:6379> sismember s1 b
(integer) 0
③計算元素總數:scard key
127.0.0.1:6379> scard s1
(integer) 6
④計算並、交、差 集:
先新增 s2 做測試
127.0.0.1:6379> sadd s2 n c a a 5 8
(integer) 5
127.0.0.1:6379> smembers s1
1) "c"
2) "a"
3) "1"
4) "n"
5) "5"
6) "2"
127.0.0.1:6379> smembers s2
1) "a"
2) "c"
3) "5"
4) "n"
5) "8"
並集:sunion key1 key2
127.0.0.1:6379> sunion s1 s2
1) "c"
2) "a"
3) "8"
4) "1"
5) "n"
6) "2"
7) "5"
交集:sinter key1 key2
127.0.0.1:6379> sinter s1 s2
1) "a"
2) "c"
3) "5"
4) "n"
差集:sdiff key1 key2 注意:差集以 key1 (前者) 為參考。
127.0.0.1:6379> sdiff s1 s2
1) "1"
2) "2"
127.0.0.1:6379> sdiff s2 s1
1) "8"
⑤把並、交、差 集存入新的集合
並集存入新集合:sunionstore resultSet key1 key2
127.0.0.1:6379> sunionstore sr3 s1 s2
(integer) 7
127.0.0.1:6379> smembers sr3
1) "c"
2) "a"
3) "8"
4) "1"
5) "n"
6) "2"
7) "5"
交集存入新集合:sinterstore resultSet key1 key2
127.0.0.1:6379> sinterstore sr2 s1 s2
(integer) 4
127.0.0.1:6379> smembers sr2
1) "a"
2) "c"
3) "5"
4) "n"
差集存入新集合:sdiffstore resultSet key1 key2
127.0.0.1:6379> sdiffstore sr1 s1 s2
(integer) 2
127.0.0.1:6379> smembers sr1
1) "1"
2) "2"
儲存Set使用場景: 跟蹤一些唯一性資料,用於維護資料物件之間的關聯關係。
6、Redis資料型別之有序集合——zset
Redis 有序集合和集合一樣也是string型別元素的集合,且不允許重複的成員。
不同的是每個元素都會關聯一個double型別的分數。redis正是通過分數來為集合中的成員進行從小到大的排序。
有序集合的成員是唯一的,但分數(score)卻可以重複。
集合是通過雜湊表實現的,所以新增,刪除,查詢的複雜度都是O(1)。
集合中最大的成員數為 232 - 1 (4294967295, 每個集合可儲存40多億個成員)。
Sorted-Set使用場景:
大型線上遊戲積分排行榜
構建索引資料
①新增元素、查詢元素:zadd key score1 field1 score2 field2 ; zrange key start stop
127.0.0.1:6379> zadd z1 8 aa 5 bb 2 cc
(integer) 3
127.0.0.1:6379> zrange z1 0 -1
1) "cc"
2) "bb"
3) "aa"
說明:新增集合 z1 ,元素是 aa,bb和cc,評分是8,5和2,評分在前,元素在後。
集合裡的排序是根據評分從小到大排序的,所以輸出的時候評分小的輸出在前。
重複新增元素:有則覆蓋,沒有則新增。例子中,aa已經存在,覆蓋;dd沒有,新增。
127.0.0.1:6379> zadd z1 25 aa
(integer) 0
127.0.0.1:6379> zadd z1 35 dd
(integer) 1
127.0.0.1:6379> zrange z1 0 -1
1) "cc"
2) "bb"
3) "aa"
4) "dd"
之前aa的評分是8,現在看aa的評分是否是25:zscore key filed
127.0.0.1:6379> zscore z1 aa
"25"
是25,證明是被覆蓋了。
②刪除元素:zrem key field
127.0.0.1:6379> zrem z1 bb
(integer) 1
127.0.0.1:6379> zrange z1 0 -1
1) "cc"
2) "aa"
3) "dd"
③檢視集合裡元素個數:zcard key field
127.0.0.1:6379> zcard z1
(integer) 3
檢視元素,包括評分也列出來:
127.0.0.1:6379> zrange z1 0 -1 withscores
1) "cc"
2) "2"
3) "aa"
4) "25"
5) "dd"
6) "35"
④降序排序輸出:zrevrange key start stop withscores (說明:reverse是反向的意思)
127.0.0.1:6379> zrevrange z1 0 -1 withscores
1) "dd"
2) "35"
3) "aa"
4) "25"
5) "cc"
6) "2"
新增幾個測試元素:
127.0.0.1:6379> zadd z1 3 y 5 n 30 w 18 q
(integer) 4
127.0.0.1:6379> zrange z1 0 -1 withscores
1) "cc"
2) "2"
3) "y"
4) "3"
5) "n"
6) "5"
7) "q"
8) "18"
9) "aa"
10) "25"
11) "w"
12) "30"
13) "dd"
14) "35"
根據評分範圍來查詢元素:zrangebyscore key score1 score2 withscores
127.0.0.1:6379> zrangebyscore z1 10 20 withscores
1) "q"
2) "18"
限定查詢起始,類似分頁:zrangebyscore key score1 score2 withscores limit start stop
127.0.0.1:6379> zrangebyscore z1 2 20 withscores limit 0 3
1) "cc"
2) "2"
3) "y"
4) "3"
5) "n"
6) "5"
查詢指定評分範圍的元素個數:zcount key start stop
127.0.0.1:6379> zcount z1 3 30
(integer) 5
給指定元素加分:zincrby key score field
127.0.0.1:6379> zincrby z1 13 cc
"15"
根據排名來刪除元素,刪除2個:zremrangebyrank key start stop (從 0 開始計算)
127.0.0.1:6379> zremrangebyrank z1 0 1
(integer) 2
127.0.0.1:6379> zrange z1 0 -1 withscores
1) "cc"
2) "15"
3) "q"
4) "18"
5) "aa"
6) "25"
7) "w"
8) "30"
9) "dd"
10) "35"
根據具體評分範圍來刪除元素:zremrangebyscore key start stop
127.0.0.1:6379> zremrangebyscore z1 10 20
(integer) 2
127.0.0.1:6379> zrange z1 0 -1 withscores
1) "aa"
2) "25"
3) "w"
4) "30"
5) "dd"
6) "35"