⑴ redis里list類型的數據怎麼使用
1. LPUSH/LPUSHX/LRANGE:
/> redis-cli #在Shell提示符下啟動redis客戶端工具。
redis 127.0.0.1:6379> del mykey
(integer) 1
#mykey鍵並不存在,該命令會創建該鍵及與其關聯的List,之後在將參數中的values從左到右依次插入。
redis 127.0.0.1:6379> lpush mykey a b c d
(integer) 4
#取從位置0開始到位置2結束的3個元素。
redis 127.0.0.1:6379> lrange mykey 0 2
1) "d"
2) "c"
3) "b"
#取鏈表中的全部元素,其中0表示第一個元素,-1表示最後一個元素。
redis 127.0.0.1:6379> lrange mykey 0 -1
1) "d"
2) "c"
3) "b"
4) "a"
#mykey2鍵此時並不存在,因此該命令將不會進行任何操作,其返回值為0。
redis 127.0.0.1:6379> lpushx mykey2 e
(integer) 0
#可以看到mykey2沒有關聯任何List Value。
redis 127.0.0.1:6379> lrange mykey2 0 -1
(empty list or set)
#mykey鍵此時已經存在,所以該命令插入成功,並返回鏈表中當前元素的數量。
redis 127.0.0.1:6379> lpushx mykey e
(integer) 5
#獲取該鍵的List Value的頭部元素。
redis 127.0.0.1:6379> lrange mykey 0 0
1) "e"
2. LPOP/LLEN:
redis 127.0.0.1:6379> lpush mykey a b c
⑵ Redis --- 八種數據類型(基本命令)
String、Hash、List、Set和Zset。
等同於java中的, Map<String,String> string 是redis裡面的最基本的數據類型,一個key對應一個value。
應用場景 :String是最常用的一種數據類型,普通的key/value存儲都可以歸為此類,如用戶信息,登錄信息和配置信息等;
實現方式 :String在redis內部存儲默認就是一個字元串,被redisObject所引用,當遇到incr、decr等操作(自增自減等原子操作)時會轉成數值型進行計算,此時redisObject的encoding欄位為int。
Redis雖然是用C語言寫的,但卻沒有直接用C語言的字元串,而是自己實現了一套字元串。目的就是為了提升速度,提升性能。 Redis構建了一個叫做簡單動態字元串(Simple Dynamic String),簡稱SDS。
Redis的字元串也會遵守C語言的字元串的實現規則,即 最後一個字元為空字元。然而這個空字元不會被計算在len里頭。
Redis動態擴展步驟:
Redis字元串的性能優勢
常用命令 :set/get/decr/incr/mget等,具體如下;
ps:計數器(字元串的內容為整數的時候可以使用),如 set number 1。
補充:
等同於java中的: Map<String,Map<String,String>> ,redis的hash是一個string類型的field和value的映射表, 特別適合存儲對象。 在redis中,hash因為是一個集合,所以有兩層。第一層是key:hash集合value,第二層是hashkey:string value。所以判斷是否採用hash的時候可以參照有兩層key的設計來做參考。並且注意的是, 設置過期時間只能在第一層的key上面設置。
應用場景 :我們要存儲一個用戶信息對象數據,其中包括用戶ID、用戶姓名、年齡和生日,通過用戶ID我們希望獲取該用戶的姓名或者年齡或者生日;
實現方式 :Redis的Hash實際是內部存儲的Value為一個HashMap,並提供了直接存取這個Map成員的介面。如,Key是用戶ID, value是一個Map。 這個Map的key是成員的屬性名,value是屬性值 。這樣對數據的修改和存取都可以直接通過其內部Map的Key(Redis里稱內部Map的key為field), 也就是通過 key(用戶ID) + field(屬性標簽) 就可以操作對應屬性數據。 當前HashMap的實現有兩種方式 :當HashMap的成員比較少時Redis為了節省內存會採用類似一維數組的方式來緊湊存儲,而不會採用真正的HashMap結構,這時對應的value的redisObject的encoding為zipmap,當成員數量增大時會自動轉成真正的HashMap,此時redisObject的encoding欄位為int。
常用命令 :hget/hset/hgetall等,具體如下:
等同於java中的 Map<String,List<String>> ,list 底層是一個鏈表,在redis中,插入list中的值,只需要找到list的key即可,而不需要像hash一樣插入兩層的key。 list是一種有序的、可重復的集合。
應用場景 :Redis list的應用場景非常多,也是Redis最重要的數據結構之一,比如twitter的關注列表,粉絲列表等都可以用Redis的list結構來實現;
實現方式 :Redis list的實現為一個 雙向鏈表 ,即可以支持反向查找和遍歷,更方便操作,不過帶來了部分額外的內存開銷,Redis內部的很多實現,包括 發送緩沖隊列 等也都是用的這個數據結構。
常用命令 :lpush/rpush/lpop/rpop/lrange等,具體如下:
性能總結 :
它是一個字元串鏈表,left、right都可以插入添加。
等同於java中的 Map<String,Set<String>> ,Set 是一種無序的,不能重復的集合。並且在redis中,只有一個key它的底層由hashTable實現的,天生去重。
應用場景 :Redis set對外提供的功能與list類似是一個列表的功能,特殊之處在於set是可以自動去重的,當你需要存儲一個列表數據,又不希望出現重復數據時,set是一個很好的選擇,並且 set提供了判斷某個成員是否在一個set集合內的重要介面 ,這個也是list所不能提供的;如保存一些標簽的名字。標簽的名字不可以重復,順序是可以無序的。
實現方式 :set 的內部實現是一個 value永遠為null的HashMap,實際就是通過計算hash的方式來快速排重的,這也是set能提供判斷一個成員是否在集合內的原因。
常用命令 :sadd/spop/smembers/sunion等,具體如下:
ZSet(Sorted Set:有序集合) 每個元素都會關聯一個double類型的分數score,分數允許重復,集合元素按照score排序( 當score相同的時候,會按照被插入的鍵的字典順序進行排序 ),還可以通過 score 的范圍來獲取元素的列表。
應用場景 :Redis sorted set的使用場景與set類似,區別是set不是自動有序的,而sorted set可以 通過用戶額外提供一個優先順序(score)的參數來為成員排序,並且是插入有序的,即自動排序。 當你需要一個有序的並且不重復的集合列表,那麼可以選擇sorted set數據結構,比如twitter 的public timeline可以以發表時間作為score來存儲,這樣獲取時就是自動按時間排好序的。
底層實現 : zset 是 Redis 提供的一個非常特別的數據結構,常用作排行榜等功能,以用戶 id 為 value ,關注時間或者分數作為 score 進行排序。實現機制分別是 zipList 和 skipList 。規則如下:
zipList:滿足以下兩個條件
skipList:不滿足以上兩個條件時使用跳錶、組合了hash和skipList
為什麼用skiplist不用平衡樹?
主要從內存佔用、對范圍查找的支持和實現難易程度這三方面總結的原因。
拓展:mysql為什麼不用跳錶?
常用命令 :zadd/zrange/zrem/zcard等;
官網地址: https://redis.io/commands/geoadd
可以用來推算兩地之間的距離,方圓半徑內的人。
關於經度緯度的限制: https://www.redis.net.cn/order/3685.html
一般我們使用Hyperloglog做基數統計。
什麼是基數?就是一個集合中不重復的數的個數。
集合A:{1,3,5,7,9,7}
集合B:{1,3,5,7,9}
AB集合的基數都是5
應用:統計網站的訪問量(一個人訪問網站很多次仍然算作一次)。
優點:佔用的內存是固定的,找2^64次方個數的基數,只需要12KB內存。
缺點:有0.81%的錯誤率,可以忽略不計
概述: bitmap 存儲的是連續的二進制數字(0 和 1),通過 bitmap, 只需要一個 bit 位來表示某個元素對應的值或者狀態,key 就是對應元素本身 。 我們知道 8 個 bit 可以組成一個 byte,所以 bitmap 本身會極大的節省儲存空間。
應用場景: 適合需要保存狀態信息(比如是否簽到、是否登錄...)並需要進一步對這些信息進行分析的場景。比如用戶簽到情況、活躍用戶情況、用戶行為統計(比如是否點贊過某個視頻)。
針對上面提到的一些場景,這里進行進一步說明。
使用場景一:用戶行為分析 很多網站為了分析你的喜好,需要研究你點贊過的內容。
使用場景二:統計活躍用戶
使用時間作為 key,然後用戶 ID 為 offset,如果當日活躍過就設置為 1
那麼我該如果計算某幾天/月/年的活躍用戶呢(暫且約定,統計時間內只有有一天在線就稱為活躍),有請下一個 redis 的命令
使用場景三:用戶在線狀態
對於獲取或者統計用戶在線狀態,使用 bitmap 是一個節約空間效率又高的一種方法。
只需要一個 key,然後用戶 ID 為 offset,如果在線就設置為 1,不在線就設置為 0。
補充 :
巨人的肩膀:
https://www.cnblogs.com/Small-sunshine/p/11687809.html
https://mp.weixin.qq.com/s/CMu7oXVIKp2s-PXTdMlimA
⑶ redis getset 命令怎麼使用方法
[Redis] redis-cli 命令總結
Redis提供豐富命令(command)資料庫各種數據類型進行操作些commandLinux終端使用
編程比使用Redis Java語言包些命令都應面Redis提供命令做總結
官網命令列表: (英文)
1、連接操作相關命令
quit:關閉連接(connection)
auth:簡單密碼認證
2、value操作命令
exists(key):確認key否存
del(key):刪除key
type(key):返值類型
keys(pattern):返滿足給定pattern所key
randomkey:隨機返key空間key
rename(oldname, newname):key由oldname重命名newname若newname存則刪除newname表示key
dbsize:返前資料庫key數目
expire:設定key間(s)
ttl:獲key間
select(index):按索引查詢
move(key, dbindex):前資料庫key轉移dbindex索引資料庫
flushdb:刪除前選擇資料庫所key
flushall:刪除所資料庫所key
3、String操作命令
set(key, value):給資料庫名稱keystring賦予值value
get(key):返資料庫名稱keystringvalue
getset(key, value):給名稱keystring賦予value
mget(key1, key2,…, key N):返庫string(名稱key1key2…)value
setnx(key, value):存名稱keystring則向庫添加string名稱key值value
setex(key, time, value):向庫添加string(名稱key值value)同設定期間time
mset(key1, value1, key2, value2,…key N, value N):同給string賦值名稱key istring賦值value i
msetnx(key1, value1, key2, value2,…key N, value N):所名稱key istring都存則向庫添加string
名稱key i賦值value i
incr(key):名稱keystring增1操作
incrby(key, integer):名稱keystring增加integer
decr(key):名稱keystring減1操作
decrby(key, integer):名稱keystring減少integer
append(key, value):名稱keystring值附加value
substr(key, start, end):返名稱keystringvalue串
4、List操作命令
rpush(key, value):名稱keylist尾添加值value元素
lpush(key, value):名稱keylist添加值value 元素
llen(key):返名稱keylist度
lrange(key, start, end):返名稱keyliststart至end間元素(標0始同)
ltrim(key, start, end):截取名稱keylist保留start至end間元素
lindex(key, index):返名稱keylistindex位置元素
lset(key, index, value):給名稱keylistindex位置元素賦值value
lrem(key, count, value):刪除count名稱keylist值value元素
count0刪除所值value元素count>0至尾刪除count值value元素count<0尾刪除|count|值value元素
lpop(key):返並刪除名稱keylist首元素 rpop(key):返並刪除名稱keylist尾元素
blpop(key1, key2,… key N, timeout):lpop命令block版本
即timeout0若遇名稱key ilist存或該list空則命令結束
timeout>0則遇述情況等待timeout秒問題沒解決則keyi+1始list執行pop操作
brpop(key1, key2,… key N, timeout):rpopblock版本參考命令
rpoplpush(srckey, dstkey):返並刪除名稱srckeylist尾元素並該元素添加名稱dstkeylist部
5、Set操作命令
sadd(key, member):向名稱keyset添加元素member
srem(key, member) :刪除名稱keyset元素member
spop(key) :隨機返並刪除名稱keyset元素
smove(srckey, dstkey, member) :member元素名稱srckey集合移名稱dstkey集合
scard(key) :返名稱keyset基數
sismember(key, member) :測試member否名稱keyset元素
sinter(key1, key2,…key N) :求交集
sinterstore(dstkey, key1, key2,…key N) :求交集並交集保存dstkey集合
sunion(key1, key2,…key N) :求並集
sunionstore(dstkey, key1, key2,…key N) :求並集並並集保存dstkey集合
sdiff(key1, key2,…key N) :求差集
sdiffstore(dstkey, key1, key2,…key N) :求差集並差集保存dstkey集合
smembers(key) :返名稱keyset所元素
srandmember(key) :隨機返名稱keyset元素
6、zset(sorted set)操作命令
zadd(key, score, member):向名稱keyzset添加元素memberscore用於排序該元素已經存則根據score更新該元素順序
zrem(key, member) :刪除名稱keyzset元素member
zincrby(key, increment, member) :名稱keyzset已經存元素member則該元素score增加increment;
否則向集合添加該元素其score值increment
zrank(key, member) :返名稱keyzset(元素已按score排序)member元素rank(即index0始)
若沒member元素返nil
zrevrank(key, member) :返名稱keyzset(元素已按score排序)member元素rank(即index0始)
若沒member元素返nil
zrange(key, start, end):返名稱keyzset(元素已按score排序)indexstartend所元素
zrevrange(key, start, end):返名稱keyzset(元素已按score排序)indexstartend所元素
zrangebyscore(key, min, max):返名稱keyzsetscore >= min且score <= max所元素
zcard(key):返名稱keyzset基數 zscore(key, element):返名稱keyzset元素element
score zremrangebyrank(key, min, max):刪除名稱keyzsetrank >= min且rank <= max所元素
zremrangebyscore(key, min, max) :刪除名稱keyzsetscore >= min且score <= max所元素
zunionstore / zinterstore(dstkeyN, key1,…,keyN, WEIGHTS w1,…wN, AGGREGATE SUM|MIN|MAX):Nzset求並集交集
並集合保存dstkeyN於集合每元素score進行AGGREGATE運算前都要乘於WEIGHT參數
沒提供WEIGHT默認1默認AGGREGATESUM即結集合元素score所集合應元素進行SUM運算值MINMAX指
結集合元素score所集合應元素值值
7、Hash操作命令
hset(key, field, value):向名稱keyhash添加元素fieldvalue
hget(key, field):返名稱keyhashfield應value
hmget(key, field1, …,field N):返名稱keyhashfield i應value
hmset(key, field1, value1,…,field N, value N):向名稱keyhash添加元素field ivalue i
hincrby(key, field, integer):名稱keyhashfieldvalue增加integer
hexists(key, field):名稱keyhash否存鍵field域
hdel(key, field):刪除名稱keyhash鍵field域
hlen(key):返名稱keyhash元素數
hkeys(key):返名稱keyhash所鍵
hvals(key):返名稱keyhash所鍵應value
hgetall(key):返名稱keyhash所鍵(field)及其應value
8、持久化
save:數據同步保存磁碟
bgsave:數據非同步保存磁碟
lastsave:返功數據保存磁碟Unix戳
shundown:數據同步保存磁碟關閉服務
9、遠程服務控制
info:提供伺服器信息統計
monitor:實轉儲收請求
slaveof:改變復制策略設置
config:運行配置Redis伺服器
⑷ redis怎麼清空list數據
可以使用 DEL直接 刪除這個 list 或者就用
RPOP key 移除並返回列表 key 的尾元素。
⑸ Redis數據結構之list對象
新版本的redis的list對象都是使用quicklit編碼。為了更好的理解quicklit編碼,我們先介紹quicklit編碼的前身,ziplist和linklist。
==ziplist和linklist都已經被quicklit所取代,這里只是為了更好的理解quicklit才列出ziplist和linklist兩種編碼==
顧名思義,壓縮鏈表,為了節約內存空間而設計。
·若列表zlbytes屬性的值為0x50(十進制80),表示壓縮列表的總長為80位元組。
·若列表zltail屬性的值為0x3c(十進制60),這表示如果我們有一個指向壓縮列表起始地址的指針p,那麼只要用指針p加上偏移量60,就可以計算出表尾節點entry3的地址。
·若列表zllen屬性的值為0x3(十進制3),表示壓縮列表包含三個節點。
節點的previous_entry_length屬性以位元組為單位,記錄了壓縮列表中前一個節點的長度,也就是說當我們獲取到一個指向當前節點的指針p時,么只要用指針p減去偏移量previous_entry_length就可以獲得上一個節點,通過zltail屬性又可快速獲取最後一個節點。壓縮鏈表通過這種方式實現從表尾向表頭遍歷鏈表。
壓縮鏈表開辟了一塊連續的空間實現了鏈表結構,極大的提高的內存的利用率,缺點是需要經常要重新分配內存。
優點是插入新增不需要重新分配內寸,缺點內存使用效率較低。
了解了ziplist和linkedlist之後就很容易理解quicklist的結構了
這樣就極大的降低了內存的碎片化程度,又降低了內存重新分配的規模。
實際使用的時候,quicklist在不斷的新增元素時,第一個quicklistNode和最後一個quicklistNode指向的ziplist始終保持不壓縮的狀態,而中間的ziplist會被再次壓縮(執行LZF演算法)。不被壓縮的ziplist數量是由redis.conf中的list-compress-depth決定的,默認是一,也就是第一個和最後一個不被壓縮,當ziplist滿了需要新建一個quicklistNode時它的空間限制是8kb,由list-max-ziplist-size決定。
我們可以用rpush,lpush,rpop,lpop等命令操作quicklist。
⑹ Redis數據結構--List(列表)
Redis列表是簡單的字元串列表,按照插入順序排序,你可以添加一個元素到列表的頭部(左邊)或者尾部(右邊)
一個列表最多可以包含超過 40億個元素
列表的常用命令(持續擴充):
1、lpush key value1 [value2]: 將一個或多個值插入列表頭部(左邊)
通過執行lpush animal cat dog 向animal中左邊同時插入 cat和dog,下方提示的(Integer)2,是指當前列表中元素的個數;
然後通過查詢命令,我們可以看到排在第一個的是dog 第二個是cat,這是因為從左邊插入,縣插入cat,然後再在左側插入dog,這就導致dog在cat的前面。
2、rpush key value1 [value2]: 將一個或多個值插入列表尾部(右邊)
執行rpush animal monkey:向列表的右側插入一個元素monkey,此時列表中的元素就有3個
通過查詢命令我們可以看到monkey出現在了列表的尾部
3、lrange key start stop: 獲取列表指定范圍內的元素(包含start和stop)
執行lrange animal 1 2 查詢列表的第2個和第3個元素(注意列表中的索引是從0開始計算的)
4、llen key: 獲取列表長度
在前面幾個步驟中我們一共插入了三個元素dog、cat、monkey
5、lpop key: 移出並獲取列表的第一個元素
列表中第一個元素是dog,執行lpop animal後,彈出左邊第一個元素並返回,再次查詢,我們看到只剩下兩個元素
6、rpop key: 移出並獲取列表的最後一個元素
執行rpop animal,移除並返回monkey,最後列表中只剩下cat一個元素
⑺ Redis中如何操作List數組
Ubuntu終端命令行
首先打開Ubuntu命令行,在命令行中我們可以用lpush命令按從左往右的順序插入一個list數組,如下圖所示
接下來我們還可以用rpush命令按照從右往左的順序插入數組,rpush和lpush用法一樣,只不過順序不同,如下圖所示
然後我們可以通過linsert after命令在某個數組後面插入新的list數組,如下圖所示
接下來我們來看一下怎麼取出list數組裡面的值,如下圖所示,通過lpop命令就可以直接取出list裡面的數組內容,這是從左側開始取
另外也可以通過rpop命令從右側開始取list數組的值,如下圖所示
如果想取出list裡面的所有數組內容,可以通過lrange命令提取,如下圖所示,最後一個一個數字-1代表全部取出
最後我們還可以通過索引取list數組中的某一項的值,如下圖所示,通過lindex命令即可實現
⑻ redis中list和hash的基本命令和使用場景
Redis的數據類型
Redis的數據類型共有五種:string,list,hash,set,zset;
String 字元串相對來說做平常,key-value,類似是hashmap的用法;
List 隊列,可以雙向的存值,設計時,也可以簡單用來當隊列模式;
Hash 字典,一個key 對應多個值;
Set 無序的集合;
Zset 有序的集合;
列表 list
Redis列表是簡單的字元串列表,按照插入順序排序。你可以添加一個元素導列表的頭部(左邊)或者尾部(右邊)
列表 list—— 基本命令
lpush
語法:lpush key value [value„]
作用:將一個或多個值 value 插入到列表 key 的表頭(最左邊),從左邊開始加入值,從左到右的順序依次插入到表頭
返回值:數字,新列表的長度
rpush
語法:rpush key value [value„]
作用:將一個或多個值 value 插入到列表 key 的表尾(最右邊),各個 value 值按從左到右 的順序依次插入到表尾
返回值:數字,新列表的長度
lrange
語法:lrange key start stop
作用:獲取列表 key 中指定區間內的元素,0 表示列表的第一個元素,以 1 表示列表的第二個元素;
start ,
stop 是列表的下標值,也可以負數的下標, -1 表示列表的最後一個元素, -2 表示列表的倒 數第二個元素,以此類推。
start ,stop 超出列表的范圍不會出現錯誤。
返回值:指定區間的列表
lindex
語法:lindex key index
作用:獲取列表 key 中下標為指定 index 的元素,列表元素不刪除,只是查詢。
0 表示列表的第一個元素,以 1 表示列表的第二個元素;
start ,
stop 是列表的下標值,也可以負數的下標, -1 表示列表的最後一個元素, -2 表示列表的倒數第二個元素,以此類推。
返回值:指定下標的元素;index 不在列表范圍,返回nil
llen
語法:llen key
作用:獲取列表 key 的長度 返回值:數值,列表的長度; key 不存在返回0
lrem
語法:lrem key count value
作用:根據參數count的值,移除列表中與參數value相等的元素,
count>0,從列表的左側向右開始移 除;
count<0從列表的尾部開始移除;
count=0 移除表中所有與value相等的值。
返回值:數值,移除的元素個數
lset
語法:lset key index value
作用:將列表 key 下標為 index 的元素的值設置為 value。
返回值:設置成功返回 ok ; key 不存在或者 index 超出范圍返回錯誤信息
linsert
語法:linsert key BEFORE(前)|AFTER(後) pivot value
作用:
將值value插入到列表key當中位於值pivot之前或之後的位置。
key不存在,pivot不在列表中, 不執行任何操作。
返回值:命令執行成功,返回新列表的長度。沒有找到 pivot 返回 -1, key 不存在返回 0。
RPOP key
移除列表的最後一個元素,返回值為移除的元素。
RPOPLPUSH source destination
移除列表的最後一個元素,並將該元素添加到另一個列表並返回
LPOP key
移除列表的第一個元素,返回值為移除的元素。
使用場景
1. 消息隊列
隊列模式的情況下,可以使用,左進右出的原則,但不建議使用,因為現在市面上有很多成熟的消息中間件,沒有必要造輪子;
2.排行榜
某一段時間統計數據的排行榜可以放在list裡面,需要分頁的話,也可以使用lrange start stop實現;
3. list類型的lpush命令和lrange命令能實現最新列表的功能,每次通過lpush命令往列表裡插入新的元素,然後通過lrange命令讀取最新的元素列表,如朋友圈的點贊列表、評論列表。
但是,並不是所有的最新列表都能用list類型實現,因為對於頻繁更新的列表,list類型的分頁可能導致列表元素重復或漏掉,舉個例子,當前列表裡由表頭到表尾依次有(E,D,C,B,A)五個元素,每頁獲取3個元素,用戶第一次獲取到(E,D,C)三個元素,然後表頭新增了一個元素F,列表變成了(F,E,D,C,B,A),此時用戶取第二頁拿到(C,B,A),元素C重復了。只有不需要分頁(比如每次都只取列表的前5個元素)或者更新頻率低(比如每天凌晨更新一次)的列表才適合用list類型實現
哈希類型hash
redis hash是一個 string 類型的 field 和 value 的映射表,hash特別適合用於存儲對象,每個 hash 可以存儲 232 - 1鍵值對(40多億);
哈希類型 hash—— 基本命令
hset /hget /hmset /hmget /hgetall /hkeys /hvals /hexists
hset
語法:hset hash 表的key field value
作用:將哈希表 key 中的域 field 的值設為value ,如果 key 不存在,則新建 hash 表,執行賦值,如果有 field ,則覆蓋值。
返回值: ①如果 field 是 hash 表中新field,且設置值成功,返回 1 ②如果 field 已經存在,舊值覆蓋新值,返回0
hget
語法:hget key field
作用:獲取哈希表 key 中給定域 field 的值
返回值:field 域的值,如果 key 不存在或者 field 不存在返回nil
hmset
語法:hmset key field value [field value„]
說明:同時將多個field-value(域-值)設置到哈希表key中,此命令會覆蓋已經存在的field, hash表key不存在,創建空的hash表,執行hmset.
返回值:設置成功返回ok, 如果失敗返回一個錯誤
hmget
語法:hmget key field [field„]
作用:獲取哈希表key中一個或多個給定域的值
返回值:返回和field順序對應的值,如果field不存在,返回nil
hgetall
語法:hgetall key
作用:獲取哈希表key中所有的域和值
返回值:以列表形式返回hash中域和域的值 ,key不存在,返回空hash
hdel
語法:hdel key field [field„]
作用:刪除哈希表 key 中的一個或多個指定域 field,不存在 field 直接忽略
返回值:成功刪除的 field 的數量
hkeys
語法:hkeys key
作用:查看哈希表 key 中的所有 field 域
返回值:包含所有 field 的列表,key 不存在返回空列表
hvals
語法:hvals key
作用:返回哈希表中所有域的值 返回值:包含哈希表所有域值的列表,key 不存在返回空列表
hexists
語法:hexists key field
作用:查看哈希表 key 中,給定域 field 是否存在
返回值:如果 field 存在,返回 1, 其他返回0
使用場景
1、購物車
以用戶id為key,商品id為field,商品數量為value,恰好構成了購物車的3個要素,如下圖所示。
2、hash還是比較適合存儲對象(key field value)或者是字典表(type,key,vlaue),剛好符合對象的要素,但string + json也可以存儲,兩則比較有什麼區別?
String + json Hash
效率很 高 高
容量 低 低
靈活性 低 高
序列化 簡單 復雜
⑼ Redis數據結構之string類型和list類型
String是redis最基礎和最常用的數據結構,其值最大能存儲 512MB,可以是簡單字元串、復雜的xml/json的字元串、二進制圖像或者音頻的字元串、以及可以是數字的字元串。String底層使用的是SDS,是Redis的一種基本數據結構,主要是用於存儲字元串和整數。
2.1 set命令 set key value
用於設置給定key的值,如果key存儲了其他值,覆蓋寫入,無視類型。
2.2 get命令 get key
獲取指定key的值,如果key不存在返回nil
2.3 getset命令 get key [value]
該命令用於獲取指定的key的舊值,然後按照新值對key進行賦值。當key中沒有舊值的時候返回nil。
2.4 mget命令 get key1 [key2 keyN]
返回多個key的值,某個key不存在時返回nil
2.5 decr命令 decr key
對key對應的數字做減1操作。如果key不存在,那麼在操作之前,這個key對應的值會被置為0。如果key有一個錯誤類型的value或者是一個不能表示成數字的字元串,就返回錯誤。
2.6 incr命令 incr key
對key對應的數字做減1操作。如果key不存在,那麼在操作之前,這個key對應的值會被置為0。如果key有一個錯誤類型的value或者是一個不能表示成數字的字元串,就返回錯誤。
2.7 append命令 append key value
如果 key 已經存在,並且值為字元串,那麼這個命令會把 value 追加到原來值(value)的結尾。 如果 key 不存在,那麼它將首先創建一個空字元串的key,再執行追加操作,這種情況 APPEND 將類似於 SET 操作。返回append後字元串值(value)的長度。
3.1 SDS動態字元串
struct sdshdr {
unsigned int len;
unsigned int free;
char buf[];
}
其中,buf表示數據空間,用於存儲字元串;len表示buf中已佔用的位元組數;free表示空閑的位元組數。
3.2 新的SDS結構
增加了一個flags來標識類型,用一個位元組(8位)來存儲,前3位表示字元串的類型;剩餘5位,存儲長度小於32的段字元串。
創建 SDS 的大致流程是這樣的:首先根據字元串長度計算得到 type,根據 type 計算頭部所需長度,然後動態分配內存空間。
注意:① 創建空字元串時,SDS_TYPE_5 被強制轉換為 SDS_TYPE_8(原因是創建空字元串後,內容可能會頻繁更新而引發擴容操作,故直接創建為 sdshdr8)
②長度計算有 +1 操作,因為結束符 \0 會佔用一個長度的空間。
③返回的是指向 buf 的指針 s。
4.1 session共享
4.2 計數器(商品瀏覽記錄)
4.3 訪問限速
list類型用來存儲多個有序的字元串,列表當中的每一個字元看做一個元素,一個列表當中可以存儲有一個或者多個元素,redis的list支持存儲2^32次方-1個元素。
Redis可以從兩端push和pop元素,支持讀取指定范圍或者制定下表的元素。list是一種靈活的鏈式結構,可以充當隊列或者棧的角色。
list的元素是有序的,且列表內的元素是可以重復的。
注意:Redis3.2以前,列表底層的編碼是ziplist(壓縮列表)和linkedlist(雙向列表)實現的,因為雙線列表佔用的內存比壓縮列表多,所以當創建新的列表鍵時,列表會優先考慮用壓縮列表,只有在需要的時候才會轉換到雙向列表實現。3.2以後重新引入了一個quicklist,列表底層都是有quicklist實現,quicklist是一個由ziplist組成的雙向列表,每個節點使用ziplist來存儲數據。
2.1 Lpush命令 lpush key value
將一個或多個值插入到列表頭部。 如果 key 不存在,則創建list,然後再插入數據操作。 當 key 存在但不是列表類型時,返回一個錯誤。
2.2 Rpush命令 rpush key value
將一個或多個值從list的尾部插入
2.3 Blpop命令 blpop key seconds
Blpop是取出列表的第一個元素,如果list中沒有元素則會一直等到到超時,或者發現有數據為止,seconds是指定多少秒返回。如沒有數據,則返回nil。
同理,Bropo為移除list列表的最後一個元素
2.4 Linsert命令 linsert key before/after val1 val2
在list列表的某一個元素前或者後插入另外一個元素。當指的的元素不存在時,不執行任何動作。如果列表不存在時,視為空列表,不執行任何動作。
2.5 Lindex命令 lindex key index
通過鏈表的下標獲取列表中的元素,可以是-1表示鏈表最後一個元素,-2代表倒數第二個元素,沒有返回nil
2.6 Llen命令 llen key
返回list的長度,如果list不存在,返回0
2.7 Lrange命令
返回指定list區間內的元素,區間以偏移量start和end決定。其中 0 表示列表的第一個元素, 1 表示列表的第二個元素,以此類推。 也可以使用負數下標,以 -1 表示列表的最後一個元素, -2 表示列表的倒數第二個元素,以此類推。
5.1 隊列秒殺搶購
list類型的lpop和rpush(或者反過來,lpush和rpop)能實現隊列的功能,故而可以用Redis的list類型實現簡單的點對點的消息隊列。不過不推薦在實戰中這么使用,因為現在已經有Kafka、NSQ、RabbitMQ等成熟的消息隊列了,它們的功能已經很完善了,除非是為了更深入地理解消息隊列,不然沒必要去重復造輪子。
5.2 排行榜
list類型的lrange命令可以分頁查看隊列中的數據。可將每隔一段時間計算一次的排行榜存儲在list類型中。只有定時計算的排行榜才適合使用list類型存儲,與定時計算的排行榜相對應的是實時計算的排行榜,list類型不能支持實時計算的排行榜。
⑽ python redis setex可以設value為list或者其他數據結構嗎
redis setex 命令存放php數組將返回Array, 如果場景確定適合用,就存放前序列化,取時再反序列化,如果是二維數組,建議用Hash數據
redis 數據結構多樣化,根據不同的業務場景滿足各種不同的需求
Hash 對應的場景(常用,歡迎大家補充討論)
產品各參數信息
用戶信息等
使用過活動專題上的點贊場景等
Hash 常見的命令
hgetall - 以列表形式返回哈希表的域和域的值,若key不存在,返回空列表
hget - hget key field 返回哈希表key中給定域field 的值
hmset - hmset key field value [field value ...] 同時設置多個值,成功返回ok
hsetnx - hsetnx key field value 如果域field 已經存在,該操作無效,返回0,成功返回1
hset - hset key field value 一個新的哈希表被創建並進行設置值,如果域field已經存在於哈希表中,舊值被覆蓋
hgetall 取得全部屬性 但是如果內部Map的成員很多,那麼涉及到遍歷整個內部Map的操作,由於Redis單線程模型的緣故,這個遍歷操作可能會比較耗時,而另其它客戶端的請求完全不響應,這點需要格外注意。
hlen - 返回哈希表key中域的數量
hvals - 返回哈希表key中的所有值
hdel - 刪除一個或多個的域,例: hdel key field0 field1 返回成功刪除的數量,成功刪除2個即返回2
# 其它看官網文檔
可以仔細了解redis 各數據結構(重要),具體根據自己的業務場景使用