Redis字符串類型的操作

set key value [ex 秒數] / [px 毫秒數] [nx] /[xx]

如: set a 1 ex 10 , 10秒有效
Set a 1 px 9000 , 9秒有效
注: 如果ex,px同時寫,以後面的有效期爲準
如 set a 1 ex 100 px 9000, 實際有效期是9000毫秒

nx: 表示key不存在時,執行操作
xx: 表示key存在時,執行操作

<?php
$redis->set('myname','ikodota');

mset multi set , 一次性設置多個鍵值

例: mset key1 v1 key2 v2 ….

<?php
$redis->mset(array('key1'=>1,'key2'=>2,...));

get key

作用:獲取key的值

<?php
$redis->get($key);

mget key1 key2 ..keyn

作用:獲取多個key的值

<?php
$redis->mget(array('key1','key2',...));

setrange key offset value

作用:把字符串的offset偏移字節,改成value

redis 127.0.0.1:6379> set greet hello
OK
redis 127.0.0.1:6379> setrange greet 2 x
(integer) 5
redis 127.0.0.1:6379> get greet
"hexlo"

注意: 如果偏移量>字符長度, 該字符自動補0x00

redis 127.0.0.1:6379> setrange greet 6 !
(integer) 7
redis 127.0.0.1:6379> get greet
"heyyo\x00!"
<?php
$redis->SETRANGE('greet', 2, "x"); //int(5)

append key value

作用: 把value追加到key的原值上

<?php
$redis->append('myphone',"nokia"); # 對不存在的key進行APPEND,等同於SET myphone "nokia" //int(5) # 字符長度

# 情況2:對字符串進行APPEND
$redis->append('myphone', " - 1110");# 長度從5個字符增加到12個字符 //int(12)
echo $redis->get('myphone'); # 查看整個字符串 //"nokia - 1110"

getrange key start stop

作用: 是獲取字符串中 [start, stop]範圍的值
注意: 對於字符串的下標,左數從0開始,右數從-1開始

redis 127.0.0.1:6379> set title 'chinese'
OK
redis 127.0.0.1:6379> getrange title 0 3
"chin"
redis 127.0.0.1:6379> getrange title 1 -2
"hines"

注意:
1: start>=length, 則返回空字符串
2: stop>=length,則截取至字符結尾
3: 如果start 所處位置在stop右邊, 返回空字符串**

<?php
$redis->SET('greeting', "hello, my friend");
echo $redis->GETRANGE('greeting', 0, 4); # 返回索引0-4的字符(包括4)。//"hello"
echo $redis->GETRANGE('greeting', -1 ,-5); # 不支持迴繞操作
echo $redis->GETRANGE('greeting', -3 ,-1); # 負數索引 //"end"
echo $redis->GETRANGE('greeting', 0, -1); # 從第一個到最後一個 //"hello, my friend"
echo $redis->GETRANGE('greeting', 0, 1008611); # 值域範圍不超過實際字符串,超過部分自動被符略 //"hello, my friend"

getset key newvalue

作用: 獲取並返回舊值,設置新值

redis 127.0.0.1:6379> set cnt 0
OK
redis 127.0.0.1:6379> getset cnt 1
"0"
redis 127.0.0.1:6379> getset cnt 2
"1"
<?php
var_dump($redis->EXISTS('mail'));//return bool(false);
var_dump($redis->GETSET('mail','[email protected]')); # 因爲mail之前不存在,沒有舊值,返回nil ,#(nil) //bool(false)

var_dump($redis->GETSET('mail','[email protected]')); # mail被更新,舊值被返回 //string(14) "[email protected]"

incr key

作用: 指定的key的值加1,並返回加1後的值

注意:
1:不存在的key當成0,再incr操作
2: 範圍爲64有符號

應用實例

GETSET可以和INCR組合使用,實現一個有原子性(atomic)復位操作的計數器(counter)。
舉例來說,每次當某個事件發生時,進程可能對一個名爲mycount的key調用INCR操作,通常我們還要在一個原子時間內同時完成獲得計數器的值和將計數器值復位爲0兩個操作。
可以用命令GETSET mycounter 0來實現這一目標。

<?php
$redis->select(2);
echo $redis->incr('mycount'); #(integer) 11

if($redis->get('mycount')>19){
echo $redis->getset('mycount', 0); # 一個原子內完成get mycount和set mycount 0操作 #"11"
}
echo $redis->get('mycount'); #"0"

incrby key number

作用: 指定的key的值加N,並返回加N後的值

redis 127.0.0.1:6379> incrby age  90
(integer) 92
<?php
# 情況1:key存在且是數字值
$redis->SET('rank', 50); # 設置rank爲50
$redis->INCRBY('rank', 20); # 給rank加上20
var_dump($redis->GET('rank')); #"70" //string(2) "70"

# 情況2:key不存在
$redis->EXISTS('counter'); //bool(false)
$redis->INCRBY('counter',30); #int 30 //bool(false)
var_dump($redis->GET('counter')); #30 //經測試 與手冊上結果不一樣,不能直接從bool型轉爲int型。 return bool(false)

# 情況3:key不是數字值
$redis->SET('book', "long long ago...");
var_dump($redis->INCRBY('book', 200)); #(error) ERR value is not an integer or out of range // bool(false)

incrbyfloat key floatnumber

redis 127.0.0.1:6379> incrbyfloat age 3.5
"95.5"
<?php
$redis->incrByFloat('key1', 1.5);//key1 不在,則賦值1.5

$redis->incrByFloat('key1', 1.5); // 3
$redis->incrByFloat('key1', -1.5); //1.5
$redis->incrByFloat('key1', 2.5); //3.5

decr key

自減1,不存在的key則賦值-1

redis 127.0.0.1:6379> set age 20
OK
redis 127.0.0.1:6379> decr age
(integer) 19
<?php
# 情況1:對存在的數字值key進行decr
$redis->set('failure_times', 10);
$redis->decr('failure_times'); //int(9)
echo $redis->get('failure_times').'
'; //string(1) "9"

# 情況2:對不存在的key值進行decr
$redis->exists('count'); #(integer) 0 //bool(false)
$redis->decr('count'); //int(-1)
echo $redis->get('count').'
'; //string(2) "-1"

# 情況3:對存在但不是數值的key進行decr
$redis->set('company', 'your_code_sucks.llc');
var_dump($redis->decr('company')); #(error) err value is not an integer or out of range //bool(false)
echo $redis->get('company').'
'; //your_code_sucks.llc

decrby key number

redis 127.0.0.1:6379> decrby age 3
(integer) 16
<?php
$redis->set('count', 100);
var_dump($redis->decrby('count', 20)); //int(80)
var_dump($redis->get('count')); //string(2) "80"

# 情況2:對不存在的key進行decrby
$redis->exists('pages');#(integer) 0 //bool(false)
var_dump($redis->decrby('pages', 10)); //int(-10)
var_dump($redis->get('pages')); //string(3) "-10"

setbit key offset value

設置offset對應二進制位上的值
返回: 該位上的舊值

注意:
1:如果offset過大,則會在中間填充0,
2: offset最大大到多少
3:offset最大2^32-1,可推出最大的的字符串爲512M

<?php
echo decbin(65); //1000001(A)
var_dump($redis->setbit('bit',0,1));//int(1)
var_dump($redis->setbit('bit',1,0));//int(0)
var_dump($redis->setbit('bit',2,0));//int(0)
var_dump($redis->setbit('bit',3,0));//int(0)
var_dump($redis->setbit('bit',4,0));//int(0)
var_dump($redis->setbit('bit',5,0));//int(0)
var_dump($redis->setbit('bit',6,1));//int(0)
var_dump($redis->setbit('bit',7,1));//int(1)

var_dump($redis->get('bit')); //string(1) "A" ,二進制爲:1000001 ,ascii:65

var_dump($redis->getbit('bit', 6 )); //int(1) 取出第6位(從左到右)爲“1”

getbit key offset

作用:獲取值的二進制表示,對應位上的值(從左,從0編號)

redis 127.0.0.1:6379> set char A
OK
redis 127.0.0.1:6379> getbit char 1
(integer) 1
redis 127.0.0.1:6379> getbit char 2
(integer) 0
redis 127.0.0.1:6379> getbit char 7
(integer) 1
<?php
var_dump($redis->getbit('bit', 6 )); //int(1) 取出第6位(從左到右)爲“1”

bitop operation destkey key1 [key2 …]

對key1,key2..keyN作operation,並將結果保存到 destkey 上。
operation 可以是 AND 、 OR 、 NOT 、 XOR

redis 127.0.0.1:6379> setbit lower 7 0
(integer) 0
redis 127.0.0.1:6379> setbit lower 2 1
(integer) 0
redis 127.0.0.1:6379> get lower
" "
redis 127.0.0.1:6379> set char Q
OK
redis 127.0.0.1:6379> get char
"Q"
redis 127.0.0.1:6379> bitop or char char lower
(integer) 1
redis 127.0.0.1:6379> get char
"q"

注意: 對於NOT操作, key不能多個

Setbit 的實際應用

場景: 1億個用戶, 每個用戶 登陸/做任意操作 ,記爲 今天活躍,否則記爲不活躍

每週評出: 有獎活躍用戶: 連續7天活動
每月評,等等…

思路:

Userid dt active
1 2013-07-27 1
1 2013-0726 1

如果是放在表中, 1:表急劇增大,2:要用group ,sum運算,計算較慢

用: 位圖法 bit-map
Log0721: ‘011001……………0’

……
log0726 : ‘011001……………0’
Log0727 : ‘0110000………….1’

1: 記錄用戶登陸:
每天按日期生成一個位圖, 用戶登陸後,把user_id位上的bit值置爲1

2: 把1周的位圖 and 計算,
位上爲1的,即是連續登陸的用戶

redis 127.0.0.1:6379> setbit mon 100000000 0
(integer) 0
redis 127.0.0.1:6379> setbit mon 3 1
(integer) 0
redis 127.0.0.1:6379> setbit mon 5 1
(integer) 0
redis 127.0.0.1:6379> setbit mon 7 1
(integer) 0
redis 127.0.0.1:6379> setbit thur 100000000 0
(integer) 0
redis 127.0.0.1:6379> setbit thur 3 1
(integer) 0
redis 127.0.0.1:6379> setbit thur 5 1
(integer) 0
redis 127.0.0.1:6379> setbit thur 8 1
(integer) 0
redis 127.0.0.1:6379> setbit wen 100000000 0
(integer) 0
redis 127.0.0.1:6379> setbit wen 3 1
(integer) 0
redis 127.0.0.1:6379> setbit wen 4 1
(integer) 0
redis 127.0.0.1:6379> setbit wen 6 1
(integer) 0
redis 127.0.0.1:6379> bitop and  res mon feb wen
(integer) 12500001

如上例,優點:
1: 節約空間, 1億人每天的登陸情況,用1億bit,約1200WByte,約10M 的字符就能表示
2: 計算方便

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章