Redis五種數據類型

Redis簡介

Redis 是一個開源的使用 ANSI C 語言編寫、遵守 BSD 協議、支持網絡、可基於內存亦可持久化的日誌型、Key-Value 數據庫,並提供多種語言的 API。
它通常被稱爲數據結構服務器,因爲值(value)可以是 字符串(String), 哈希(Map),列表(list),集合(sets)和 有序集合(sorted sets)等類型。

Redis安裝

$ wget http://download.redis.io/releases/redis-5.0.5.tar.gz
$ tar xzf redis-5.0.5.tar.gz
$ cd redis-5.0.5
$ make

以後臺方式啓動Redis

修改Redis.conf文件

將daemonize on
修改爲

daemonize yes

啓動Redis

src/redis-server redis.conf

Redis五種數據類型

開機啓動Redis

執行安裝腳本,一直默認就可以

./utils/install_server.sh  

Redis五種數據類型

mv /etc/init.d/redis_6379 /etc/init.d/redis

設置Redis密碼

vim /etc/redis/6379.conf
requirepass redispass
service redis restart

再次連接發現需要輸入密碼
Redis五種數據類型

Redis命令

全局命令

獲取鍵

keys pattern

keys還支持通配符

127.0.0.1:6379> set we "hello"
OK
127.0.0.1:6379> keys *
1) "we"
127.0.0.1:6379> set name wanger
OK
127.0.0.1:6379> keys name
1) "name"
127.0.0.1:6379> keys *
1) "name"
2) "we"

keys 命令遍歷了Redis中所有的鍵,當鍵的數量過多時會影響Redis性能

刪除鍵

del key1 key2 ..

例如:

127.0.0.1:6379> keys *
1) "qwe"
2) "asd"
3) "we"
127.0.0.1:6379> del asd qwe
(integer) 2
127.0.0.1:6379> keys *
1) "we"

判斷鍵是否存在

exists key1 key2

例如:

127.0.0.1:6379> exists we
(integer) 1
127.0.0.1:6379> exists name
(integer) 0
127.0.0.1:6379> set qwe 2
OK
127.0.0.1:6379> exists we qwe
(integer) 2
127.0.0.1:6379> exists we name
(integer) 1

獲取鍵的總數

dbsize

例如:

127.0.0.1:6379> dbsize
(integer) 2
127.0.0.1:6379> keys *
1) "qwe"
2) "we"

獲取鍵的數據類型

type key

例如:

127.0.0.1:6379> type we
string
127.0.0.1:6379> lpush list1 1 2 3
(integer) 3
127.0.0.1:6379> type list1
list

對列表、集合、有序集合的元素進行排序

sort key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern ...]] [ASC|DESC] [ALPHA] [STORE destination]

例如:

127.0.0.1:6379> lrange list 0 -1
1) "5"
2) "7"
3) "2"
4) "4"
5) "3"
6) "1"
sort list desc limit 0 5 
1) "7"
2) "5"
3) "4"
4) "4"
5) "3"
127.0.0.1:6379> lpush list2 asd qwe zxc
(integer) 3
sort list2 desc limit 0 5 alpha
1) "zxc"
2) "qwe"
3) "asd"

清空數據庫

flushdb  //清空當前數據庫
flushall  //清空所有數據庫

例如:

127.0.0.1:6379[11]> set a 1
OK
127.0.0.1:6379[11]> get a 
"1"
127.0.0.1:6379[11]> flushdb
OK
127.0.0.1:6379[11]> get a 
(nil)

將指定的鍵移動到其他數據庫

move key db  

例如:

127.0.0.1:6379[11]> set a 1
OK
127.0.0.1:6379[11]> move a 2
(integer) 1
127.0.0.1:6379[11]> select 2
OK
127.0.0.1:6379[2]> get a
"1"

字符串

字符串類型是Redis最基礎的數據結構,字符串類型是其他幾種數據類型的基礎,他能存儲任何形式的字符串,包括二進制數據

設值取值

set key value [EX seconds] [PX milliseconds] [NX|XX]
get key
  • nx:鍵必須不存在,纔可以設置成功,用於添加。
  • xx:與nx相反,鍵必須存在,纔可以設置成功,用於更新

例如:

127.0.0.1:6379> set name wanger
OK
127.0.0.1:6379> get name
"wanger"
127.0.0.1:6379> setnx name wanger 
(integer) 0
127.0.0.1:6379> set name wang xx
OK

批量設值取值

mset key1 value1 key2 value2 ..
mget key1 key2

例如:

127.0.0.1:6379> mset key1 1 key2 2
OK
127.0.0.1:6379> mget key1 key2
1) "1"
2) "2"

對鍵值自增自減

incr key
decr key

例如:

127.0.0.1:6379> incr key1
(integer) 2
127.0.0.1:6379> incr key2
(integer) 3
127.0.0.1:6379> get key1
"2"
127.0.0.1:6379> get key2
"3"
127.0.0.1:6379> get we
"hello"
127.0.0.1:6379> incr we
(error) ERR value is not an integer or out of range
127.0.0.1:6379> decr key1
(integer) 1
127.0.0.1:6379> decr key2
(integer) 2

追加值

append key value

例如:

127.0.0.1:6379> append key hello
(integer) 5
127.0.0.1:6379> append key world
(integer) 10
127.0.0.1:6379> get key
"helloworld"

獲取字符串長度

strlen key

例如:

127.0.0.1:6379> get key
"helloworld"
127.0.0.1:6379> strlen key
(integer) 10
127.0.0.1:6379> set name "王二"
OK
127.0.0.1:6379> strlen name
(integer) 6

設置和獲取指定位置的字符串

setrange key offset value
getrange key start end

例如:

127.0.0.1:6379> SET key1 "Hello World"
OK
127.0.0.1:6379> setrange key1 6 "Redis"
(integer) 11
127.0.0.1:6379> get key1
"Hello Redis"
127.0.0.1:6379> getrange key1 6 12
"Redis"

字符串對象編碼

字符串類型的內部編碼有3種:

  • int:8個字節的長整型。
  • embstr:小於等於39個字節的字符串。
  • raw:大於39個字節的字符串。

例如:

127.0.0.1:6379> set num 123456
OK
127.0.0.1:6379> object encoding num
"int"
127.0.0.1:6379> set short qweasd
OK
127.0.0.1:6379> object encoding short
"embstr"
127.0.0.1:6379> set raw "when you love me I have lost of plot wow wow"
OK
127.0.0.1:6379> object encoding raw
"raw"

列表

Redis列表可以存儲一個有序的字符串列表,內部使用雙向鏈表實現,雙向鏈表作爲一種常見的數據結構,雙向鏈表的每個數據節點都有兩個指針,分別指向後繼與前驅節點,從雙向鏈表中的任意一個節點開始都可以很方便地訪問其前驅與後繼節點,因此獲取越接近兩端的元素就越快

從左右兩邊插入元素或者從某一個元素前後插入數據

lpush key value1 value2 value3
rpush key value1 value2 value3
linsert key BEFORE|AFTER pivot value

例如:

127.0.0.1:6379> lpush names 1 2 3 4
(integer) 4
127.0.0.1:6379> lrange names 0 4
1) "4"
2) "3"
3) "2"
4) "1"
127.0.0.1:6379> rpush nums 1 2 3 4
(integer) 4
127.0.0.1:6379> lrange nums 0 4
1) "1"
2) "2"
3) "3"
4) "4"
127.0.0.1:6379> linsert nums before 2 5
(integer) 5
127.0.0.1:6379> lrange nums 0 5
1) "1"
2) "5"
3) "2"
4) "3"
5) "4"

從列表兩端刪除元素

lpop key
rpop key

例如:

127.0.0.1:6379> lrange nums 0 5
1) "1"
2) "5"
3) "2"
4) "3"
5) "4"
127.0.0.1:6379> lpop nums
"1"
127.0.0.1:6379> rpop nums
"4"
127.0.0.1:6379> lrange nums 0 5
1) "5"
2) "2"
3) "3"

獲取給定位置上的元素

lindex key index

例如:

127.0.0.1:6379> lrange nums 0 5
1) "5"
2) "2"
3) "3"
127.0.0.1:6379> lindex nums 2
"3"
127.0.0.1:6379> lindex nums 1
"2"
127.0.0.1:6379> lindex nums -1
"3"

獲取給定範圍的元素

lrange key start stop

例如:

127.0.0.1:6379> lrange nums 0 1
1) "5"
2) "2"
127.0.0.1:6379> lrange nums 0 2
1) "5"
2) "2"
3) "3"

獲取列表長度

llen key

例如:

127.0.0.1:6379> lrange nums 0 3
1) "5"
2) "2"
3) "3"
127.0.0.1:6379> llen nums
(integer) 3

從列表中刪除值

lrem key count value
  • count > 0:刪除數量爲count的從頭到尾移動的值爲value的元素。
  • count < 0:刪除數量爲count的從尾到頭移動的值爲value的元素。
  • count = 0:刪除所有等於value的元素。

例如:

127.0.0.1:6379> lrange mylist 0 10
 1) "1"
 2) "2"
 3) "3"
 4) "4"
 5) "5"
 6) "2"
 7) "3"
 8) "4"
 9) "5"
10) "5"
127.0.0.1:6379> lrem mylist 1 5
(integer) 1
127.0.0.1:6379> lrange mylist 0 10
 1) "1"
 2) "2"
 3) "3"
 4) "4"
 5) "2"
 6) "3"
 7) "4"
 8) "5"
 9) "5"
127.0.0.1:6379> lrem mylist -2 5
(integer) 2
127.0.0.1:6379> lrange mylist 0 10
1) "1"
2) "2"
3) "3"
4) "4"
5) "2"
6) "3"
7) "4"
127.0.0.1:6379> lrem mylist 0 2
(integer) 2
127.0.0.1:6379> lrange mylist 0 11
1) "1"
2) "3"
3) "4"
4) "3"
5) "4"

修改指定索引的元素

lset key index value

例如:

127.0.0.1:6379> lrange mylist 0 6
1) "1"
2) "3"
3) "4"
4) "3"
5) "4"
127.0.0.1:6379> lset mylist 1 5
OK
127.0.0.1:6379> lrange mylist 0 6
1) "1"
2) "5"
3) "4"
4) "3"
5) "4"

阻塞操作

blpop和brpop分別是lpop和rpop的阻塞版本,功能類似,當列表爲空時,會發生阻塞,timeout可定義阻塞時間,timeout爲0時將一直阻塞,直到在另一個客戶端中往列表中加入元素

blpop key1 key2 timeout
brpop key1 key2 timeout

例如:

127.0.0.1:6379> lrange list2 0 4
1) "4"
2) "3"
3) "2"
127.0.0.1:6379> lrange list1 0 4
1) "8"
2) "7"
127.0.0.1:6379> blpop list1 list2 0
1) "list1"
2) "8"
127.0.0.1:6379> brpop list1 list2 0
1) "list1"
2) "7"
127.0.0.1:6379> brpop list1 list2 0
1) "list2"
2) "2"
127.0.0.1:6379> brpop list1 list2 0
1) "list2"
2) "3"
127.0.0.1:6379> brpop list1 list2 0
1) "list2"
2) "4"
127.0.0.1:6379> brpop list1 list2 0
1) "list2"
2) "1"
(18.49s)
在另一個客戶端執行
127.0.0.1:6379> lpush list2 1
(integer) 1

列表內部編碼

  • ziplist(壓縮列表):列表元素保存的所有字符串元素的長度都小於64字節且元素數量小於512個時使用ziplist編碼
  • linkedlist(鏈表):當列表類型無法滿足兩個條件的任意一個的時候,redis會使用linkedlist作爲列表的內部實現
  • quicklist:list的內部實現quicklist是一個ziplist的雙向鏈表,雙向鏈表是由多個節點(Node)組成的,quicklist的每個節點都是一個ziplist。

參考張鐵蕾http://zhangtielei.com/posts/blog-redis-quicklist.html

哈希

哈希是由與值關聯的字段組成的映射。字段和值都是字符串,哈希類型中的映射關係叫作field-value

設值取值

hset key field value
hget key field

例如:

127.0.0.1:6379> hset ha name wanger
(integer) 1
127.0.0.1:6379> hget ha name
"wanger"

批量設值取值

hmset key field1 value1 field2 value2
hmget key field1 field2

例如:

127.0.0.1:6379> hmset he name wanger sex nan
OK
127.0.0.1:6379> hmget he name sex
1) "wanger"
2) "nan"

刪除field

hdel key field1 field2

例如:

127.0.0.1:6379> hdel he name 
(integer) 1
127.0.0.1:6379> hget he name
(nil)

獲取field個數

hlen key

例如:

127.0.0.1:6379> hmset he name wanger sex nan age 18
OK
127.0.0.1:6379> hlen he
(integer) 3

獲取哈希中的所有字段和值

hgetall key

例如:

127.0.0.1:6379> hgetall he
1) "sex"
2) "nan"
3) "name"
4) "wanger"
5) "age"
6) "18"

獲取哈希中的所有字段

hkeys key

例如:

127.0.0.1:6379> hkeys he
1) "sex"
2) "name"
3) "age"

判斷哈希字段是否存在

hexists key field

例如:

127.0.0.1:6379> hexists he name
(integer) 1
127.0.0.1:6379> hexists he sex
(integer) 1

將哈希字段的值遞增

hincrby key field increment

例如:

127.0.0.1:6379> hincrby asd asdf 2
(integer) 3
127.0.0.1:6379> hget asd asdf
"3"
127.0.0.1:6379> hincrby asd asdf 2
(integer) 5
127.0.0.1:6379> hget asd asdf
"5"

獲取哈希中的所有值

hvals key

例如:

127.0.0.1:6379> hvals he
1) "nan"
2) "wanger"
3) "18"

內部編碼:

  • ziplist(壓縮列表):當哈希類型元素個數小於hash-max-ziplist-entries配置(默認512個)、同時所有值都小於hash-max-ziplist-value配置(默認64字節)時,Redis會使用ziplist作爲哈希的內部實現,ziplist使用更加緊湊的結構實現多個元素的連續存儲,所以在節省內存方面比hashtable更加優秀。
  • hashtable(哈希表):當哈希類型無法滿足ziplist的條件時,Redis會使用hashtable作爲哈希的內部實現,因爲此時ziplist的讀寫效率會下降,而hashtable的讀寫時間複雜度爲O(1)

例如:

127.0.0.1:6379> hset ziplist hash 12335452335235fwgvsfwbhfbwhhfwuesrfhwueywhufgbrewfghusfhwueughsajkifo34ejigji
(integer) 1
127.0.0.1:6379> hmset hash asd fcfg zdf fty
OK

集合

唯一且無序的字符串元素的集合。

將一個或多個成員添加到集合中

sadd key member1 member2 

例如

127.0.0.1:6379> sadd set s1 s2
(integer) 0

獲取集合所有值

smembers key

例如:

127.0.0.1:6379> smembers set
1) "s2"
2) "s1"
3) "s3"

刪除集合的元素

srem key member1 members2

例如:

127.0.0.1:6379> srem set s2
(integer) 1
127.0.0.1:6379> smembers set
1) "s1"
2) "s3"

獲取元素的長度

scard key

例如:

127.0.0.1:6379> scard set
(integer) 2

隨機獲取指定個數的元素

srandmember key [count]

例如:

127.0.0.1:6379> srandmember set 1
1) "s1"

判斷元素是否在集合中

sismember key member

例如:

127.0.0.1:6379> sismember set s2
(integer) 0
127.0.0.1:6379> sismember set s3
(integer) 1

從集合中彈出指定數量的元素

spop key [count]

例如:

127.0.0.1:6379> smembers set
1) "s5"
2) "s4"
3) "s1"
4) "s3"
127.0.0.1:6379> spop set
"s4"
127.0.0.1:6379> spop set 3
1) "s5"
2) "s1"
3) "s3"
127.0.0.1:6379> smembers set
(empty list or set)

集合間的並集運算

sunion key1 key2 

例如:

127.0.0.1:6379> sadd set1 1 2 3
(integer) 3
127.0.0.1:6379> sadd set2 2 3 4 5
(integer) 4
127.0.0.1:6379> sunion set1 set2
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"

集合間的交集運算

sinter key1 key2

例如:

127.0.0.1:6379> sinter set1 set2
1) "2"
2) "3"

集合間的差集運算

sdiff key1 key2

例如:

127.0.0.1:6379> sdiff set1 set2
1) "1"
127.0.0.1:6379> sdiff set2 set1
1) "4"
2) "5"

內部編碼

  • intset(整數集合):當集合中的元素都是整數且元素個數小於set-max-intset-entries配置(默認512個)時,Redis會選用intset來作爲集合的內部實現,從而減少內存的使用。
  • hashtable(哈希表):當集合類型無法滿足intset的條件時,Redis會使用hashtable作爲集合的內部實現。

例如:

127.0.0.1:6379> sadd set3 s1 s2 s3
(integer) 3
127.0.0.1:6379> object encoding set3
"hashtable"
127.0.0.1:6379> sadd set4 1 2 3
(integer) 3
127.0.0.1:6379> object encoding set4
"intset"

有序集合

每個字符串元素都與一個稱爲score的浮點值相關聯。元素總是按它們的分數排序,因此與Sets不同,可以檢索一系列元素

添加元素

zadd key [NX|XX] [CH] [INCR] score1 member1 score2 member2

例如:

127.0.0.1:6379> zadd score xx 80 wanger 80 huazai 95 dongdong +inf a
(integer) 0
127.0.0.1:6379> zrange score 0 -1
1) "huazai"
2) "wanger"
3) "dongdong"
4) "a"
+inf和-inf分別表示正無窮和負無窮

獲取某個成員的分數

zscore key member

例如:

127.0.0.1:6379> zscore score dongdong
"95"

對成員進行排名,從0開始

zrange key start end [withscores]  #升序排列
zrevrange key start end [withscores]  #降序排列

例如:

127.0.0.1:6379> zadd score 95 huazai 90 wanger 85 dongdong +inf a
(integer) 0
127.0.0.1:6379> zrank score huazai
(integer) 2
127.0.0.1:6379> zrevrank score huazai
(integer) 1
127.0.0.1:6379> zrevrank score a
(integer) 0
127.0.0.1:6379> zrange score 0 -1 WITHSCORES
1) "dongdong"
2) "85"
3) "wanger"
4) "90"
5) "huazai"
6) "95"
7) "a"
8) "inf"

獲取成員個數

zcard key

例如:

127.0.0.1:6379> zcard score
(integer) 4

刪除成員

zrem key member1 member2

例如:

127.0.0.1:6379> zrem score dongdong
(integer) 1
127.0.0.1:6379> zrange score 0 -1
1) "wanger"
2) "huazai"
3) "a"

增加成員的分數

zincrby key increment member

例如:

127.0.0.1:6379> zincrby score 5 wanger
"95"

獲取指定分數範圍的成員

zrangebyscore key min max [withscores] [limit offset count] #升序
zrevrangebyscore key max min [withscores] [limit offset count] #降序

例如:

127.0.0.1:6379> zrangebyscore score 80 90 withscores
1) "dongdong"
2) "85"
3) "wanger"
4) "90"
127.0.0.1:6379> zrevrangebyscore score 95 80 withscores
1) "huazai"
2) "95"
3) "wanger"
4) "90"
5) "dongdong"
6) "85"

獲取指定分數範圍成員個數

zcount key min max

例如:

127.0.0.1:6379> zcount score 85 95
(integer) 3

刪除指定分數範圍的成員

zremrangebyscore key min max

例如:

127.0.0.1:6379> zremrangebyscore score 85 90
(integer) 2

有序集合的交集運算

zinterstore destination numkeys key1 key2 [WEIGHTS weight]
  • destination:交集計算結果保存到這個鍵。
  • numkeys:需要做交集計算鍵的個數。
  • key[key...]:需要做交集計算的鍵。
  • weights weight[weight...]:每個鍵的權重,在做交集計算時,每個鍵中
  • 的每個member會將自己分數乘以這個權重,每個鍵的權重默認是1。
  • aggregate sum|min|max:計算成員交集後,分值可以按照sum(和)、
  • min(最小值)、max(最大值)做彙總,默認值是sum。

最終的結果就是權重乘分數,之後再進行聚合
例如:

127.0.0.1:6379> zadd user 10 wanger 20 huazai 30 dongdong
(integer) 3
127.0.0.1:6379> zadd user1 15 wanger 35 huazai
(integer) 2
127.0.0.1:6379> zinterstore userset 2 user user1
(integer) 2
127.0.0.1:6379> zrange userset 0 -1 withscores
1) "wanger"
2) "25"
3) "huazai"
4) "55"
127.0.0.1:6379> zinterstore user2set 2 user user1 weights 1 0.5 aggregate min
(integer) 2
127.0.0.1:6379> zrange user2set 0 -1 withscores
1) "wanger"
2) "7.5"
3) "huazai"
4) "17.5"

有序集合的並集計算

zunionstore destination numkeys key [key ...] [WEIGHTS weight]

例如:

127.0.0.1:6379> zadd user 10 wanger 20 huazai 30 dongdong
(integer) 3
127.0.0.1:6379> zadd user1 15 wanger 35 huazai
(integer) 2
127.0.0.1:6379> zunionstore user3set 2 user user1 weights 1 0.5 aggregate max
(integer) 3
127.0.0.1:6379> zrange user3set 0 -1 withscores
1) "wanger"
2) "10"
3) "huazai"
4) "20"
5) "dongdong"
6) "30"

內部編碼

  • ziplist(壓縮列表):當有序集合的元素小於zset-max-ziplist-entries配置(默認是128個),同時每個元素的值都小於zset-max-ziplist-value(默認是64字節)時,Redis會用ziplist來作爲有序集合的內部編碼實現,ziplist可以有效的減少內存的使用
  • skiplist(跳躍表):當ziplist的條件不滿足時,有序集合將使用skiplist作爲內部編碼的實現,來解決此時ziplist造成的讀寫效率下降的問題.

例如:

127.0.0.1:6379> zadd sortset1 10 a 20 b 30 c
(integer) 3
127.0.0.1:6379> object encoding sortset1
"ziplist"
127.0.0.1:6379> zadd sortset2 10 a 20 b 30 cddddddddddddddddddddddffffffffffffffffffffffffwfwfwggggggggggggggggggwg4yhhhhhhhhhhhhhhhh
(integer) 3
127.0.0.1:6379> object encoding sortset2
"skiplist"  

歡迎關注我的公號“沒有故事的陳師傅”
Redis五種數據類型

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章