1. 程式人生 > >開啟運維之路之第 6 篇——Redis五種資料型別string、list、hash、set、zset

開啟運維之路之第 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"