Redis系列三:redis支持的數據類型

如下是摘自redis官網,描述了redis支持了哪些數據類型:java

 It supports data structures such as strings, hashes, lists, sets, sorted sets with range queries, bitmaps, hyperloglogs, geospatial indexes with radius queries and streams.redis

如下只介紹經常使用的前五個。數據庫

1、字符串(String)

一、字符串類型

實際上能夠是字符串(包括XML、JSON),數字(整型、浮點型),二進制(圖片、音頻、視頻)等,但最大不超過512MB。編程

二、設置命令

set name zhangsan ex 10 //10秒過時  px 10000 毫秒過時網絡

setnx name zhangsan //不存在鍵name時才設置,返回1設置成功;若已存在鍵name則返回0app

set age 29 //已存在鍵age則覆蓋以前的鍵值,返回1成功分佈式

場景:經過setnx只有一個可以設置成功,可作分佈式鎖;也可經過setnx佔位,防止連續調用的場景性能

獲值的命令:get age //存在則返回value,不存在鍵則返回nil測試

批量設置:mset name zhangsan age 15網站

批量獲取 mget name age //返回zhangsan 15

若沒有mget命令,則要執行n次get,從而佔用網絡資源影響性能

使用mget=1次網絡請求redis內部n次查詢,一次性返回全部查詢結果

三、計數

incr age //無age鍵則從0自增返回1;若age不死整數則返回錯誤,爲整數則自加1

decr age//整數age自減1,非整數返回錯誤,無age鍵從0自減返回-1

incrby age 2//整數自加2,非整數返回錯誤,無age鍵從0自加2返回2

decrby age 2//同上

incrbyfloat age 1.1 //整數age+1.1

四、append追加指令

set name zhang;append name san//追加後返回zhangsan

五、字符串長度

set name "你好"; strlen name //返回6,每一箇中文佔3個字節

六、截取字符串

set name zhangsna; getrange name 2 4//返回ang

七、內部編碼

int:8字節長整型

 set age 100; object encoding age //返回int

embstr:小於等於39字節串

 set name zhangsan; object encoding name //返回embstr

raw:大於39字節的字符串

  set name iafhsdfsdhfhusdfufdhhdghdbvjdvhdushfuisdhfudsihfusdhfuisgsvbnsdhfsduhfsduhfdsfhudhgfghdf

object encoding name //返回raw

八、切換數據庫

select 2//16個數據庫 0-15

九、應用場景

鍵值設計:業務名:對象名:id:[屬性]

數據庫爲order,用戶表爲user,對應的鍵可爲order:user:1 , order:user:name

注意:

redis目前處於受保護模式,不容許非本地客戶端連接,能夠經過給redis設置密碼,而後客戶端連接的時候,寫上密碼句能夠了

 127.0.0.1:6379>config set requirepas 123456 臨時生效

或修改redis.conf requirepass 123456

啓動時: ./redis-server redis.conf指定conf

   ./redis-cli -p 6379 -a 12345678 //須要加入密碼才能訪問

2、哈希(hash)

hash時一個string類型的field和value的映射表。hash適用於存儲對象。

一、命令

hset key field value

設值:hset user:1 name zhangsan //成功返回1,失敗返回0

取值:hget user:1 name//返回zhangsan

刪值:hdel user:1 nage //返回刪除的個數

計算鍵對應的字段個數:

hset user:1 name zhangsan; hset user:1 age 15;

hlen user:1 //返回2,user:1有兩個屬性

批量設值:hmset user:2 name zhangsan age 15 //返回OK

批量取值:hmget user:2 name age//返回兩行 zhangsan 15

判斷field是否存在 hexists user:2 zhangsan //存在返回1,不存在返回0

獲取全部field:hkeys user:2 //返回name age兩個field

獲取user:2全部value:hvals user:2 //返回zhangsan 15

獲取user:2全部field與value :hgetall user:2 //返回 name zhangsan  age 15

增長1:

hincrby user:2 age 1//15 + 1

hincrbyfloat user:2 age 2//浮點型加2

二、內部編碼

ziplist<壓縮列表>和hashtable<哈希表>

當field個數少且沒有大的value時,內部編碼爲ziplist

示例:

hmset user:3 name lisi age 20;object encoding user:3//返回ziplist

當value大於64字節,內部編碼由ziplist編程hashtable

示例:

hset user:4 name "王五王五王五王五王五王五王五王五王五王五王五王五王五王五王五王五王五王五王五王五王五王五王五王五王五王五王五王五王五王五王五王五王五王五王五王五王五王五王五王五王五王五王五王五";

object encoding user:4//返回hashtable

hash類型是稀疏,每一個鍵能夠有不一樣的field,若用redis模擬作關係複雜查詢開發困難,維護成本高。

三、三種方案實現用戶信息存儲

1)原生

set user:1 nage haha;

set user:1 age 60;

優勢:簡單直觀,每一個鍵對應一個值

缺點:鍵數過多,佔用內存多,用戶信息過於分散,不用於生產環境

2)將對象序列化存入redis

set user:1 serialize(user)

優勢:編程簡單,內存使用率高

缺點:序列化與反序列化有必定開銷,更新屬性須要把user所有取出來進行反序列化,更新後再序列化存入redis

3)使用hash類型

hmset user:1 name hahs age 60

優勢:簡單直觀,可減小內存空間消耗

缺點:要控制ziplist與hashtable兩種編碼轉換,且hashtable會消耗更多內存

總結:對於更新很少的狀況下,可使用序列化,對於value值不大於64字節可使用hash類型

3、列表(list)

一、用來存儲多個有序的字符串,一個列表最多可存2的32 次方減1個元素

由於有序,能夠經過因此下標獲取元素或某個範圍內元素列表,列表元素能夠重複

 

二、列表相關命令

添加命令:rpush lpush linsert

rpush name a b c d //從右向左插入a b c d,因此a是最早插入的

lrange name 0 -1//從左到右獲取列表全部元素a b c d

lpush fav a b c d //從左向右插入a b c d

lrange fav 0 -1//從左到右獲取列表全部元素 d c b a

linsert fav before b r //在b以前插入r,after爲以後,使用lrange fav 0 -1 返回d c r b a

查找命令:lrange index llen

lrange key start end //索引下標特色:從左到右爲0 到n-1, 如果從右到左則最右邊第一個下標爲-1,第二個爲-2.。。

lindex fav -1 //返回最右末尾a, -2 返回b

llen fav //返回當前列表長度5

刪除命令:lpop rpop lrem ltrim

lpop fav //把最左邊的第一個元素d刪除

rpop fav //把最右邊的元素a刪除

lrem key count value //刪除指定元素,count爲0表示刪除全部值爲value的,count小於0表示從右往左刪除count個值爲value的

示例:

lpush test b b b b b j x z//鍵test放入z x j b b b b b

lrange test 0 -1 //查詢結果爲z x j b b b b b

lrem test 4 b //從左邊開始刪除b的元素,刪除4個

//lrem test 8 b //刪除8個b,但只有5個則所有刪除

lrange test 0 -1 //刪除後的結果爲b j x z

lrem test 0 b //檢索全部b所有刪除j x z

 

lpush user b b b b b j x z //鍵user從左到右放入z x j b b b b b

ltrim user 1 3//只保留從第2到第4的元素x j b,其餘所有刪除

lrange user 0 -1 //查詢結果爲x j b,其餘已所有刪除

修改命令:lset

lpush user1 z y x//鍵user1從左到右翻入x y z

lset user1 2 java//把第3個元素z替換成java

lrange user1 0 -1//查詢結果爲x y java

阻塞命令:blpop brpop

三、列表內部編碼

1)當元素個數少且沒大元素,編碼爲ziplist,減小內存的使用

rpush list a b c

object encoding list//返回ziplist

2)當元素超過512個,或元素超過64字節,內部編碼變成linkedlist鏈表

rpush list a1 a2.............a513或rpush list nnnnnnnnnnnnn.....nnn

object encoding list //linkedlist

在3.2版本億歐,redis提供了quicklist內部編碼,它結合了ziplist和linkedlist二者的優點,以前的ziplist是存在bug的,使用qulicklist內部編碼效率更高,因此如今3.2之後看不到這兩個編碼了,只看到qulicklist。

4、無序集合set

保存多元素,與列表不同的是不容許有重複元素,且集合是無序的,一個集合最多可存2得32次方減1個元素,除了支持增刪改查,還支持集合交集、並集、差集;

一、元素集合set相關命令

元素操做:exists sadd smembers srem scard spop

exists user //檢查user鍵值是否存在

sadd user a b c//向user插入3個元素,返回3

sadd user a b //若再插入吸管弄太難過元素,則重複無效,返回0

srem user a//返回1,刪除a元素

scard user //返回2,計算元素個數

sismember user a//判斷元素是否在集合存在,存在返回1,不存在返回0

srandmember user a//隨機返回2個元素,2位元素個數

spop user 2//隨機返回2個元素a b,並將a b從集合中刪除

smembers user//此時已沒有a b,只有c

集合交集:sinter

add user:1 lili 22 girl

add user:2 zhangsan 22 boy

sinter user:1 user:2 //求兩個集合交集,此時返回22

sadd user:3 lucy 22 girl //新增第三個元素

sinter user:1 user:2 user:3 //求三個集合交集,此時返回22

 

集合的並集(去重):sunion

sunion user:1 user:2 user:3 //三個集合合併,去重,返回 lili zhangsan lucy girl boy

集合差集:sdiff

sdiff user:1 user:2 //lili girl

將集合的結果另存到隊列:sinterstore sunionstore sdiffstore

sinterstore user_jj user:1 user:2 //將交集結果保存到user_jj

sunionstore user_bj user:1 user:2 //將並集結果保存到user_bj

sdiffstore user_cj user:1 user:2 //將差集結果保存到user_cj

smembers user_cj //返回lili girl

二、內部編碼

sadd user 1 2 3 4 //當元素個數少(小於512個)且都爲整數,redis使用intset減小內存的使用

sadd user 1 2....513 //當元素個數超過512個或不爲整數(如a b)時,編碼爲hashtable

object encoding user //hashtables

三、無序集合set的應用場景

標籤、社交、查詢有共同興趣愛好的人,智能推薦

使用方式:

給用戶添加標籤:

sadd user:1:fav basketball football 

add user:2 pq

或者給標籤添加用戶:

sadd basketball:users user:1 user:2

sadd football:users user:1 user:2 user:3

...

計算出共同興趣愛好的人:

sinter user:1:fav user:2:fav

5、有序集合

經常使用於排行榜,如視頻網站須要對用戶上傳視頻作排行榜,或點贊數

與集合有聯繫,不能有重複的成員 

有序集合與集合set以及隊列list的區別: 

 

一、有序集合的相關命令

添加命令

zadd key score member [score member....]

zadd user:zan 200 zhangsan //zhangsan點贊數1,返回操做成功的條數1

zadd user:zan 200 zhangsan 120 lisi 100 wangwu //返回3

zadd test:1 nx 100 zhangsan //鍵test:1不存在,主要用於添加

zadd test:1 xx incr 200 zhangsan//鍵test:1必須存在,主要用於修改,此時爲300

zadd test:1 xx ch incr -299 zhangsan //返回操做結果1,300-299=1

查看命令

zrange test:1 0 -1 withiscores //查看點贊(分數)與成員名

zcard test:1 //計算成員個數,返回1

查看贊數

zadd test:2 nx 100 zahngsan //新增一個集合

zscore test:2 zhangsan//查看lisi的點贊數(分數),返回100

排名:

zadd user:3 200 zhangsan 120 lisi 100 wangwu //先插入數據

zrange user:3 0 -1 withscores //查看分數與成員

zrank user:3 zhangsan //返回名次:第三名返回2 從0開始到2,共3名

zrevrank user:3 zhangsan//返回0 反排序,點贊數越高,排名越靠前

刪除命令:

刪除成員:

zrem user:3 zhangsan lisi//返回成功刪除2個成員,還剩wangwu

增長分數:

zincrby user:3 10 wangwu //成員王五的分數加10

zadd user:3 xx incr 10 wangwu//和上述命令同樣

返回指定排名範圍的分數與成員

zadd user:4 200zhangsan 120 lisi 100 wangwu //先插入數據

zrange user:4 0 -1 withscores //返回結果wangwu 100 lisi 120 zhangsan 200 (該處空格實際上是換行的)

zrevrange user:4 0 -1 withscores //倒序,結果是zhangsan 200 lisi 120 wangwu 100

返回指定分數範圍的成員

zrangebyscore user:4 110 300 withscores //返回結果由低到高 lisi 120 zhangsan 200

zrevrangebyscore user:4 300 110 withscores //返回結果由高到低 zhangsan 200 lisi 120

zrangebyscore user:4 (110 +inf withscores//110到無限大,結果爲lisi 120 zhangsan 200

zrevrangebyscore user:4 (110 -inf withscores //無限小到110,結果爲wangwu 100

返回指定分數範圍的成員個數:

zcount user:4 110 300//返回2,由lisi和zhangsan兩條數據

刪除指定排名內的升序元素:

zremrangebyrank user:4 0 1 //分數升序排序,刪除第0個與第1個,只剩zhangsan

刪除指定分數範圍的成員:

zadd user:5 200 zhangsan 120 lisi 100 wangwu//先插入測試數據
zremrangebyscore user:5 210 300 //刪除分數在210與300範圍的成員
zremrangebyscore user:5 (100 +inf //刪除分數大於100(不包括100),還剩wangwu

有序集合交集:

   格式:zinterstore destination numkeys key ... [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]

         destination:交集產生新的元素存儲鍵名稱 

         numkeys:  要作交集計算的鍵個數

         key :元素鍵值

         weights:每一個被選中的鍵對應值乘weight, 默認爲1

  初始化數據:

       zadd user:7 1 james 2 mike 4 jack 5 kate      //初始化user:7數據

       zadd user:8 3 james 4 mike 4 lucy 2 lee  6 jim  //初始化user:8數據

  交集例子:

  zinterstore user_jj 2 user:7 user:8 aggregate sum //2表明鍵合併個數,

//aggregate sum可加也不可加上,由於默認是sum

//結果user_jj:4james(1+3), 6mike(2+4)

zinterstore user_jjmax 2 user:7 user:8 aggregate max 或min 

//取交集最大的分數,返回結果 3james  4mike, min取最小

 weights:

  zinterstore user_jjweight 2 user:7 user:8 weights 8 4 aggregate max

  //1,取兩個成員相同的交集,user:7->1 james  2 mike;  user:8->3 james  4 mike

  //2,將user:7->james 1*8=8,  user:7->mike 2*8 =16,最後user:7結果 8 james  16 mike;

 //3,將user:8-> james 3*4=12, user:8->mike 4*4=16,最後user:8結果12 james  16 mike

 //4,最終相乘後的結果,取最大值爲  12 james 16mike

//5, zrange user_jjweight 0 -1 withscores 查詢結果爲  12 james 16mike

總結:將user:7成員值乘8,將user:8成員值乘4,取交集,取最大

有序集合並集(合併去重):

   格式:zunionstore destination numkeys key ... [WEIGHTS weight] [AGGREGATE SUM|MIN|MAX]

         destination:交集產生新的元素存儲鍵名稱

         numkeys:  要作交集計算的鍵個數

         key :元素鍵值

         weights:每一個被選中的鍵對應值乘weight, 默認爲1

zunionstore user_jjweight2 2 user:7 user:8 weights 8 4 aggregate max

//與以上zinterstore同樣,只是取並集,指令同樣

2.有序集合內部編碼

1)ziplist

zadd user:9 20 james 30 mike 40 lee
object encoding user:9 //返回ziplist
//當元素個數少(小於128個),元素值小於64字節時,使用ziplist編碼,可有效減小內存的使用
2)skiplist 

zadd user:10 20 james......
//大於128個元素或元素值大於64字節時爲skiplist編碼

3.使用場景

   排行榜系統,如視頻網站須要對用戶上傳的視頻作排行榜

   點贊數:zadd user:1:20180106 3 mike  //mike得到3個贊

   再獲一讚:zincrby user:1:20180106 1 mike  //在3的基礎上加1

   用戶做弊,將用戶從排行榜刪掉:zrem user:1:20180106 mike

   展現贊數最多的5個用戶:zrevrangebyrank user:1:20180106  0  4 

   查看用戶贊數與排名:

    zscore user:1:20180106 mike   zrank user:1:20180106 mike

相關文章
相關標籤/搜索