你真的瞭解Redis數據類型的那些高級用法嗎?

文章目錄

一、前置知識

1、設置(set)和獲取(get)

127.0.0.1:6379> set name chuzhuyong
OK
127.0.0.1:6379> get name
"chuzhuyong"

2、判斷key是否存在(exists)和移動當前key(move)

127.0.0.1:6379> exists name
(integer) 1
127.0.0.1:6379> exists age
(integer) 0

exists命令的返回值:如果key存在,則返回1;若不存在,則返回0。

127.0.0.1:6379> move name 1
(integer) 1
127.0.0.1:6379> select 1
OK
127.0.0.1:6379[1]> get name
"chuzhuyong"

move命令的作用:將當前數據庫的 key 移動到給定的數據庫 db 當中。
move命令的返回值:移動成功返回 1;失敗則返回 0

注意:如果當前數據庫(源數據庫)和給定數據庫(目標數據庫)有相同名字的給定 key ,或者 key 不存在於當前數據庫,那麼 move沒有任何效果。
因此,也可以利用這一特性,將 move當作鎖(locking)原語(primitive)。

3、設置key的過期時間(expire)和查看剩餘時間(ttl)

127.0.0.1:6379> expire name 10
(integer) 1
127.0.0.1:6379> ttl name
(integer) 6
127.0.0.1:6379> ttl name
(integer) 4
127.0.0.1:6379> ttl name
(integer) 1
127.0.0.1:6379> ttl name
(integer) -2
127.0.0.1:6379> get name
(nil)

expire用來設置key的過期時間,超過時間後,將會自動刪除該key。
ttl用來返回key剩餘的過期時間。

4、查看key的所屬類型(type)

127.0.0.1:6379> set name chuzhuyong
OK
127.0.0.1:6379> type name
string

返回key所存儲的value的數據結構類型,它可以返回string, list, set, zset 和 hash等不同的類型。

5、獲取所有的key(keys *)

127.0.0.1:6379> keys *
1) "name"

6、清空當前數據庫(flushdb)和清空所有數據庫(flushall)

127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> flushall
OK

7、切換數據庫(select)

我們知道,Redis有16個數據庫(0~15),默認使用第0個數據庫。如果我們需要切換到其他數據庫, 可以使用select命令。

127.0.0.1:6379> select 1
OK

二、五大基本數據類型

1、字符串類型string

上面講到的例如get、set等命令不再贅述。

(1)追加一個值到key上(append )

127.0.0.1:6379> append name ",Hello!"
(integer) 17
127.0.0.1:6379> get name
"chuzhuyong,Hello!"

如果 key 已經存在,並且值爲字符串,那麼這個命令會把 value 追加到原來值(value)的結尾。 如果 key 不存在,那麼它將首先創建一個空字符串的key,再執行追加操作,這種情況 append 將類似於 set操作。

(2)獲取指定key的長度(strlen)

127.0.0.1:6379> strlen name
(integer) 17

返回key的string類型value的長度。如果key對應的非string類型,就返回錯誤。

(3)對指定的key值加1(incr)和對指定的key值減1(decr)

127.0.0.1:6379> set views 0
OK
127.0.0.1:6379> incr views
(integer) 1
127.0.0.1:6379> incr views
(integer) 2
127.0.0.1:6379> decr views
(integer) 1
127.0.0.1:6379> decr views
(integer) 0

(4)對指定的key設置增加步長(incrby)和減小步長(decrby)

127.0.0.1:6379> incrby views 10
(integer) 10
127.0.0.1:6379> decrby views 5
(integer) 5

(5)截取字符串(getrange)和替換指定位置開始的字符串(setrange)

127.0.0.1:6379> get name
"chuzhuyong,Hello!"
127.0.0.1:6379> getrange name 0 2
"chu"
127.0.0.1:6379> getrange name 0 -1
"chuzhuyong,Hello!"

字符串的下標從0開始,如果結束下標爲-1,則返回整個字符串。

127.0.0.1:6379> setrange name 0 lin
(integer) 17
127.0.0.1:6379> get name
"linzhuyong,Hello!"

setrange 的作用是覆蓋key對應的string的一部分,從指定的offset處開始,覆蓋value的長度。如果offset比當前key對應string還要長,那這個string後面就補0以達到offset。不存在的keys被認爲是空字符串,所以這個命令可以確保key有一個足夠大的字符串,能在offset處設置value。

(6)設置key-value並設置過期時間(setex)和不存在設置key-value(setnx)

127.0.0.1:6379> setex province 10 "anhui"
OK
127.0.0.1:6379> ttl province
(integer) -2
127.0.0.1:6379> get province
(nil)

setex province 10 "anhui"相當於如下命令:

127.0.0.1:6379>set province "anhui"
127.0.0.1:6379>expire province 10
127.0.0.1:6379> setnx age 23
(integer) 1
127.0.0.1:6379> get age
"23"

將key設置值爲value,如果key不存在,這種情況下等同set命令。 當key存在時,什麼也不做。SETNX是”SET if Not eXists”的簡寫。【(在分佈式鎖中會經常使用!)】

(7)同時設置(mset)和獲取(mget)多個值、不存在同時設置(msetnx)

127.0.0.1:6379> mset name chuzhuyogn sex man age 23
OK
127.0.0.1:6379> mget name sex age
1) "chuzhuyogn"
2) "man"
3) "23"
127.0.0.1:6379> msetnx name chuzhuyong address "Luan"
(integer) 0
127.0.0.1:6379> get address
(nil)
127.0.0.1:6379> get name
"chuzhuyogn"

(8)設置對象(set、mset)

127.0.0.1:6379> set user:1 {name:chuzhuyong,age:23}
OK
127.0.0.1:6379> get user:1
"{name:chuzhuyong,age:23}"
127.0.0.1:6379> mset user:1:name chuzhuyong user:1:age 23
OK
127.0.0.1:6379> mget user:1:name user:1:age
1) "chuzhuyong"
2) "23"

(9)先get後set(getset)

127.0.0.1:6379> getset city luan
(nil)
127.0.0.1:6379> get city
"luan"
127.0.0.1:6379> getset city hefei
"luan"
127.0.0.1:6379> get city
"hefei"

如果不存在值,則返回 nil;如果存在值,獲取原來的值,並設置新的值。

String類型的使用場景:value除了是字符串還可以是數字!

  • 計數器
  • 統計多單位的數量
  • 粉絲數
  • 對象緩存存儲

2、列表類型list

(1)從隊列的左邊(lpush)或右邊(rpush)入隊一個或多個元素

127.0.0.1:6379> lpush city luan
(integer) 1
127.0.0.1:6379> lpush city hefei
(integer) 2
127.0.0.1:6379> lpush city wuhu
(integer) 3
127.0.0.1:6379> lrange city 0 -1
1) "wuhu"
2) "hefei"
3) "luan"
127.0.0.1:6379> rpush city suzhou
(integer) 4
127.0.0.1:6379> lrange city 0 -1
1) "wuhu"
2) "hefei"
3) "luan"
4) "suzhou"

我們也可以使用lpush或rpush命令入隊多個元素

127.0.0.1:6379> lpush city luan heifei wuhan
(integer) 3
127.0.0.1:6379> lrange city 0 -1
1) "wuhan"
2) "heifei"
3) "luan"

(2)從隊列的右邊(rpop)或左邊(lpop)出一個元素

127.0.0.1:6379> lpush city luan heifei wuhan
(integer) 3
127.0.0.1:6379> lrange city 0 -1
1) "wuhan"
2) "heifei"
3) "luan"
127.0.0.1:6379> lpop city
"wuhan"
127.0.0.1:6379> lrange city 0 -1
1) "heifei"
2) "luan"
127.0.0.1:6379> rpop city
"luan"
127.0.0.1:6379> lrange city 0 -1
1) "heifei"

(3)通過索引列表獲取一個元素(lindex)、獲取隊列的長度(llen)

127.0.0.1:6379> lpush mylist world
(integer) 1
127.0.0.1:6379> lpush mylist hello
(integer) 2
127.0.0.1:6379> lrange mylist 0 -1
1) "hello"
2) "world"
127.0.0.1:6379> lindex mylist 0
"hello"
127.0.0.1:6379> llen mylist
(integer) 2

(4)從列表中刪除元素(lrem)、修剪到指定範圍內的清單(ltrim)

127.0.0.1:6379> lpush mylist student a am I
(integer) 4
127.0.0.1:6379> lrange mylist 0 -1
1) "I"
2) "am"
3) "a"
4) "student"
127.0.0.1:6379> lrem mylist 1 am
(integer) 1
127.0.0.1:6379> lrange mylist 0 -1
1) "I"
2) "a"
3) "student"
127.0.0.1:6379> ltrim mylist 0 1
OK
127.0.0.1:6379> lrange mylist 0 -1
1) "I"
2) "a"

(5)刪除列表中的最後一個元素,將其追加到另一個列表(rpoplpush )

127.0.0.1:6379> lpush mylist one two three
(integer) 3
127.0.0.1:6379> rpoplpush mylist myotherlist
"one"
127.0.0.1:6379> lrange myotherlist 0 -1
1) "one"

(6)設置隊列裏面一個元素的值(lset)

127.0.0.1:6379> lpush mylist one two three
(integer) 3
127.0.0.1:6379> lset mylist 0 four
OK
127.0.0.1:6379> lrange mylist 0 -1
1) "four"
2) "two"
3) "one"

(7)在列表中的另一個元素之前或之後插入一個元素(linsert)

127.0.0.1:6379> rpush mylist Hello World
(integer) 2
127.0.0.1:6379> linsert mylist before Hello Nice
(integer) 3
127.0.0.1:6379> lrange mylist 0 -1
1) "Nice"
2) "Hello"
3) "World"
127.0.0.1:6379> linsert mylist after World !
(integer) 4
127.0.0.1:6379> lrange mylist 0 -1
1) "Nice"
2) "Hello"
3) "World"
4) "!"

應用場景:消息排隊等

3、集合類型set

集合裏面的元素是無序的且不能重複。

(1)向集合中添加一個或多個元素(sadd)並查看所有元素(smembers)

127.0.0.1:6379> sadd myset Hello World
(integer) 2
127.0.0.1:6379> smembers myset
1) "Hello"
2) "World"

(2)判斷某一個元素是否在集合中(sismember)、獲取元素的個數(scard)

127.0.0.1:6379> sismember myset Hello
(integer) 1
127.0.0.1:6379> sismember myset hello
(integer) 0
127.0.0.1:6379> scard myset
(integer) 2

(3)從集合中移除一個或多個元素(srem)

127.0.0.1:6379> sadd myset one two three
(integer) 3
127.0.0.1:6379> srem myset one
(integer) 1
127.0.0.1:6379> smembers myset
1) "three"
2) "two"

(4)從集合中隨機獲取一個元素的值(srandmember)

127.0.0.1:6379> sadd myset ont two three
(integer) 3
127.0.0.1:6379> srandmember myset 1
1) "ont"
127.0.0.1:6379> srandmember myset 2
1) "three"
2) "two"

### (5)移動集合裏面的元素到另一個集合(smove)
```bash
127.0.0.1:6379> smove myset myotherset three
(integer) 1
127.0.0.1:6379> smembers myotherset
1) "three"

(5)集合的並集(sunion)、交集(sinter)、差集(sdiff)

127.0.0.1:6379> sadd myset one two three
(integer) 3
127.0.0.1:6379> sadd otherset four five three
(integer) 3
127.0.0.1:6379> sunion myset otherset
1) "one"
2) "three"
3) "four"
4) "two"
5) "five"
127.0.0.1:6379> sinter myset otherset
1) "three"
127.0.0.1:6379> sdiff myset otherset
1) "one"
2) "two"

應用場景:
微博,A用戶將所有關注的人放在一個set集合中!將它的粉絲也放在一個集合中!

4、哈希類型hash

(1)設置(hset)、獲取(hget)hash裏面一個字段的值

127.0.0.1:6379> hset myhash field Hello
(integer) 1
127.0.0.1:6379> hget myhash field
"Hello"

(2)設置(hmset)、獲取(hmget)單個、獲取所有(hgetall)、刪除)(hdel)字段值

127.0.0.1:6379> hmset myset field1 Hello field2 World
OK
127.0.0.1:6379> hmget myset field1
1) "Hello"
127.0.0.1:6379> hgetall myset
1) "field1"
2) "Hello"
3) "field2"
4) "World"
127.0.0.1:6379> hdel myset field1
(integer) 1
127.0.0.1:6379> hgetall myset
1) "field2"
2) "World"

(3)獲取hash所有字段的數量(hlen)、判斷某個字段是否存在(hexists )

127.0.0.1:6379> hmset myset field1 Hello field2 World
OK
127.0.0.1:6379> hlen myset
(integer) 2
127.0.0.1:6379> hexists myset field1
(integer) 1
127.0.0.1:6379> hexists myset field3
(integer) 0

(4)獲取所有的field(hkeys )、value(hvals )

127.0.0.1:6379> hmset myset field1 Hello field2 World
OK
127.0.0.1:6379> hkeys myset
1) "field1"
2) "field2"
127.0.0.1:6379> hvals myset
1) "Hello"
2) "World"

應用場景:
hash經常適用於變更的數據 user name age,尤其是是用戶信息之類的。
hash 更適合於對象的存儲,String更加適合字符串存儲!

5、有序集合類型Zset

(1)添加元素(zadd)、顯示所有元素(zrange)

127.0.0.1:6379> zadd myzset 1 one
(integer) 1
127.0.0.1:6379> zadd myzset 2 two 3 three
(integer) 2
127.0.0.1:6379> zrange myzset 0 -1
1) "one"
2) "two"
3) "three"

(2)集合的排序從小到大(zrangebyscore )、從大到小(zrevrange )、附帶score(withscores)

127.0.0.1:6379> zadd salary 1000 zhangsan
(integer) 1
127.0.0.1:6379> zadd salary 1500 lisi
(integer) 1
127.0.0.1:6379> zadd salary 2000 wangwu
(integer) 1
127.0.0.1:6379> zrangebyscore salary -inf +inf
1) "zhangsan"
2) "lisi"
3) "wangwu"
127.0.0.1:6379> zrevrange salary 0 -1
1) "wangwu"
2) "lisi"
3) "zhangsan"
127.0.0.1:6379> zrevrange salary 0 -1 withscores
1) "wangwu"
2) "2000"
3) "lisi"
4) "1500"
5) "zhangsan"
6) "1000"

(3)移除有序集合中的指定元素(zrem )、 獲取有序集合中的個數(zcount )

127.0.0.1:6379> zrem salary zhangsan
(integer) 1
127.0.0.1:6379> zrange salary 0 -1
1) "lisi"
2) "wangwu"
127.0.0.1:6379> zcard salary
(integer) 2
127.0.0.1:6379> zadd myzset 1  one 2 two 3 three
(integer) 3
127.0.0.1:6379> zcount myzset 1 2
(integer) 2

應用場景:
set 排序 存儲班級成績表,工資表排序!
普通消息 1, 重要消息 2,帶權重進行判斷!
排行榜應用實現,取Top N 測試!

三、三大特殊數據類型

1、地理空間(geospatial)

(1)添加地理空間位置(geoadd)、查詢地理空間位置(geopos)

127.0.0.1:6379> geoadd china:city 116.405285 39.904989 beijing
(integer) 1
127.0.0.1:6379> geoadd china:city 121.472644 31.231706 shanghai
(integer) 1
127.0.0.1:6379> geoadd china:city 120.153576 30.287459 hangzhou
(integer) 1
127.0.0.1:6379> geoadd china:city 106.504962 29.533155 chongqing
(integer) 1
127.0.0.1:6379> geopos china:city beijing
1) 1) "116.40528291463851929"
   2) "39.9049884229125027"
127.0.0.1:6379> geopos china:city shanghai
1) 1) "121.47264629602432251"
   2) "31.23170490709807012"

格式:geoadd key 經度 緯度 名稱
有效的經度從-180度到180度。
有效的緯度從-85.05112878度到85.05112878度。

點擊城市經緯度網站進行查詢。

(2)查詢兩地之間的距離(geodist)、以給定的經緯度爲中心查詢某一半徑內的元素(georadius )

127.0.0.1:6379> geodist china:city beijing shanghai km
"1067.5980"
127.0.0.1:6379> georadius china:city 100 30 100 km
(empty array)
127.0.0.1:6379> georadius china:city 100 30 1000 km
1) "chongqing"

應用場景:比如:微信上的查找附近的人。

(3)查詢給定的城市名稱某一半徑下的城市(georadiusbymember )

127.0.0.1:6379> georadiusbymember china:city shanghai 1000 km
1) "hangzhou"
2) "shanghai"

(4)返回一個或多個位置元素的 Geohash值(geohash )

127.0.0.1:6379> geohash china:city shanghai beijing
1) "wtw3sjt9vg0"
2) "wx4g0b7xrt0"

geohash命令將二維的經緯度信息轉化爲一維的字符串。

注意:地理空間(geospatial)類型底層使用的是有序集合(Zset),所以Zset下面的命令我們也可以使用,如下:

127.0.0.1:6379> zrange china:city 0 -1
1) "chongqing"
2) "hangzhou"
3) "shanghai"
4) "beijing"
127.0.0.1:6379> zrange china:city 0 -1 withscores
1) "chongqing"
2) "4026042117887371"
3) "hangzhou"
4) "4054134271990931"
5) "shanghai"
6) "4054803464817068"
7) "beijing"
8) "4069885370671010"

2、 hyperloglogs

(1)創建元素(pfadd)、統計基數數量(pfcount)、並集(pfmerge )

127.0.0.1:6379> pfadd mykey a b c d e f
(integer) 1
127.0.0.1:6379> pfcount mykey
(integer) 6
127.0.0.1:6379> pfadd mykey2 e f g h i j
(integer) 1
127.0.0.1:6379> pfcount mykey2
(integer) 6
127.0.0.1:6379> pfmerge mykey mykey2
OK
127.0.0.1:6379> pfmerge mykey3 mykey mykey2
OK
127.0.0.1:6379> pfcount mykey3
(integer) 10

(2)應用場景

優點:佔用的內存是固定,2^64 不同的元素的計數,只需要 12KB內存!如果要從內存角度來比較的話 Hyperloglog 首選!

網頁的 UV (一個人訪問一個網站多次,但是還是算作一個人!)
傳統的方式, set 保存用戶的id,然後就可以統計 set 中的元素數量作爲標準判斷 !
這個方式如果保存大量的用戶id,就會比較麻煩!我們的目的是爲了計數,而不是保存用戶id;
0.81% 錯誤率! 統計UV任務,可以忽略不計的!

3、 bitmaps

Bitmap 位圖,是一種數據結構! 用來操作二進制位來進行記錄,只有0 和 1 兩個狀態!

使用bitmaps 來記錄 週一到週日的打卡情況

0表示未打卡,1表示已打卡

添加週一到週日的打卡記錄(setbit)、查詢某一天的打卡情況(getbit )、統計打卡的天數(bitcount )

127.0.0.1:6379> setbit sign 0 1
(integer) 0
127.0.0.1:6379> setbit sign 1 1
(integer) 0
127.0.0.1:6379> setbit sign 2 0
(integer) 0
127.0.0.1:6379> setbit sign 3 1
(integer) 0
127.0.0.1:6379> setbit sign 4 0
(integer) 0
127.0.0.1:6379> setbit sign 5 0
(integer) 0
127.0.0.1:6379> setbit sign 6 0
(integer) 0
127.0.0.1:6379> getbit sign 3
(integer) 1
127.0.0.1:6379> bitcount sign
(integer) 3
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章