<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                現在開始將探究Redis的5種數據結構,我們會解釋每種數據結構都是什么,包含了什么有效的方法(Method),以及你能用這些數據結構處理哪些類型的特性和數據。 目前為止,我們所知道的Redis構成僅包括命令、關鍵字和值,還沒有接觸到關于數據結構的具體概念。當我們使用`set`命令時,Redis是怎么知道我們是在使用哪個數據結構?其解決方法是,每個命令都相對應于一種特定的數據結構。例如,當你使用`set`命令,你就是將值存儲到一個字符串數據結構里。而當你使用`hset`命令,你就是將值存儲到一個散列數據結構里。考慮到Redis的關鍵字集很小,這樣的機制具有相當的可管理性。 [Redis的網站](http://redis.io/commands)里有著非常優秀的參考文檔,沒有任何理由去重造輪子。但為了搞清楚這些數據結構的作用,我們將會覆蓋那些必須知道的重要命令。 沒有什么事情比高興的玩和試驗有趣的東西來得更重要的了。在任何時候,你都能通過鍵入`flushdb`命令將你數據庫里的所有值清除掉,因此,不要再那么害羞了,去嘗試做些瘋狂的事情吧! ## 字符串(Strings) 在Redis里,字符串是最基本的數據結構。當你在思索著關鍵字-值對時,你就是在思索著字符串數據結構。不要被名字給搞混了,如之前說過的,你的值可以是任何東西。我更喜歡將他們稱作“標量”(Scalars),但也許只有我才這樣想。 我們已經看到了一個常見的字符串使用案例,即通過關鍵字存儲對象的實例。有時候,你會頻繁地用到這類操作: ~~~ set users:leto "{name: leto, planet: dune, likes: [spice]}" ~~~ 除了這些外,Redis還有一些常用的操作。例如,`strlen `能用來獲取一個關鍵字對應值的長度;`getrange `將返回指定范圍內的關鍵字對應值;`append `會將value附加到已存在的關鍵字對應值中(如果該關鍵字并不存在,則會創建一個新的關鍵字-值對)。不要猶豫,去試試看這些命令吧。下面是我得到的: ~~~ > strlen users:leto (integer) 42 > getrange users:leto 27 40 "likes: [spice]" > append users:leto " OVER 9000!!" (integer) 54 ~~~ 現在你可能會想,這很好,但似乎沒有什么意義。你不能有效地提取出一段范圍內的JSON文件,或者為其附加一些值。你是對的,這里的經驗是,一些命令,尤其是關于字符串數據結構的,只有在給定了明確的數據類型后,才會有實際意義。 之前我們知道了,Redis不會去關注你的值是什么東西。通常情況下,這沒有錯。然而,一些字符串命令是專門為一些類型或值的結構而設計的。作為一個有些含糊的用例,我們可以看到,對于一些自定義的空間效率很高的(space-efficient)串行化對象,`append`和`getrange`命令將會很有用。對于一個更為具體的用例,我們可以再看一下`incr`、`incrby`、`decr`和`decrby`命令。這些命令會增長或者縮減一個字符串數據結構的值: ~~~ > incr stats:page:about (integer) 1 > incr stats:page:about (integer) 2 > incrby ratings:video:12333 5 (integer) 5 > incrby ratings:video:12333 3 (integer) 8 ~~~ 由此你可以想象到,Redis的字符串數據結構能很好地用于分析用途。你還可以去嘗試增長`users:leto`(一個不是整數的值),然后看看會發生什么(應該會得到一個錯誤)。 更為進階的用例是`setbit`和`getbit`命令。“今天我們有多少個獨立用戶訪問”是個在Web應用里常見的問題,有一篇[精彩的博文](http://blog.getspool.com/2011/11/29/fast-easy-realtime-metrics-using-redis-bitmaps/),在里面可以看到Spool是如何使用這兩個命令有效地解決此問題。對于1.28億個用戶,一部筆記本電腦在不到50毫秒的時間里就給出了答復,而且只用了16MB的存儲空間。 最重要的事情不是在于你是否明白位圖(Bitmaps)的工作原理,或者Spool是如何去使用這些命令,而是應該要清楚Redis的字符串數據結構比你當初所想的要有用許多。然而,最常見的應用案例還是上面我們給出的:存儲對象(簡單或復雜)和計數。同時,由于通過關鍵字來獲取一個值是如此之快,字符串數據結構很常被用來緩存數據。 ## 散列(Hashes) 我們已經知道把Redis稱為一種關鍵字-值型存儲是不太準確的,散列數據結構是一個很好的例證。你會看到,在很多方面里,散列數據結構很像字符串數據結構。兩者顯著的區別在于,散列數據結構提供了一個額外的間接層:一個域(Field)。因此,散列數據結構中的`set`和`get`是: ~~~ hset users:goku powerlevel 9000 hget users:goku powerlevel ~~~ 相關的操作還包括在同一時間設置多個域、同一時間獲取多個域、獲取所有的域和值、列出所有的域或者刪除指定的一個域: ~~~ hmset users:goku race saiyan age 737 hmget users:goku race powerlevel hgetall users:goku hkeys users:goku hdel users:goku age ~~~ 如你所見,散列數據結構比普通的字符串數據結構具有更多的可操作性。我們可以使用一個散列數據結構去獲得更精確的描述,是存儲一個用戶,而不是一個序列化對象。從而得到的好處是能夠提取、更新和刪除具體的數據片段,而不必去獲取或寫入整個值。 對于散列數據結構,可以從一個經過明確定義的對象的角度來考慮,例如一個用戶,關鍵之處在于要理解他們是如何工作的。從性能上的原因來看,這是正確的,更具粒度化的控制可能會相當有用。在下一章我們將會看到,如何用散列數據結構去組織你的數據,使查詢變得更為實效。在我看來,這是散列真正耀眼的地方。 ## 列表(Lists) 對于一個給定的關鍵字,列表數據結構讓你可以存儲和處理一組值。你可以添加一個值到列表里、獲取列表的第一個值或最后一個值以及用給定的索引來處理值。列表數據結構維護了值的順序,提供了基于索引的高效操作。為了跟蹤在網站里注冊的最新用戶,我們可以維護一個`newusers`的列表: ~~~ lpush newusers goku ltrim newusers 0 50 ~~~ (譯注:`ltrim`命令的具體構成是`LTRIM Key start stop`。要理解`ltrim`命令,首先要明白Key所存儲的值是一個列表,理論上列表可以存放任意個值。對于指定的列表,根據所提供的兩個范圍參數start和stop,`ltrim`命令會將指定范圍外的值都刪除掉,只留下范圍內的值。) 首先,我們將一個新用戶推入到列表的前端,然后對列表進行調整,使得該列表只包含50個最近被推入的用戶。這是一種常見的模式。`ltrim`是一個具有O(N)時間復雜度的操作,N是被刪除的值的數量。從上面的例子來看,我們總是在插入了一個用戶后再進行列表調整,實際上,其將具有O(1)的時間復雜度(因為N將永遠等于1)的常數性能。 這是我們第一次看到一個關鍵字的對應值索引另一個值。如果我們想要獲取最近的10個用戶的詳細資料,我們可以運行下面的組合操作: ~~~ keys = redis.lrange('newusers', 0, 10) redis.mget(*keys.map {|u| "users:#{u}"}) ~~~ 我們之前談論過關于多次往返數據的模式,上面的兩行Ruby代碼為我們進行了很好的演示。 當然,對于存儲和索引關鍵字的功能,并不是只有列表數據結構這種方式。值可以是任意的東西,你可以使用列表數據結構去存儲日志,也可以用來跟蹤用戶瀏覽網站時的路徑。如果你過往曾構建過游戲,你可能會使用列表數據結構去跟蹤用戶的排隊活動。 ## 集合(Sets) 集合數據結構常常被用來存儲只能唯一存在的值,并提供了許多的基于集合的操作,例如并集。集合數據結構沒有對值進行排序,但是其提供了高效的基于值的操作。使用集合數據結構的典型用例是朋友名單的實現: ~~~ sadd friends:leto ghanima paul chani jessica sadd friends:duncan paul jessica alia ~~~ 不管一個用戶有多少個朋友,我們都能高效地(O(1)時間復雜度)識別出用戶X是不是用戶Y的朋友: ~~~ sismember friends:leto jessica sismember friends:leto vladimir ~~~ 而且,我們可以查看兩個或更多的人是不是有共同的朋友: ~~~ sinter friends:leto friends:duncan ~~~ 甚至可以在一個新的關鍵字里存儲結果: ~~~ sinterstore friends:leto_duncan friends:leto friends:duncan ~~~ 有時候需要對值的屬性進行標記和跟蹤處理,但不能通過簡單的復制操作完成,集合數據結構是解決此類問題的最好方法之一。當然,對于那些需要運用集合操作的地方(例如交集和并集),集合數據結構就是最好的選擇。 ## 分類集合(Sorted Sets) 最后也是最強大的數據結構是分類集合數據結構。如果說散列數據結構類似于字符串數據結構,主要區分是域(field)的概念;那么分類集合數據結構就類似于集合數據結構,主要區分是標記(score)的概念。標記提供了排序(sorting)和秩劃分(ranking)的功能。如果我們想要一個秩分類的朋友名單,可以這樣做: ~~~ zadd friends:duncan 70 ghanima 95 paul 95 chani 75 jessica 1 vladimir ~~~ 對于`duncan`的朋友,要怎樣計算出標記(score)為90或更高的人數? ~~~ zcount friends:duncan 90 100 ~~~ 如何獲取`chani`在名單里的秩(rank)? ~~~ zrevrank friends:duncan chani ~~~ (譯注:`zrank`命令的具體構成是`ZRANK Key menber`,要知道Key存儲的Sorted Set默認是根據Score對各個menber進行升序的排列,該命令就是用來獲取menber在該排列里的次序,這就是所謂的秩。) 我們使用了`zrevrank`命令而不是`zrank`命令,這是因為Redis的默認排序是從低到高,但是在這個例子里我們的秩劃分是從高到低。對于分類集合數據結構,最常見的應用案例是用來實現排行榜系統。事實上,對于一些基于整數排序,且能以標記(score)來進行有效操作的東西,使用分類集合數據結構來處理應該都是不錯的選擇。 ## 小結 對于Redis的5種數據結構,我們進行了高層次的概述。一件有趣的事情是,相對于最初構建時的想法,你經常能用Redis創造出一些更具實效的事情。對于字符串數據結構和分類集合數據結構的使用,很有可能存在一些構建方法是還沒有人想到的。當你理解了那些常用的應用案例后,你將發現Redis對于許多類型的問題,都是很理想的選擇。還有,不要因為Redis展示了5種數據結構和相應的各種方法,就認為你必須要把所有的東西都用上。只使用一些命令去構建一個特性是很常見的。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看