Redis 筆記系列(五)——redis五大數據類型概述

 

Redis  數據類型:

Redis的數據類型,其實最好的介紹文檔是redis的官方文檔:http://redis.io/topics/data-types-introhtml

數據類型有不少種,最經常使用的爲如下5個:java

字符串String、列表List、集合Set、散列表Hash、有序集合ZSet(Sorted set)python

其餘還有:golang

  • Bit arrays (or simply bitmaps): it is possible, using special commands, to handle String values like an array of bits: you can set and clear individual bits, count all the bits set to 1, find the first set or unset bit, and so forth.
  • HyperLogLogs: this is a probabilistic data structure which is used in order to estimate the cardinality of a set. Don't be scared, it is simpler than it seems... See later in the HyperLogLog section of this tutorial.

這裏就不作介紹了。redis

 

 

String字符串類型

string類型是redis最基本的類型,內衣裂解成與Memcahed同樣的類型,一個key對應一個value。數組

string類型是二進制安全的,意思是redis的string能夠包含任何數據,好比jpg圖片或者序列化對象。安全

string類型是Redis最基本的數據類型,一個redis中字符串value最多能夠是512M。(這是個上限,但別犯2,真去存個value是512M的value。好吧,打個比方,格力空調說他們每晚只用一度電,秒懂?)bash

Redis之因此可以幹掉mencached,一個最主要的緣由就是redis除了字符串類型,還支持其餘多種數據類型。服務器

 

Redis字符串(String)
    單值單value
         set/get/del/append/strlen
        Incr/decr/incrby/decrby,必定要是數字才能進行加減
         getrange/setrange
         setex(set with expire)鍵秒值/setnx(set if not exist)
         mset/mget/msetnx
         getset(先get再set)網絡

127.0.0.1:6379> get k1
"100"
127.0.0.1:6379> type k1
string
127.0.0.1:6379> INCR k1
(integer) 101
127.0.0.1:6379> get k1
"101"
127.0.0.1:6379> type k1
string
127.0.0.1:6379>

127.0.0.1:6379>
127.0.0.1:6379> INCR k1 2
(error) ERR wrong number of arguments for 'incr' command
127.0.0.1:6379> INCRBY k1 2
(integer) 103
127.0.0.1:6379> DECR k1
(integer) 102
127.0.0.1:6379> DECRBY k1 3
(integer) 99
127.0.0.1:6379> get k1
"99"
127.0.0.1:6379>

 

127.0.0.1:6379> set k2 'i love you'
OK
127.0.0.1:6379> get k2
"i love you"
127.0.0.1:6379> append k2 ', but have to leave'
(integer) 29
127.0.0.1:6379> get k2
"i love you, but have to leave"
127.0.0.1:6379> strlen k2
(integer) 29
127.0.0.1:6379>

 

SETRANGE key offset value

用 value 參數覆寫(overwrite)給定 key 所儲存的字符串值,從偏移量 offset 開始。

不存在的 key 看成空白字符串處理。

SETRANGE 命令會確保字符串足夠長以便將 value 設置在指定的偏移量上,若是給定 key 原來儲存的字符串長度比偏移量小(好比字符串只有 5 個字符長,但你設置的 offset 是 10 ),那麼原字符和偏移量之間的空白將用零字節(zerobytes, "\x00" )來填充。

注意你能使用的最大偏移量是 2^29-1(536870911) ,由於 Redis 字符串的大小被限制在 512 兆(megabytes)之內。若是你須要使用比這更大的空間,你可使用多個 key 。

當生成一個很長的字符串時,Redis 須要分配內存空間,該操做有時候可能會形成服務器阻塞(block)。在2010年的Macbook Pro上,設置偏移量爲 536870911(512MB 內存分配),耗費約 300 毫秒, 設置偏移量爲 134217728(128MB 內存分配),耗費約 80 毫秒,設置偏移量 33554432(32MB 內存分配),耗費約 30 毫秒,設置偏移量爲 8388608(8MB 內存分配),耗費約 8 毫秒。 注意若首次內存分配成功以後,再對同一個 key 調用 SETRANGE 操做,無須再從新內存。

127.0.0.1:6379> SETRANGE k2 7 'anyone but y'
(integer) 29
127.0.0.1:6379> get k2
"i love anyone but ye to leave"

是覆蓋不是插入哦。

 

List列表

回想一下Java中的List包含了兩個經常使用的List:

一個是ArrayList,實際上是一個Object數組。

一個是LinkedList,是一個雙向鏈表。在jdk1.6中,節點是一個Entry;在jdk1.7中節點是一個Node對象。

在Redis裏的List是一個ArrayList呢?仍是LinkedList呢?

Redis列表是簡單的字符串列表,按照插入順序排序。你能夠添加一個元素到列表的頭部(左邊)或者尾部(右邊)。

它的底層實際是個鏈表。

Redis列表(List)

    單值多value
         lpush/rpush/lrange
         lpop/rpop
         lindex,按照索引下標得到元素(從上到下)
         llen
         lrem key 刪N個value
         ltrim key 開始index 結束index,截取指定範圍的值後再賦值給key
         rpoplpush 源列表 目的列表
         lset key index value
         linsert key  before/after 值1 值2
        性能總結

127.0.0.1:6379> lpush list1 1 2 3 4 5
(integer) 5
127.0.0.1:6379> get list1
(error) WRONGTYPE Operation against a key holding the wrong kind of value
127.0.0.1:6379>
127.0.0.1:6379> lrange list1 0 -1
1) "5"
2) "4"
3) "3"
4) "2"
5) "1"
127.0.0.1:6379>
127.0.0.1:6379> rpush list2 5 4 3 2 1
(integer) 5
127.0.0.1:6379> lrange list2 0 -1
1) "5"
2) "4"
3) "3"
4) "2"
5) "1"
127.0.0.1:6379>
127.0.0.1:6379> lpop list1
"5"
127.0.0.1:6379> lrange list1 0 -1
1) "4"
2) "3"
3) "2"
4) "1"
127.0.0.1:6379> rpop list2
"1"
127.0.0.1:6379> lrange list2 0 -1
1) "5"
2) "4"
3) "3"
4) "2"
127.0.0.1:6379>
127.0.0.1:6379> LINDEX list1 0
"4"
127.0.0.1:6379> llen list1
(integer) 4
127.0.0.1:6379>

 

127.0.0.1:6379> rpush list3 1 1 1 2 2 2 3 3 3 4 4 4
(integer) 12
127.0.0.1:6379> LRANGE list3 0 -1
 1) "1"
 2) "1"
 3) "1"
 4) "2"
 5) "2"
 6) "2"
 7) "3"
 8) "3"
 9) "3"
10) "4"
11) "4"
12) "4"
127.0.0.1:6379> lrem list3 2 3
(integer) 2
127.0.0.1:6379> LRANGE list3 0 -1
 1) "1"
 2) "1"
 3) "1"
 4) "2"
 5) "2"
 6) "2"
 7) "3"
 8) "4"
 9) "4"
10) "4"
127.0.0.1:6379>
127.0.0.1:6379>
127.0.0.1:6379> ltrim list3 2 6
OK
127.0.0.1:6379> LRANGE list3 0 -1
1) "1"
2) "2"
3) "2"
4) "2"
5) "3"
127.0.0.1:6379>

 

127.0.0.1:6379> lpush list4 java python golang
(integer) 3
127.0.0.1:6379> lrange list4 0 -1
1) "golang"
2) "python"
3) "java"
127.0.0.1:6379> linsert list4 before python x
(integer) 4
127.0.0.1:6379> linsert list4 after python y
(integer) 5
127.0.0.1:6379> lrange list4 0 -1
1) "golang"
2) "x"
3) "python"
4) "y"
5) "java"
127.0.0.1:6379> lset list4 1 y
OK
127.0.0.1:6379> lrange list4 0 -1
1) "golang"
2) "y"
3) "python"
4) "y"
5) "java"
127.0.0.1:6379> linsert list4 before y www
(integer) 6
127.0.0.1:6379> lrange list4 0 -1
1) "golang"
2) "www"
3) "y"
4) "python"
5) "y"
6) "java"
127.0.0.1:6379>

這裏須要注意:linsert在插入時,若是對應的元素存在多個相同值的元素,那麼只會相對於第一個符合的元素的位置進行插入。

rpoplpush是針對將一個列表中尾部的元素迅速插入到另外一個列表的頭部的情景。

127.0.0.1:6379> rpush list5 aa bb cc
(integer) 3
127.0.0.1:6379> lrange list5 0 -1
1) "aa"
2) "bb"
3) "cc"
127.0.0.1:6379> rpoplpush list4 list5
"java"
127.0.0.1:6379> lrange list4 0 -1
1) "golang"
2) "www"
3) "y"
4) "python"
5) "y"
127.0.0.1:6379> lrange list5 0 -1
1) "java"
2) "aa"
3) "bb"
4) "cc"
127.0.0.1:6379>

 

性能總結:

它是一個字符串鏈表,left、right均可以插入添加

若是鍵不存在,穿件新的鏈表

若是鍵已經存在,建立新的鏈表

若是值所有移除,對應的鍵也就消失了

鏈表的操做不管是頭和尾,效率都極高,但假如是對中間元素進行操做,效率就會很低。

 

 

Set集合

在Java中,HashSet的底層實現實際上是一個HashMap。

Redis的Set是string類型的無須集合。它是經過HashTable實現的。

Redis集合(Set)
    經常使用
    單值多value
    案例
         sadd/smembers/sismember  添加元素、輸出set的全部成員、判斷一個元素是不是set的成員
         scard,獲取集合裏面的元素個數
         srem key value 刪除集合中元素
         srandmember key 某個整數(隨機出幾個數)
         spop key 隨機出棧
         smove key1 key2 在key1裏某個值      做用是將key1裏的某個值賦給key2
         數學集合類
            差集:sdiff
            交集:sinter
            並集:sunion

127.0.0.1:6379> sadd set01 1 1 2 2 3 3 3
(integer) 3
127.0.0.1:6379> SMEMBERS set01
1) "1"
2) "2"
3) "3"
127.0.0.1:6379>
127.0.0.1:6379> SISMEMBER set01 1
(integer) 1
127.0.0.1:6379> SISMEMBER set01 2
(integer) 1
127.0.0.1:6379> SISMEMBER set01 3
(integer) 1
127.0.0.1:6379> SISMEMBER set01 4
(integer) 0

 

127.0.0.1:6379> keys *
1) "set01"
127.0.0.1:6379>
127.0.0.1:6379> SCARD set01
(integer) 3
127.0.0.1:6379> SCARD set02
(integer) 0

刪除元素

127.0.0.1:6379> SREM set01 2
(integer) 1
127.0.0.1:6379> SMEMBERS set01
1) "1"
2) "3"
127.0.0.1:6379>

隨機取數

127.0.0.1:6379> sadd set02 1 2 3 4 5 6 7 8 9
(integer) 9
127.0.0.1:6379> SRANDMEMBER set02 3
1) "3"
2) "7"
3) "4"
127.0.0.1:6379>
127.0.0.1:6379> SRANDMEMBER set02 3
1) "3"
2) "8"
3) "2"
127.0.0.1:6379> SRANDMEMBER set02 3
1) "1"
2) "6"
3) "2"
127.0.0.1:6379>
127.0.0.1:6379> SRANDMEMBER set02
"4"
127.0.0.1:6379> SRANDMEMBER set02
"5"
127.0.0.1:6379> SRANDMEMBER set02
"5"
127.0.0.1:6379> SRANDMEMBER set02
"1"
127.0.0.1:6379>

隨機出棧

127.0.0.1:6379> spop set02
"2"
127.0.0.1:6379> spop set02
"5"
127.0.0.1:6379> SMEMBERS set02
1) "1"
2) "3"
3) "4"
4) "6"
5) "7"
6) "8"
7) "9"
127.0.0.1:6379> spop set02 2
1) "4"
2) "7"
127.0.0.1:6379> spop set02 3
1) "1"
2) "9"
3) "3"
127.0.0.1:6379> SMEMBERS set02
1) "6"
2) "8"
127.0.0.1:6379>

smove key1 key2 在key1裏某個值      做用是將key1裏的某個值賦給key2

127.0.0.1:6379> keys *
1) "set02"
2) "set01"
127.0.0.1:6379> SMEMBERS set01
1) "1"
2) "3"
127.0.0.1:6379> SMEMBERS set02
1) "6"
2) "8"
127.0.0.1:6379> SMOVE set01 set02 3
(integer) 1
127.0.0.1:6379> SMEMBERS set01
1) "1"
127.0.0.1:6379> SMEMBERS set02
1) "3"
2) "6"
3) "8"
127.0.0.1:6379> SMOVE set01 set02 7
(integer) 0
127.0.0.1:6379>

刪除鍵

127.0.0.1:6379> del set01
(integer) 1
127.0.0.1:6379> del set02
(integer) 1
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379>
127.0.0.1:6379> SADD set01 1 2 3 4 5
(integer) 5
127.0.0.1:6379> SADD set02 1 2 3 a b
(integer) 5

 差集:sdiff

127.0.0.1:6379> SDIFF set01 set02
1) "4"
2) "5"


交集:sinter

127.0.0.1:6379> SINTER set01 set02
1) "1"
2) "2"
3) "3"


 並集:sunion

127.0.0.1:6379> SUNION set01 set02
1) "4"
2) "1"
3) "2"
4) "b"
5) "a"
6) "5"
7) "3"

 

Hash哈希

redis hash是一個鍵值對的集合。

redis hash是一個string類型的field和value的映射表,hash特別適合用於存儲對象,相似Java裏的map<String,Object>

Redis哈希(Hash)
    KV模式不變,但V是一個鍵值對

  經常使用命令以下:紅色的必定牢記
         hset/hget/hmset/hmget/hgetall/hdel
         hlen
         hexists key 在key裏面的某個值的key
         hkeys/hvals
         hincrby/hincrbyfloat
         hsetnx

127.0.0.1:6379> hset personA name happybks
(integer) 1
127.0.0.1:6379> hget personA name
"happybks"

127.0.0.1:6379> hmset personA gender male age 18 score 100.0
OK
127.0.0.1:6379> hget personA age
"18"
127.0.0.1:6379> hmget personA name score
1) "happybks"
2) "100.0"

127.0.0.1:6379> hgetall personA
1) "name"
2) "happybks"
3) "gender"
4) "male"
5) "age"
6) "18"
7) "score"
8) "100.0"
127.0.0.1:6379>

127.0.0.1:6379> HDEL personA gender
(integer) 1
127.0.0.1:6379> HGET personA gender
(nil)
127.0.0.1:6379>

 

127.0.0.1:6379> HLEN personA
(integer) 3
127.0.0.1:6379> HKEYS personA
1) "name"
2) "age"
3) "score"
127.0.0.1:6379> HVALS personA
1) "happybks"
2) "18"
3) "100.0"
127.0.0.1:6379>

這裏自增注意的是:即便原先的值是整型或者浮點數,兩種自增方式均可以使用;自增若補償爲負值即爲自減。

127.0.0.1:6379> HINCRBY personA age 1
(integer) 19
127.0.0.1:6379> HINCRBY personA age 2
(integer) 21
127.0.0.1:6379> HINCRBYFLOAT personA score -1.5
"98.5"
127.0.0.1:6379> HINCRBYFLOAT personA score 1.5
"100"
127.0.0.1:6379> HINCRBYFLOAT personA age 1.5
"22.5"
127.0.0.1:6379> HINCRBYFLOAT personA age -1.5
"21"
127.0.0.1:6379> HINCRBY personA score 50
(integer) 150
127.0.0.1:6379>

hsetnx value中的鍵值對有此鍵則失敗,無則成功設置鍵-鍵的值。

127.0.0.1:6379> HSETNX personA age 24
(integer) 0
127.0.0.1:6379>
127.0.0.1:6379> HSETNX personA email happybks@123.com
(integer) 1
127.0.0.1:6379>
127.0.0.1:6379> HGETALL personA
1) "name"
2) "happybks"
3) "age"
4) "21"
5) "score"
6) "150"
7) "email"
8) "happybks@123.com"
127.0.0.1:6379>

 

Zset(sorted set)有序集合

Hash是無須的。Redis zset和set同樣也是string類型元素的集合,且不容許重複的元素。

不一樣的是每一個元素會關聯一個double類型的份數。

redis正式經過這個分數來爲集合中的成員進行從小到大的排序。

zset成員是惟一的,但分數能夠重複。

能夠聯想一下網絡遊戲中的多人在線的分數更新等等。

Redis有序集合Zset(sorted set)
    在set基礎上,加一個score值。
以前set是k1 v1 v2 v3,
如今zset是k1 score1 v1 score2 v2
    經常使用命令以下:
         zadd/zrange【withscores】
         zrangebyscore key 開始score 結束score
             withscores
             (   不包含
            limit 做用是返回限制
                 limit 開始下標步 多少步
         zrem key 某score下對應的value值,做用是刪除元素
         zcard/zcount key score區間

         /zrank key values值,做用是得到下標值

         /zscore key 對應值,得到分數
         zrevrank key values值,做用是逆序得到下標值
         zrevrange
         zrevrangebyscore  key 結束score 開始score

 

首先咱們須要注意的是zset在添加新元素以後,它默認是按照分數進行排序的。不管你是先添加仍是後添加。

127.0.0.1:6379> ZADD zset1 2000 L1
(integer) 1
127.0.0.1:6379> ZADD zset1 4000 L2 6000 L3
(integer) 2
127.0.0.1:6379> ZADD zset1 8000 L4 100000 L5 12000 L6 0 L0
(integer) 4
127.0.0.1:6379> ZRANGE zset1 0 -1
1) "L0"
2) "L1"
3) "L2"
4) "L3"
5) "L4"
6) "L6"
7) "L5"
127.0.0.1:6379> ZRANGE zset1 0 -1 withscores
 1) "L0"
 2) "0"
 3) "L1"
 4) "2000"
 5) "L2"
 6) "4000"
 7) "L3"
 8) "6000"
 9) "L4"
10) "8000"
11) "L6"
12) "12000"
13) "L5"
14) "100000"
127.0.0.1:6379>

127.0.0.1:6379> ZADD zset1 -1000 L7
(integer) 1
127.0.0.1:6379> ZRANGE zset1 0 -1 withscores
 1) "L7"
 2) "-1000"
 3) "L0"
 4) "0"
 5) "L1"
 6) "2000"
 7) "L2"
 8) "4000"
 9) "L3"
10) "6000"
11) "L4"
12) "8000"
13) "L6"
14) "12000"
15) "L5"
16) "100000"
127.0.0.1:6379>

 

127.0.0.1:6379> ZRANGEBYSCORE zset1 2000 12000
1) "L1"
2) "L2"
3) "L3"
4) "L4"
5) "L6"
127.0.0.1:6379> ZRANGEBYSCORE zset1 2000 (12000
1) "L1"
2) "L2"
3) "L3"
4) "L4"
127.0.0.1:6379> ZRANGEBYSCORE zset1 (2000 (12000
1) "L2"
2) "L3"
3) "L4"
127.0.0.1:6379> ZRANGEBYSCORE zset1 2000 12000 limit 2 3
1) "L3"
2) "L4"
3) "L6"
127.0.0.1:6379> ZRANGEBYSCORE zset1 2000 12000 limit 3 2
1) "L4"
2) "L6"
127.0.0.1:6379>

刪除zset中的某個value,注意刪除的是value(附帶刪除score),而不是刪除score(附帶刪除value)

127.0.0.1:6379> ZREM zset1 100000
(integer) 0
127.0.0.1:6379>
127.0.0.1:6379>
127.0.0.1:6379>
127.0.0.1:6379> ZREM zset1 L5
(integer) 1
127.0.0.1:6379>

注意,按照區間查詢符合分數區間的值個數,區間的分數能夠不存在與已有的值分數中,且一樣能夠支持不包含操做(。

127.0.0.1:6379> ZCARD zset1
(integer) 7

127.0.0.1:6379>
127.0.0.1:6379> ZCOUNT zset1 3000 9000
(integer) 3
127.0.0.1:6379>
127.0.0.1:6379> ZCOUNT zset1 3000 12000
(integer) 4
127.0.0.1:6379> ZCOUNT zset1 3000 (12000
(integer) 3
127.0.0.1:6379>

反饋下標,第幾個。分正序和倒序。從0開始。

127.0.0.1:6379> ZRANK zset1 L4
(integer) 5

127.0.0.1:6379> ZREVRANK zset1 L4
(integer) 1
127.0.0.1:6379>

一樣,查詢也能夠正序倒序,也能夠附帶分數。

127.0.0.1:6379> ZRANGE zset1 0 -1
1) "L7"
2) "L0"
3) "L1"
4) "L2"
5) "L3"
6) "L4"
7) "L6"
127.0.0.1:6379> ZREVRANGE zset1 0 -1
1) "L6"
2) "L4"
3) "L3"
4) "L2"
5) "L1"
6) "L0"
7) "L7"
127.0.0.1:6379> ZREVRANGE zset1 0 -1 withscores
 1) "L6"
 2) "12000"
 3) "L4"
 4) "8000"
 5) "L3"
 6) "6000"
 7) "L2"
 8) "4000"
 9) "L1"
10) "2000"
11) "L0"
12) "0"
13) "L7"
14) "-1000"
127.0.0.1:6379>

還能夠經過指定分數範圍來顯示值。可是請必定注意:與以前經過下標指定範圍查詢不一樣,按照分數的倒序查詢時,分數的左右區間也是從大到小 倒過來的!!!

127.0.0.1:6379> ZRANGEBYSCORE zset1 4000 9000
1) "L2"
2) "L3"
3) "L4"
127.0.0.1:6379> ZREVRANGEBYSCORE zset1 4000 (12000
(empty list or set)
127.0.0.1:6379> ZREVRANGEBYSCORE zset1 (12000 4000
1) "L4"
2) "L3"
3) "L2"
127.0.0.1:6379>

 

另外介紹一個方便查找的在線文檔:http://redisdoc.com/

關於每一個類型的具體redis命令將在下面的幾篇文章中接收

相關文章
相關標籤/搜索