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: 计算方便

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