Redis專題(二)——Redis資料型別(1)
Redis專題(二)——Redis資料型別(1)
(原創內容,轉載請註明來源,謝謝)
一、概述
Redis是一種Key-Value型別的資料庫,屬於非關係型資料庫,NoSQL的一種。Redis共有5種資料型別:字串(string)、雜湊(hash)、列表(list)、集合(set)、有序集合(zset)。
1、萬用字元
Redis支援部分萬用字元,包括?、*、[]、x,和正則表示式一致,?表示匹配0或1個,*匹配任意個,[]匹配框內的任意一個內容,x轉義,例如?表示匹配?。
2、獲取鍵 KEYS
當要獲取鍵值時,可以用KEYS* 獲取所有的鍵,也可以用KEYS a*獲取所有a開頭的鍵。該方法會遍歷所有的鍵,影響效能,不建議使用。
3、判斷鍵是否存在 EXISTS
如 EXISTS test,判斷test鍵是否存在,存在返回整數1,不存在返回0。
4、刪除鍵 DEL
DELtest,如果test存在,則刪除,返回1;如果不存在,則返回0。
該命令不支援萬用字元,因此要刪除多個鍵時,可以在linux命令列下,通過管道符的方式獲取與刪除,例如redis-cli KEYS “user*” | xargs redis-cli DEL。其中xargs是將管道符前面的命令的執行結果作為引數傳給xargs後面的命令。也可以使用redis-cli DEL “user*”的方式刪除。
5、獲取鍵的資料型別 TYPE
TYPEtest 可以獲取test鍵的資料型別,返回值即上述五種資料型別中的一種。
6、原子性
redis的所有命令都是原子性的,例如自增命令incr,當併發呼叫incr對某個key的value設定自增,只會增加一次。其他命令也是如此。
7、儲存方式
redis儲存元素都是用hash的方式儲存,將每個鍵用hash進行計算後,儲存在hash(key)的位置,每個位置即為一個bucket。當hash(key1)和hash(key2)相同時,會採用連結串列的方式,將key1和key2都儲存在同一個bucket的結果中,bucket根路徑指向key1,key1再指向key2。
二、字串型別(String)
字串是redis的最基本資料型別,其他的資料型別可以看作是各種方式把字串集合在一起的型別。字串的一個鍵允許儲存512MB的值,因此可以存放絕大多數的內容。
1、使用方式
賦值:SET keyvalue,給key賦值為value。獲取:GET key。當get不存在的鍵,會返回(nil)。
用PHP連線redis,並接收命令列的引數,使用set和get操作redis,如下:
<?php
$redis = new Redis();
$redis->pconnect('127.0.0.1', 6379);
$name = $argv[1];
$redis->set('test:1:name', $name);
echo $redis->get('test:1:name');
echo PHP_EOL;
2、遞增數字
INCRkey,當key對於的value是數字時自增1,否則會報error。當key沒有設定value時,預設是0,所以執行INCR會變成1。
redis中的操作都是都是原子操作,因此當有多個客戶端併發對某個鍵使用INCR時,最後的結果也僅加1次,不會出現多次加的情況。
3、實現文章訪問量統計
給每篇文章設定一個名字,名字為article:id:page.view,表示文章的id中某個頁面的訪問量。
1)id可以選用文章在資料庫(如mysql)中的id。如果文章不用資料庫儲存,而用redis,則也可以自制自增的id。自增id的設定方法為,新建一個欄位為articles:count,初始值為1,每有一篇文章要計算時,就把這個值INCR,返回的結果就是文章的id。
2)當要用redis儲存文章標題、內容等資訊時,需要將文章的各類內容儲存在陣列中,通過PHP序列化後進行儲存,取出則同樣是反序列化後使用。
4、字串相關其他命令
1)增加指定整數:INCRBY、自減一:DECR、減少指定整數:DECRBY、增加浮點數:INCRBYFLOAT。
2)尾部追加內容:APPEND、獲取串長度:STRLEN。
3)同時獲取/設定多個值:MGETkey1 key2…. ,MSET key1 value1 key2 value2…
4)位操作:SETBIT ival、GETBIT,獲取或者操作變數的第i位,由於是二進位制操作,因此值只有0或1。此方法用於獲取或設定數量較小的內容時,效率極高,如性別、狀態等,只有幾個數字的可能的情況,用此方法比較好。
三、雜湊型別(Hash)
雜湊儲存了欄位和欄位值的對映,即每個key對應的值仍是field =>value的形式,每個key可以對應多個field =>value形式的內容,最多支援232-1。但是欄位值只能是string,不能是其他型別,即不支援巢狀。
redis的每種型別都只支援字串,不支援型別的巢狀。
1、設定與獲取
1)單次單個:HGETkey field、HSET key field value
2)單次多個:HMGETkey field1 field2… 、HMSET key field1 value1 field2 value2…
3)獲取某個key的全部:HGETALL,返回的是field1、value1、field2、value2…,不是很直觀,但是很多語言都已經將結果封裝。
在PHP中,$redis->hgetall(key)會返回key對應的field=>value的一個二維陣列。
但是,當欄位數量非常多時,由於redis是單執行緒的,hgetall要遍歷某個key所有的field和value,因此會發生阻塞,甚至可能是伺服器宕機。
因此,可以將key和field另外進行儲存。
2、判斷
1)field是否存在:HEXISTSkey field
2)field不存在時賦值:HSETNXkey field value,由於具有原子性,當多個hsetnx命令同時發出時,只會執行第一個命令,後面的命令由於已經有值了所以不會再次設定。
3)增加數字:HINCRBYkey field increment
4)刪除field:HDEL keyfield1 field2…
3、儲存文章資料
當使用序列化將文章的標題、內容等儲存,反序列化取出時,存在的問題由於反序列化以及修改的操作不是在redis執行,不是原子性,因此併發情況下有可能發生問題。另外,反序列化則如果只修改標題也需要取出全部內容,浪費資源。
使用雜湊可以很好解決此問題,儲存的方法是關鍵字設定為article:id,然後裡面的field分別是title、content等,要修改也可以用HSET進行修改。
4、其他命令
1)部分獲取:只獲取field——HKEYS key,只獲取value——HVALS key,獲取field的數量:HLEN key
——written by linhxx 2017.08.04