【數據庫】Redis(2)--Redis的經常使用數據類型及命令

1.Redis主要數據類型分類

Redis中存儲數據經常使用的數據類型主要有五種:String、List、Set、Sorted Set、Hash,這五種數據結構在Redis中存儲數據的命令掌握對於咱們後期在使用Java框架封裝類操做Redis的API瞭解是很是重要的。因此在這裏對這五種數據結構進行一一彙總,另外也簡單介紹一下bitmaps、hyperloglogs、geospatial這三種類型。redis

 

1.1.String類型

String類型在Redis中經常使用的操做:算法

①get/set/exists/append/strlen命令:mongodb

127.0.0.1:6379> set key1 v1  # 設置值
OK 
127.0.0.1:6379> get key1    # 獲取值
"v1"
127.0.0.1:6379> keys *    # 獲取全部的值
1) "key1"
127.0.0.1:6379> EXISTS key1    # 判斷key1是否存在
(integer) 1
127.0.0.1:6379> APPEND key1 "hello"    # 向key1中追加"hello",若是Key1不存在,那就至關於set key1
(integer) 7
127.0.0.1:6379> get key1
"v1hello"
127.0.0.1:6379> STRLEN key1    #獲取字符串的長度
(integer) 7
127.0.0.1:6379> APPEND key1 ", fengye"
(integer) 15
127.0.0.1:6379> STRLEN key1
(integer) 15
127.0.0.1:6379> get key1
"v1hello, fengye"

②自增/減、步長(瀏覽量、點擊數):json

# +1/-1與+n/-n
127.0
.0.1:6379> set views 0 OK 127.0.0.1:6379> get views "0" 127.0.0.1:6379> incr views # 自增+1 (integer) 1 127.0.0.1:6379> incr views (integer) 2 127.0.0.1:6379> get views "2" 127.0.0.1:6379> decr views # 自減-1 (integer) 1 127.0.0.1:6379> decr views (integer) 0 127.0.0.1:6379> decr views (integer) -1 127.0.0.1:6379> get views "-1" 127.0.0.1:6379> INCRBY views 10 # 增長 n (integer) 9 127.0.0.1:6379> INCRBY views 10 (integer) 19 127.0.0.1:6379> DECRBY views 5 # 減小 n (integer) 14

③字符串截取:數據結構

127.0.0.1:6379> set key1 "hello, fengye"
OK
127.0.0.1:6379> get key1
"hello, fengye"
127.0.0.1:6379> GETRANGE key1 0 4    # 截取閉區間 [0, 4]的字符串
"hello"
127.0.0.1:6379> GETRANGE key1 0 -1   # 截取所有的字符串,和get key1同理
"hello, fengye"

④替換:app

127.0.0.1:6379> set key2 abcddefg
OK
127.0.0.1:6379> get key2
"abcddefg"
127.0.0.1:6379> SETRANGE key2 2 XXX   #  替換指定位置開始的字符串
(integer) 8
127.0.0.1:6379> get key2
"abXXXefg"

⑤setex(set with expire)與setnx(set if not exist):框架

#setex :設置過時時間
#setnx :不存在當前key纔會設置值,在分佈式鎖中經常使用
127.0
.0.1:6379> setex key3 30 "hello" # 設置過時時間爲30s,30s後過時 OK 127.0.0.1:6379> ttl key3 (integer) 21 127.0.0.1:6379> get key3 "hello" 127.0.0.1:6379> setnx mykey "redis" #設置mykey的值爲redis,當mykey不存在時設置成功 (integer) 1 127.0.0.1:6379> keys * 1) "key1" 2) "key2" 3) "mykey" 127.0.0.1:6379> ttl key3 (integer) -2 127.0.0.1:6379> setnx mykey "mongoDb" #當mykey已經存在了,設置mykey會失敗 (integer) 0 127.0.0.1:6379> get mykey "redis"

⑥同時設置多個值mset/mget/msetnx:分佈式

127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3    #同時設置多個值
OK
127.0.0.1:6379> keys *
1) "k3"
2) "k2"
3) "k1"
127.0.0.1:6379> mget k1 k2 k3    #同時獲取多個值
1) "v1"
2) "v2"
3) "v3"
127.0.0.1:6379> msetnx k1 y1 k4 v4   #同時獲取多個值,msetnx是一個原子性操做,要麼一塊兒成功,要麼一塊兒失敗
(integer) 0

127.0.0.1:6379> get k4
(nil)

⑦設置對象的值:spa

127.0.0.1:6379> set user:2 {name:lisi,age:3}   # 使用json字符串來保存user的值
OK
127.0.0.1:6379> get user:2
"{name:lisi,age:3}"
127.0.0.1:6379> mset user:1:name zhangsan user:1:age 2   # 使用user:1:name與user1:1:age來保存值,user:{id}:{field}做爲key來保存值
OK
127.0.0.1:6379> mget user:1:name user:1:age
1) "zhangsan"
2) "2"

⑧getset(先獲取後設置):code

127.0.0.1:6379> getset db redis  #若是不存在值,則返回nil,並設置初始值
(nil)
127.0.0.1:6379> get db
"redis"
127.0.0.1:6379> getset db mongodb  #若是存在值,則返回那個值,並設置新的值
"redis"
127.0.0.1:6379> get db
"mongodb"

 

1.2.List類型

①lpush/rpush/lrange(壓棧):

127.0.0.1:6379> LPUSH list one   # 將一個或多個值放到列表的頭部(左push)
(integer) 1
127.0.0.1:6379> LPUSH list two
(integer) 2
127.0.0.1:6379> LPUSH list three
(integer) 3
127.0.0.1:6379> LRANGE list 0 -1
1) "three"
2) "two"
3) "one"
127.0.0.1:6379> LRANGE list 0 1
1) "three"
2) "two"
127.0.0.1:6379> RPUSH list four    # 將一個或多個值放到列表的尾部(右push)
(integer) 4
127.0.0.1:6379> LRANGE list 0 -1
1) "three"
2) "two"
3) "one"
4) "four"

②lpop/rpop:

127.0.0.1:6379> LPOP list  # 左移除列表中的一個元素
"three"
127.0.0.1:6379> RPOP list  # 右移除列表中的一個元素
"four"
127.0.0.1:6379> LRANGE list 0 -1
1) "two"
2) "one"

③lindex(list index的簡寫):

127.0.0.1:6379> LINDEX list 1  # 經過下標得到list中的某一個值
"one"
127.0.0.1:6379> LINDEX list 0
"two"

④llen:

127.0.0.1:6379> LPUSH list one
(integer) 1
127.0.0.1:6379> LPUSH list two
(integer) 2
127.0.0.1:6379> LPUSH list three
(integer) 3
127.0.0.1:6379> Llen list  # 返回列表的長度
(integer) 3

⑤Lrem:

127.0.0.1:6379> LRANGE list 0 -1
1) "three"
2) "three"
3) "two"
4) "one"
127.0.0.1:6379> lrem list 1 one   # 移除list集合中指定個數的元素,精確匹配個數並移除
(integer) 1
127.0.0.1:6379> LRANGE list 0 -1
1) "three"
2) "three"
3) "two"
127.0.0.1:6379> lrem list 1 three
(integer) 1
127.0.0.1:6379> LRANGE list 0 -1
1) "three"
2) "two"
127.0.0.1:6379> LPUSH list three
(integer) 3
127.0.0.1:6379> lrem list 2 three
(integer) 2
127.0.0.1:6379> LRANGE list 0 -1
1) "two"

⑥Lrem:

127.0.0.1:6379> Rpush mylist "hello"
(integer) 1
127.0.0.1:6379> Rpush mylist "hello1"
(integer) 2
127.0.0.1:6379> Rpush mylist "hello2"
(integer) 3
127.0.0.1:6379> Rpush mylist "hello3"
(integer) 4
127.0.0.1:6379> Ltrim mylist 1 2   # 經過下標截取指定的長度,截取以後List會被改變,只剩下截取後的元素
OK
127.0.0.1:6379> LRANGE list 0 -1
(empty list or set)
127.0.0.1:6379> LRANGE mylist 0 -1
1) "hello1"
2) "hello2"

⑦rpoplpush:

127.0.0.1:6379> rpush mylist "hello"
(integer) 1
127.0.0.1:6379> rpush mylist "hello1"
(integer) 2
127.0.0.1:6379> rpush mylist "hello2"
(integer) 3
127.0.0.1:6379> rpoplpush mylist myotherlist  #右彈棧,移除列表中最後一個元素並放入新的列表元素中
"hello2"
127.0.0.1:6379> lrange mylist 0 -1
1) "hello"
2) "hello1"
127.0.0.1:6379> lrange myotherlist 0 -1
1) "hello2"

⑧lset:

lset:將列表中指定下標的一個元素替換成另一個元素,更新操做

127.0.0.1:6379> EXISTS list
(integer) 0
127.0.0.1:6379> lset list 0 item   #判斷列表是否存在,若是不存在的話,當前更新會報錯
(error) ERR no such key
127.0.0.1:6379> lpush list value1
(integer) 1
127.0.0.1:6379> LRANGE list 0 0
1) "value1"
127.0.0.1:6379> lset list 0 item   #若是列表已經存在元素,能夠更新當前列表中的元素
OK
127.0.0.1:6379> LRANGE list 0 0
1) "item"
127.0.0.1:6379> lset list 1 other   #若是更新範圍超出限制,也會拋出異常
(error) ERR index out of range

⑨Linsert:

Linsert將某一個具體的value插入到列表中的某個元素的前面或者後面

127.0.0.1:6379> Rpush mylist "hello"
(integer) 1
127.0.0.1:6379> Rpush mylist "world"
(integer) 2
127.0.0.1:6379> LINSERT mylist before "world" "other"
(integer) 3
127.0.0.1:6379> LRANGE mylist 0 -1
1) "hello"
2) "other"
3) "world"
127.0.0.1:6379> LINSERT mylist after "world" "new"
(integer) 4
127.0.0.1:6379> LRANGE mylist 0 -1
1) "hello"
2) "other"
3) "world"
4) "new"

 

1.3.Set類型

redis中Set集合中的元素是不能重複的。

①sadd/smembers/sismember/scard

127.0.0.1:6379> sadd myset "hello"
(integer) 1
127.0.0.1:6379> sadd myset "fengye"
(integer) 1
127.0.0.1:6379> sadd myset "love fengye"
(integer) 1
127.0.0.1:6379> SMEMBERS myset  #查看myset中全部的值
1) "fengye"
2) "love fengye"
3) "hello"127.0.0.1:6379> SISMEMBER myset hello  #判斷某一個值是否是在set集合中
(integer) 1
127.0.0.1:6379> SISMEMBER myset world
(integer) 0

  127.0.0.1:6379> scard myset  #獲取set集合中內容元素的個數
  (integer) 4

②srem

127.0.0.1:6379> SMEMBERS myset
1) "fengye"
2) "lovekuangshen2"
3) "love fengye"
4) "hello"
127.0.0.1:6379> srem myset lovekuangshen2   #移除某一個元素
(integer) 1
127.0.0.1:6379> SMEMBERS myset
1) "fengye"
2) "love fengye"
3) "hello"

③srandmember

127.0.0.1:6379> SRANDMEMBER myset
"hello"
127.0.0.1:6379> SRANDMEMBER myset
"love fengye"
127.0.0.1:6379> SRANDMEMBER myset
"fengye"
127.0.0.1:6379> SRANDMEMBER myset 2  #隨機抽選出指定個數的元素
1) "hello"
2) "love fengye"

④spop

127.0.0.1:6379> spop myset  #隨機刪除集合中的一些元素
"fengye"
127.0.0.1:6379> spop myset
"love fengye"
127.0.0.1:6379> SMEMBERS myset
1) "hello"

⑤smove

127.0.0.1:6379> sadd myset "hello"
(integer) 1
127.0.0.1:6379> sadd myset "world"
(integer) 1
127.0.0.1:6379> sadd myset "fengye"
(integer) 1
127.0.0.1:6379> sadd myset2 "set2"
(integer) 1
127.0.0.1:6379> smove myset myset2 "fengye"  #將指定的元素從一個set移動到另外一個set集合中
(integer) 1
127.0.0.1:6379> SMEMBERS myset
1) "world"
2) "hello"
127.0.0.1:6379> SMEMBERS myset2
1) "fengye"
2) "set2"

⑥sdiff/sinter/sunion

127.0.0.1:6379> sadd key1 a
(integer) 1
127.0.0.1:6379> sadd key1 b
(integer) 1
127.0.0.1:6379> sadd key1 c
(integer) 1
127.0.0.1:6379> sadd key2 c
(integer) 1
127.0.0.1:6379> sadd key2 d
(integer) 1
127.0.0.1:6379> sadd key2 e
(integer) 1
127.0.0.1:6379> SDIFF key1 key2   # 差集
1) "a"
2) "b"
127.0.0.1:6379> SINTER key1 key2  # 交集
1) "c"
127.0.0.1:6379> SUNION key1 key2  # 並集
1) "a"
2) "b"
3) "c"
4) "d"
5) "e"

 

1.4.Hash

①hset/hget/hmget/hgetall:

127.0.0.1:6379> hset myhash field1 fengye  # hset一個具體的key-value
(integer) 1
127.0.0.1:6379> hget myhash field1
"fengye"
127.0.0.1:6379> hmset myhash field1 hello field2 world    #set多個key value
OK
127.0.0.1:6379> hmget myhash field1 field2    #獲取多個字段值
1) "hello"
2) "world"
127.0.0.1:6379> hgetall myhash  #獲取所有的數據
1) "field1"
2) "hello"
3) "field2"
4) "world"

#使用hash存取對象數據

127.0.0.1:6379> hmset myhash username zhangsan sex '男' age 24
OK
127.0.0.1:6379> HGETALL myhash
1) "field2"
2) "world"
3) "field1"
4) "hello"
5) "field3"
6) "5"
7) "filed3"
8) "1"
9) "field4"
10) "hello"
11) "username"
12) "zhangsan"
13) "sex"
14) "\xe7\x94\xb7"
15) "age"
16) "24"

②hdel:

127.0.0.1:6379> hdel myhash field1  #刪除hash中指定的key字段,對應的value值也就沒有了
(integer) 1
127.0.0.1:6379> hgetall myhash
1) "field2"
2) "world"

③hlen:

127.0.0.1:6379> HGETALL myhash
1) "field2"
2) "world"
3) "field1"
4) "hello"
127.0.0.1:6379> hlen myhash  # 獲取hash表的字段數量
(integer) 2

④hexists:

127.0.0.1:6379> HEXISTS myhash field1  #判斷hash中的key是否存在
(integer) 1
127.0.0.1:6379> HEXISTS myhash field3
(integer) 0

⑤Hkeys/Hvals:

127.0.0.1:6379> HKEYS myhash   # 查詢全部的keys
1) "field2"
2) "field1"
127.0.0.1:6379> HVALS myhash   # 查詢全部的vals
1) "world"
2) "hello"

⑥hincrby/hsetnx:

127.0.0.1:6379> hset myhash field3 5
(integer) 1
127.0.0.1:6379> HINCRBY myhash field3 1  #hash指定增量
(integer) 6
127.0.0.1:6379> HINCRBY myhash field3 -1  #hash自減
(integer) 5
127.0.0.1:6379> hsetnx myhash field4 hello   #不存在則設置值
(integer) 1
127.0.0.1:6379> hsetnx myhash field4 world  #存在則沒法設置,分佈式鎖
(integer) 0

 

1.5.Sorted Set有序集合類

①zadd/zrange:

127.0.0.1:6379> zadd myset 1 one  #添加一個值
(integer) 1
127.0.0.1:6379> zadd myset 2 two 3 three   #添加多個值
(integer) 2
127.0.0.1:6379> ZRANGE myset 0 -1
1) "one"
2) "two"
3) "three"

②zrangebyscore:

127.0.0.1:6379> clear
127.0.0.1:6379> zadd salary 2500 xiaohong
(integer) 1
127.0.0.1:6379> zadd salary 4000 zhangsan
(integer) 1
127.0.0.1:6379> zadd salary 1000 fengye
(integer) 1
127.0.0.1:6379> ZRANGEBYSCORE salary -inf +inf  #按照薪資高低升序排序
1) "fengye"
2) "xiaohong"
3) "zhangsan"
127.0.0.1:6379> ZRANGEBYSCORE salary -inf +inf withscores  #按照薪資高低升序排序,附帶薪資

1) "fengye"
2) "1000"
3) "xiaohong"
4) "2500"
5) "zhangsan"
6) "4000"
127.0.0.1:6379> ZRANGEBYSCORE salary -inf 2500 withscores 

1) "fengye"
2) "1000"
3) "xiaohong"
4) "2500"

③zrem:

127.0.0.1:6379> ZREM salary zhangsan  #移除sorted set中指定的元素
(integer) 1
127.0.0.1:6379> ZRANGE salary 0 -1
1) "fengye"

④zcard:

127.0.0.1:6379> ZCARD salary  #獲取有序集合中元素的個數
(integer) 2

⑤zrevrage:

127.0.0.1:6379> ZREVRANGE salary 0 -1 withscores  #從大到小排列
1) "xiaohong" 
2) "2500"
3) "fengye"
4) "1000"

⑥zcount:

127.0.0.1:6379> zadd myset 1 hello
(integer) 1
127.0.0.1:6379> zadd myset 2 world 3 fengye
(integer) 2
127.0.0.1:6379> zcount myset 1 3  #獲取指定區間的成員數量
(integer) 3
127.0.0.1:6379> zcount myset 1 2
(integer) 2

 

2.Redis幾種特殊類型分類

2.1.Geospatial地理位置

Redis經過Geospatial能夠根據地理位置如經度、緯度查詢出兩地之間的距離。主要分爲如下幾個命令:

①geoadd:

# 添加規則:除兩極不能添加外,其它均能添加
# 參數 key 經度 緯度 名稱
# 有效的經度從-180度到180度
# 有效的緯度從-85.05112878度到85.05112878度
127.0.0.1:6379> geoadd china:city 116.40 39.90 beijing
(integer) 1
127.0.0.1:6379> geoadd china:city 121.47 31.23 shanghai  # 添加地理位置
(integer) 1
127.0.0.1:6379> geoadd china:city 106.50 29.53 chongqi 114.05 22.52 shengzhen
(integer) 2
127.0.0.1:6379> geoadd china:city 120.16 30.24 hangzhou 108.96 34.26 xian
(integer) 2

②geopos:

127.0.0.1:6379> geopos china:city beijing   # 獲取指定的成員的經度和緯度
1) 1) "116.39999896287918091"
   2) "39.90000009167092543"
127.0.0.1:6379> geopos china:city beijing xian
1) 1) "116.39999896287918091"
   2) "39.90000009167092543"
2) 1) "108.96000176668167114"
   2) "34.25999964418929977"

③geodist:

計算兩個城市地區之間的直線距離:

  • m表示單位米
  • km表示單位公里
  • mi表示單位英里
  • ft表示單位英尺
127.0.0.1:6379> geodist china:city beijing shanghai
"1067378.7564"
127.0.0.1:6379> geodist china:city beijing shanghai km  # 查找北京到上海的直線距離,單位km
"1067.3788"
127.0.0.1:6379> geodist china:city beijing hangzhou km
"1127.3378"

④georadius:

以給定的經緯度爲中心,找出某一半徑內的元素:

127.0.0.1:6379> GEORADIUS china:city 110.35 30.39 1000 km   #獲取當前經度緯度下1000km之內的城市
1) "chongqi"
2) "xian"
3) "shengzhen"
4) "hangzhou"
127.0.0.1:6379> GEORADIUS china:city 110.35 30.39 500 km
1) "chongqi"
2) "xian"
127.0.0.1:6379> GEORADIUS china:city 110.35 30.39 500 km withdist  #獲取該經度緯度下500km之內的城市並附帶距離
1) 1) "chongqi"
   2) "383.1094"
2) 1) "xian"
   2) "449.8190"
127.0.0.1:6379> GEORADIUS china:city 110.35 30.39 500 km withcoord  #獲取該經度緯度下500km之內的城市病顯示城市的經度、緯度
1) 1) "chongqi"
   2) 1) "106.49999767541885376"
      2) "29.52999957900659211"
2) 1) "xian"
   2) 1) "108.96000176668167114"
      2) "34.25999964418929977"
127.0.0.1:6379> GEORADIUS china:city 110.35 30.39 500 km withdist withcoord count 2  #count 2表示只顯示2個
1) 1) "chongqi"
   2) "383.1094"
   3) 1) "106.49999767541885376"
      2) "29.52999957900659211"
2) 1) "xian"
   2) "449.8190"
   3) 1) "108.96000176668167114"
      2) "34.25999964418929977"

⑤georadiusbymember:

127.0.0.1:6379> GEORADIUSBYMEMBER china:city shanghai 400 km  #以城市爲中心查詢出距離400km的城市
1) "hangzhou"
2) "shanghai"

⑥geohash:

該命令將返回11個字符的geohash字符串

127.0.0.1:6379> geohash china:city beijing chongqi
1) "wx4fbxxfke0"
2) "wm5xzrybty0"

⑦zset命令刪除:

geo底層就是zset,因此咱們可使用zset進行刪除:

127.0.0.1:6379> ZRANGE china:city 0 -1
1) "chongqi"
2) "xian"
3) "shengzhen"
4) "hangzhou"
5) "shanghai"
6) "beijing"
127.0.0.1:6379> ZREM china:city beijing
(integer) 1

 

2.2.hyperloglogs

Redis基於hyperloglogs提供了一種更高效的算法來計算兩個集合中的元素個數,重複個數不累計。

這種高效率的算法替代了傳統使用set集合進行不重複元素的存取計算方式。

hyperloglogs的優勢:

  • 佔用內存小,存取2^64的不一樣元素的基數,只須要12kb的內存存儲空間
127.0.0.1:6379> PFADD mykey a b c d e f g h i j
(integer) 1
127.0.0.1:6379> PFCOUNT mykey
(integer) 10
127.0.0.1:6379> PFADD mykey2 i j z x c a b n m
(integer) 1
127.0.0.1:6379> PFCOUNT mykey2
(integer) 9
127.0.0.1:6379> PFMERGE mykey3 mykey mykey2  #合併兩個集合的元素
OK
127.0.0.1:6379> PFCOUNT mykey3  #計算元素的個數,不重複
(integer) 14

注意:使用hyperloglogs有0.81%的錯誤率,若是不容許容錯,須要精確計算的,則不能使用hyoerloglogs。

 

2.3.Bitmaps類型

Bitmaps使用位0 1進行數據的存儲。

適用場景:統計用戶信息,活躍與非活躍、登陸、打卡

使用Bitmaps來記錄一週7天的打卡時間:

127.0.0.1:6379> setbit sign 0 1
(integer) 0
127.0.0.1:6379> setbit sign 1 0
(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 1
(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> getbit sign 6
(integer) 0

  127.0.0.1:6379> BITCOUNT sign  #統計打卡的天數  (integer) 3

相關文章
相關標籤/搜索