鍍金池/ 教程/ 大數(shù)據(jù)/ 數(shù)據(jù)類(lèi)型初探
使用 Redis 實(shí)現(xiàn) Twitter(上)
集群(下)
使用 Redis 實(shí)現(xiàn) Twitter(下)
使用 Redis 作為 LRU 緩存
高可用(上)
高可用客戶(hù)端指引
集群(中)
高可用(下)
持久化
Redis 介紹
集中插入
集群(上)
從入門(mén)到精通(上)
從入門(mén)到精通(下)
從入門(mén)到精通(中)
分片
數(shù)據(jù)類(lèi)型初探
復(fù)制

數(shù)據(jù)類(lèi)型初探

字符串 (Strings)

字符串是 Redis 最基本的數(shù)據(jù)類(lèi)型。Redis 字符串是二進(jìn)制安全的,也就是說(shuō),一個(gè) Redis 字符串可以包含任意類(lèi)型的數(shù)據(jù),例如一張 JPEG 圖像,或者一個(gè)序列化的 Ruby 對(duì)象。

一個(gè)字符串最大為 512M 字節(jié)。

你可以使用 Redis 的字符串類(lèi)型做很多有意思的事情,例如,你可以:

  • 使用 INCR 命令族 (INCR,DECR,INCRBY),將字符串作為原子計(jì)數(shù)器。
  • 使用 APPEND 命令追加字符串。
  • 使用 GETRANGE 和 SETRANGE 命令,使字符串作為隨機(jī)訪(fǎng)問(wèn)向量 (vectors)。
  • 編碼大量數(shù)據(jù)到很小的空間,或者使用 GETBIT 和 SETBIT 命令,創(chuàng)建一個(gè)基于 Redis 的布隆 (Bloom) 過(guò)濾器。

后續(xù)我們會(huì)詳細(xì)介紹可用的字符串命令,也會(huì)詳細(xì)介紹 Redis 數(shù)據(jù)類(lèi)型的更多高級(jí)信息。

列表 (Lists)

Redis 列表僅僅是按照插入順序排序的字符串列表。可以添加一個(gè)元素到 Redis 列表的頭部 (左邊) 或者尾部 (右邊)。

LPUSH 命令用于插入一個(gè)元素到列表的頭部,RPUSH 命令用于插入一個(gè)元素到列表的尾部。當(dāng)這兩個(gè)命令操作在一個(gè)不存在的鍵時(shí),將會(huì)創(chuàng)建一個(gè)新的列表。同樣,如果一個(gè)操作會(huì)清空列表,那么該鍵將會(huì)從鍵空間 (key space) 移除。這些是非常方便的語(yǔ)義,因?yàn)榱斜砻钊绻褂貌淮嬖诘逆I作為參數(shù),就會(huì)表現(xiàn)得像命令運(yùn)行在一個(gè)空列表上一樣。

一些列表操作的例子結(jié)果:

LPUSH mylist a   # now the list is “a”  
LPUSH mylist b   # now the list is “b”, ”a”  
RPUSH mylist c   # now the list is “b”,”a”, ”c”(RPUSH was used this time)  

列表的最大長(zhǎng)度是 223-1 個(gè)元素 (4294967295,超過(guò) 40 億個(gè)元素)。

從時(shí)間復(fù)雜度的角度看,Redis 列表主要的特性是支持以常量時(shí)間在列表的頭和尾附近插入和刪除元素,即使列表中已經(jīng)插入了上百萬(wàn)的數(shù)據(jù)。訪(fǎng)問(wèn)列表兩端的元素非常的快速,但是訪(fǎng)問(wèn)一個(gè)非常大的列表的中間卻非常的慢,因?yàn)檫@是一個(gè) O(N)時(shí)間復(fù)雜度的操作。

你可以使用 Redis 的列表類(lèi)型做很多有意思的事情,例如,你可以:

  • 為社交網(wǎng)絡(luò)時(shí)間軸 (timeline) 建模,使用 LPUSH 命令往用戶(hù)時(shí)間軸插入元素,使用 LRANGE 命令獲得最近事項(xiàng)。
  • 使用 LPUSH 和 LTRIM 命令創(chuàng)建一個(gè)不會(huì)超出給定數(shù)量元素的列表,只存儲(chǔ)最近的 N 個(gè)元素。
  • 列表可以用作消息傳遞原語(yǔ),例如,眾所周知的用于創(chuàng)建后臺(tái)任務(wù)的 Ruby 庫(kù) Resque。
  • 你可以用列表做更多的事情,這種數(shù)據(jù)類(lèi)型支持很多的命令,包括阻塞命令,如 BLPOP。

后續(xù)我們會(huì)詳細(xì)介紹可用的列表命令,也會(huì)詳細(xì)介紹 Redis 數(shù)據(jù)類(lèi)型的更多高級(jí)信息。

集合 (Sets)

Redis 集合是沒(méi)有順序的字符串集合 (collection)??梢栽?O(1) 的時(shí)間復(fù)雜度添加、刪除和測(cè)試元素存在與否 (不管集合中有多少元素都是常量時(shí)間)。

Redis 集合具有你需要的不允許重復(fù)成員的性質(zhì)。多次加入同一個(gè)元素到集合也只會(huì)有一個(gè)拷貝在其中。實(shí)際上,這意味著加入一個(gè)元素到集合中并不需要檢查元素是否已存在。

Redis 集合非常有意思的是,支持很多服務(wù)器端的命令,可以在很短的時(shí)間內(nèi)和已經(jīng)存在的集合一起計(jì)算并集,交集和差集。

你可以使用 Redis 的集合類(lèi)型做很多有意思的事情,例如,你可以:

  • 你可以使用 Redis 集合追蹤唯一性的事情。你想知道訪(fǎng)問(wèn)某篇博客文章的所有唯一 IP 嗎?只要 每次頁(yè)面訪(fǎng)問(wèn)時(shí)使用 SADD 命令就可以了。你可以放心,重復(fù)的 IP 是不會(huì)被插入進(jìn)來(lái)的。
  • Redis 集合可以表示關(guān)系。你可以通過(guò)使用集合來(lái)表示每個(gè)標(biāo)簽,來(lái)創(chuàng)建一個(gè)標(biāo)簽系統(tǒng)。然后你可以把所有擁有此標(biāo)簽的對(duì)象的 ID 通過(guò) SADD 命令,加入到表示這個(gè)標(biāo)簽的集合中。你想獲得同時(shí)擁有三個(gè)不同標(biāo)簽的對(duì)象的全部 ID 嗎?用 SINTER 就可以了。
  • 你可以使用 SPOP 或 SRANDMEMBER 命令來(lái)從集合中隨機(jī)抽取元素。

后續(xù)我們會(huì)詳細(xì)介紹可用的集合命令,也會(huì)詳細(xì)介紹 Redis 數(shù)據(jù)類(lèi)型的更多高級(jí)信息。

哈希 / 散列 (Hashes)

Redis 哈希是字符串字段 (field) 與字符串值之間的映射,所以是表示對(duì)象的理想數(shù)據(jù)類(lèi)型 (例如:一個(gè)用戶(hù)對(duì)象有多個(gè)字段,像用戶(hù)名,姓氏,年齡等等):

@cli  
HMSET user:1000 username antirez password P1pp0 age 34  
HGETALL user:1000  
HSET user:1000 password 12345  
HGETALL user:1000  

擁有少量字段 (少量指的是大約 100) 的哈希會(huì)以占用很少存儲(chǔ)空間的方式存儲(chǔ),所以你可以在一個(gè)很小的 Redis 實(shí)例里存儲(chǔ)數(shù)百萬(wàn)的對(duì)象。

由于哈希主要用來(lái)表示對(duì)象,對(duì)象能存儲(chǔ)很多元素,所以你可以用哈希來(lái)做很多其他的事情。

每個(gè)哈??梢源鎯?chǔ)多達(dá) 223-1 個(gè)字段值對(duì) (field-value pair)(多于 40 億個(gè))。

后續(xù)我們會(huì)詳細(xì)介紹可用的哈希命令,也會(huì)詳細(xì)介紹 Redis 數(shù)據(jù)類(lèi)型的更多高級(jí)信息。

有序集合 (Sorted sets)

Redis 有序集合和 Redis 集合類(lèi)似,是非重復(fù)字符串集合 (collection)。不同的是,每一個(gè)有序集合的成員都有一個(gè)關(guān)聯(lián)的分?jǐn)?shù) (score),用于按照分?jǐn)?shù)高低排序。盡管成員是唯一的,但是分?jǐn)?shù)是可以重復(fù)的。

對(duì)有序集合我們可以通過(guò)很快速的方式添加,刪除和更新元素 (在和元素?cái)?shù)量的對(duì)數(shù)成正比的時(shí)間內(nèi))。由于元素是有序的而無(wú)需事后排序,你可以通過(guò)分?jǐn)?shù)或者排名 (位置) 很快地來(lái)獲取一個(gè)范圍內(nèi)的元素。訪(fǎng)問(wèn)有序集合的中間元素也是很快的,所以你可以使用有序集合作為一個(gè)無(wú)重復(fù)元素,快速訪(fǎng)問(wèn)你想要的一切的聰明列表:有序的元素,快速的存在性測(cè)試,快速的訪(fǎng)問(wèn)中間元素!

總之,有序集合可以在很好的性能下,做很多別的數(shù)據(jù)庫(kù)無(wú)法模擬的事情。

使用有序集合你可以:

例如多人在線(xiàn)游戲排行榜,每次提交一個(gè)新的分?jǐn)?shù),你就使用 ZADD 命令更新。你可以很容易地使用 ZRANGE 命令獲取前幾名用戶(hù),你也可以用 ZRANK 命令,通過(guò)給定用戶(hù)名返回其排行。同時(shí)使用 ZRANK 和 ZRANGE 命令可以展示與給定用戶(hù)相似的用戶(hù)及其分?jǐn)?shù)。以上這些操作都非常的快。

有序集合常用來(lái)索引存儲(chǔ)在 Redis 內(nèi)的數(shù)據(jù)。例如,假設(shè)你有很多表示用戶(hù)的哈希,你可以使用有序集合,用年齡作為元素的分?jǐn)?shù),用用戶(hù) ID 作為元素值,于是你就可以使用 ZRANGEBYSCORE 命令很快且輕而易舉地檢索出給定年齡區(qū)間的所有用戶(hù)了。

有序集合或許是最高級(jí)的 Redis 數(shù)據(jù)類(lèi)型,后續(xù)我們會(huì)詳細(xì)介紹可用的有序集合命令,也會(huì)詳細(xì)介紹 Redis 數(shù)據(jù)類(lèi)型的更多高級(jí)信息。

位圖 (Bitmaps) 和超重對(duì)數(shù) (HyperLogLogs)

Redis 還支持位圖和超重對(duì)數(shù)這兩種基于字符串基本類(lèi)型,但有自己語(yǔ)義的數(shù)據(jù)類(lèi)型。

后續(xù)我們會(huì)詳細(xì)介紹這些數(shù)據(jù)類(lèi)型的更多高級(jí)信息。