php redis操作具体解释

系统 1836 0
phpredis是redis的php的一个扩展,效率是相当高有链表排序功能,对创建内存级的模块业务关系


非常实用;下面是redis官方提供的命令使用技巧:


下载地址例如以下:


https://github.com/owlient/phpredis(支持redis 2.0.4)


Redis::__construct构造函数
$redis = new Redis();


connect, open 链接redis服务
參数
host: string,服务地址
port: int,端口号
timeout: float,链接时长 (可选, 默觉得 0 ,不限链接时间)
注: 在redis.conf中也有时间,默觉得300


pconnect, popen 不会主动关闭的链接
參考上面


setOption 设置redis模式


getOption 查看redis设置的模式


ping 查看连接状态


 


KEY相关操作


DEL


移除给定的一个或多个key。


假设key不存在,则忽略该命令。


时间复杂度:
    O(N),N为要移除的key的数量。
    移除单个字符串类型的key,时间复杂度为O(1)。
    移除单个列表、集合、有序集合或哈希表类型的key,时间复杂度为O(M),M为以上数据结构内的元素数量。
返回值:
    被移除key的数量。


 








//DEL
# 情况1: 删除单个key
$redis->set('myname','ikodota');
echo $redis->get('myname').'<br>'; # 返回:ikodota


$redis->del('myname');# 返回 TRUE(1)
var_dump($redis->get('myname')); # 返回 bool(false)


# 情况2: 删除一个不存在的key
if(!$redis->exists('fake_key')) # 不存在
var_dump($redis->del('fake_key')); # 返回 int(0)


# 情况3: 同一时候删除多个key
$array_mset=array('first_key'=>'first_val',
          'second_key'=>'second_val',
          'third_key'=>'third_val');
$redis->mset($array_mset); #用MSET一次储存多个值
$array_mget=array('first_key','second_key','third_key');
var_dump($redis->mget($array_mget)); #一次返回多个值 //array(3) { [0]=> string(9) "first_val" [1]=> string(10) "second_val" [2]=> string(9) "third_val" }


$redis->del($array_mget); #同一时候删除多个key
var_dump($redis->mget($array_mget)); #返回 array(3) { [0]=> bool(false) [1]=> bool(false) [2]=> bool(false) }










 


KEYS
KEYS pattern 
查找符合给定模式的key。


KEYS *命中数据库中全部key。
KEYS h?llo命中hello, hallo and hxllo等。
KEYS h*llo命中hllo和heeeeello等。
KEYS h[ae]llo命中hello和hallo,但不命中hillo。


特殊符号用"\"隔开


时间复杂度:
    O(N),N为数据库中key的数量。
返回值:
    符合给定模式的key列表。


警告 :KEYS的速度很快,但在一个大的数据库中使用它仍然可能造成性能问题,假设你须要从一个数据集中查找特定的key,你不妨用集合(Set)。


 








//KEYS
#$redis->FLUSHALL();
$array_mset_keys=array('one'=>'1',
          'two'=>'2',
          'three '=>'3',
          'four'=>'4');
$redis->mset($array_mset_keys); #用MSET一次储存多个值
var_dump($redis->keys('*o*')); //array(3) { [0]=> string(4) "four" [1]=> string(3) "two" [2]=> string(3) "one" }
var_dump($redis->keys('t??')); //array(1) { [0]=> string(3) "two" }
var_dump($redis->keys('t[w]*')); //array(1) { [0]=> string(3) "two" }
print_r($redis->keys('*')); //Array ( [0] => four [1] => three [2] => two [3] => one )










 


RANDOMKEY


从当前数据库中随机返回(不删除)一个key。


时间复杂度:
    O(1)
返回值:
    当数据库不为空时,返回一个key。
    当数据库为空时,返回nil。


 








//RANDOMKEY
$redis->FLUSHALL();
# 情况1:数据库不为空
$array_mset_randomkey=array('fruit'=>'apple',
                'drink'=>'beer',
                'food'=>'cookis');
$redis->mset($array_mset_randomkey);
echo $redis->randomkey(); 
print_r($redis->keys('*')); # 查看数据库内全部key,证明RANDOMKEY并不删除key//Array ( [0] => food [1] => drink [2] => fruit )


# 情况2:数据库为空
$redis->flushdb();  # 删除当前数据库全部key
var_dump($redis-> randomkey()); //bool(false)
 

TTL
TTL key

返回给定key的剩余生存时间(time to live)(以秒为单位)。

时间复杂度:
    O(1)
返回值:
    key的剩余生存时间(以秒为单位)。
    当key不存在或没有设置生存时间时,返回-1 。




//TTL
# 情况1:带TTL的key
$redis->flushdb();
//$redis->set('name','ikodota'); # 设置一个key
$redis->expire('name',30);  # 设置生存时间为30秒 //return (integer) 1
echo $redis->get('name'); //return ikodota
echo $redis->ttl('name'); //(integer) 25


//echo $redis->ttl('name');  # 30秒过去,name过期 //(integer) -1
var_dump($redis->get('name')); # 过期的key将被删除 //return bool(false);


# 情况2:不带TTL的key
$redis->set('site','wikipedia.org');//OK
var_dump($redis->ttl('site'));//int(-1)


# 情况3:不存在的key
$redis->EXISTS('not_exists_key');//int(0)
var_dump($redis->TTL('not_exists_key'));//int(-1)




EXISTS
EXISTS key


检查给定key是否存在。


时间复杂度:
    O(1)
返回值:
    若key存在,返回1,否则返回0。








//EXISTS
echo '<br>EXISTS<br>';
$redis->set('db',"redis"); //bool(true) 
var_dump($redis->exists('db'));  # key存在 //bool(true) 
$redis->del('db');   # 删除key //int(1)
var_dump($redis->exists('db'))  # key不存在 //bool(false)








 


MOVE
MOVE key db


将当前数据库(默觉得0)的key移动到给定的数据库db其中。


假设当前数据库(源数据库)和给定数据库(目标数据库)有同样名字的给定key,或者key不存在于当前数据库,那么MOVE没有不论什么效果。


因此,也能够利用这一特性,将MOVE当作锁(locking)原语。


时间复杂度:
    O(1)
返回值:
    移动成功返回1,失败则返回0。










//MOVE
echo '<br><br>MOVE<br>';
# 情况1: key存在于当前数据库
$redis->SELECT(0);  # redis默认使用数据库0,为了清晰起见,这里再显式指定一次。//OK
$redis->SET('song',"secret base - Zone"); //OK
var_dump ($redis->MOVE('song',1));  # 将song移动到数据库1 //bool(true)


# 情况2:当key不存在的时候
$redis->SELECT(1);
var_dump ($redis->EXISTS('fake_key'));//bool(false);
var_dump($redis->MOVE('fake_key', 0));  # 试图从数据库1移动一个不存在的key到数据库0,失败) //bool(false)


$redis->SELECT(0); # 使用数据库0
var_dump($redis->EXISTS('fake_key'));  # 证实fake_key不存在 //bool(false)


# 情况3:当源数据库和目标数据库有同样的key时


$redis->SELECT(0);  # 使用数据库0
$redis->SET('favorite_fruit',"banana");


$redis->SELECT(1);  # 使用数据库1
$redis->SET('favorite_fruit',"apple");


$redis->SELECT(0);  # 使用数据库0,并试图将favorite_fruit移动到数据库1
var_dump($redis->MOVE('favorite_fruit',1));  # 由于两个数据库有同样的key,MOVE失败 //return bool(false)
echo $redis->GET('favorite_fruit');  # 数据库0的favorite_fruit没变 //return banana


$redis->SELECT(1);
echo $redis->GET('favorite_fruit');   # 数据库1的favorite_fruit也是 //return apple










 


RENAME 


RENAME key newkey


将key改名为newkey。


当key和newkey同样或者key不存在时,返回一个错误。


当newkey已经存在时,RENAME命令将覆盖旧值。


时间复杂度:
    O(1)
返回值:
    改名成功时提示OK,失败时候返回一个错误。










//RENAME
echo '<br><br>RENAME<br>';
# 情况1:key存在且newkey不存在
$redis->SET('message',"hello world");
var_dump($redis->RENAME('message','greeting'));  //bool(true)
var_dump($redis->EXISTS('message'));  # message不复存在 //bool(false)
var_dump($redis->EXISTS('greeting'));   # greeting取而代之 //bool(true)


# 情况2:当key不存在时,返回错误 ,php返回false;
var_dump($redis->RENAME('fake_key','never_exists'));  //bool(false)


# 情况3:newkey已存在时,RENAME会覆盖旧newkey
$redis->SET('pc',"lenovo");
$redis->SET('personal_computer',"dell"); 
var_dump($redis->RENAME('pc','personal_computer')); //bool(true)
var_dump($redis->GET('pc')); //(nil)   bool(false)
var_dump($redis->GET('personal_computer'));  # dell“没有”了 //string(6) "lenovo"










 


RENAMENX 


RENAMENX key newkey


当且仅当newkey不存在时,将key改为newkey。


出错的情况和RENAME一样(key不存在时报错)。


时间复杂度:
    O(1)
返回值:
    改动成功时,返回1。
    假设newkey已经存在,返回0。










//RENAMENX
echo '<br><br>RENAMENX<br>';


# 情况1:newkey不存在,成功
$redis->SET('player',"MPlyaer");
$redis->EXISTS('best_player'); //int(0)
var_dump($redis->RENAMENX('player','best_player')); // bool(true) 


# 情况2:newkey存在时,失败
$redis->SET('animal',"bear");
$redis->SET('favorite_animal', "butterfly");


var_dump($redis->RENAMENX('animal', 'favorite_animal'));// bool(false)


var_dump($redis->get('animal')); //string(4) "bear"
var_dump($redis->get('favorite_animal')); //string(9) "butterfly"














TYPE
TYPE key


返回key所储存的值的类型。


时间复杂度:
    O(1)
返回值:
    none(key不存在) int(0)
    string(字符串) int(1)
    list(列表) int(3)
    set(集合) int(2)
    zset(有序集) int(4)
    hash(哈希表) int(5)


 








//TYPE
$redis->flushALL();
echo '<br><br>TYPE<br>';


var_dump($redis->TYPE('fake_key')); //none /int(0)


$redis->SET('weather',"sunny");  # 构建一个字符串
var_dump($redis->TYPE('weather'));//string / int(1)


$redis->SADD('pat',"dog");  # 构建一个集合
var_dump($redis->TYPE('pat')); //set /int(2)


$redis->LPUSH('book_list',"programming in scala");  # 构建一个列表
var_dump($redis->TYPE('book_list'));//list / int(3) 


$redis->ZADD('pats',1,'cat');  # 构建一个zset (sorted set) // int(1)
$redis->ZADD('pats',2,'dog');
$redis->ZADD('pats',3,'pig');
var_dump($redis->zRange('pats',0,-1)); // array(3) { [0]=> string(3) "cat" [1]=> string(3) "dog" [2]=> string(3) "pig" }
var_dump($redis->TYPE('pats')); //zset / int(4)


$redis->HSET('website','google','www.g.cn');   # 一个新域
var_dump($redis->HGET('website','google')); //string(8) "www.g.cn"
var_dump($redis->TYPE('website')); //hash /int(5)










EXPIRE


EXPIRE key seconds


为给定key设置生存时间。


当key过期时,它会被自己主动删除。


在Redis中,带有生存时间的key被称作“易失的”(volatile)。


 
在低于2.1.3版本号的Redis中,已存在的生存时间不可覆盖。
从2.1.3版本号開始,key的生存时间能够被更新,也能够被PERSIST命令移除。(详情參见 http://redis.io/topics/expire)。


 


时间复杂度:
    O(1)
返回值:
    设置成功返回1。
    当key不存在或者不能为key设置生存时间时(比方在低于2.1.3中你尝试更新key的生存时间),返回0。










//EXPIRE
$redis->select(7);
//$redis->flushdb();


echo '<br><br>EXPIRE<br>';
$redis->SET('cache_page',"www.cnblogs.com/ikodota");
$redis->EXPIRE('cache_page', 30);  # 设置30秒后过期
sleep(6);
echo $redis->TTL('cache_page').'<br>';   # 查看给定key的剩余生存时间 //(integer) 24


$redis->EXPIRE('cache_page', 3000);  # 更新生存时间,3000秒
sleep(4);
echo $redis->TTL('cache_page').'<br>';   //(integer) 2996










 


 


EXPIREAT 
EXPIREAT key timestamp


EXPIREAT的作用和EXPIRE一样,都用于为key设置生存时间。


不同在于EXPIREAT命令接受的时间參数是UNIX时间戳(unix timestamp)。


时间复杂度:
    O(1)
返回值:
    假设生存时间设置成功,返回1。
    当key不存在或没办法设置生存时间,返回0。


 






//EXPIREAT
echo '<br><br>EXPIREAT<br>';
$redis->SET('cache','www.google.com');
echo $redis->EXPIREAT('cache','1355292000'); # 这个key将在2012.12.12过期


echo ($redis->TTL('cache')); //return 124345085








 


OBJECT 
OBJECT subcommand [arguments [arguments]]


OBJECT命令同意从内部察看给定key的Redis对象。
它通经常使用在除错(debugging)或者了解为了节省空间而对key使用特殊编码的情况。
当将Redis用作缓存程序时,你也能够通过OBJECT命令中的信息,决定key的驱赶策略(eviction policies)。


OBJECT命令有多个子命令:


    OBJECT REFCOUNT <key>返回给定key引用所储存的值的次数。此命令主要用于除错。
    OBJECT ENCODING <key>返回给定key锁储存的值所使用的内部表示(representation)。
    OBJECT IDLETIME <key>返回给定key自储存以来的空转时间(idle, 没有被读取也没有被写入),以秒为单位。


对象能够以多种方式编码:


    字符串能够被编码为raw(一般字符串)或int(用字符串表示64位数字是为了节约空间)。
    列表能够被编码为ziplist或linkedlist。ziplist是为节约大小较小的列表空间而作的特殊表示。
    集合能够被编码为intset或者hashtable。intset是仅仅储存数字的小集合的特殊表示。
    哈希表能够编码为zipmap或者hashtable。zipmap是小哈希表的特殊表示。
    有序集合能够被编码为ziplist或者skiplist格式。ziplist用于表示小的有序集合,而skiplist则用于表示不论什么大小的有序集合。


假如你做了什么让Redis没办法再使用节省空间的编码时(比方将一个仅仅有1个元素的集合扩展为一个有100万个元素的集合),特殊编码类型(specially encoded types)会自己主动转换成通用类型(general type)。


时间复杂度:
    O(1)
返回值:
    REFCOUNT和IDLETIME返回数字。
    ENCODING返回对应的编码类型。










//OBJECT
$redis->select(8);
echo '<br><br>OBJECT<br>';
$redis->SET('game',"WOW");  # 设置一个字符串
$redis->OBJECT('REFCOUNT','game');  # 仅仅有一个引用


//sleep(5);
echo $redis->OBJECT('IDLETIME','game');  # 等待一阵。。。然后查看空转时间 //(integer) 10
//echo $redis->GET('game');  # 提取game, 让它处于活跃(active)状态  //return WOW
//echo $redis->OBJECT('IDLETIME','game');  # 不再处于空转 //(integer) 0
var_dump($redis->OBJECT('ENCODING','game'));  # 字符串的编码方式 //string(3) "raw"
$redis->SET('phone',15820123123);  # 大的数字也被编码为字符串
var_dump($redis->OBJECT('ENCODING','phone')); //string(3) "raw"
$redis->SET('age',20);  # 短数字被编码为int
var_dump($redis->OBJECT('ENCODING','age')); //string(3) "int"










 


PERSIST 
PERSIST key


 


移除给定key的生存时间。


 


时间复杂度:
    O(1)
返回值:
    当生存时间移除成功时,返回1.
    假设key不存在或key没有设置生存时间,返回0。


 








//PERSIST
echo '<br><br>PERSIST<br>';
$redis->SET('time_to_say_goodbye',"886...");
$redis->EXPIRE('time_to_say_goodbye', 300);
sleep(3);
echo $redis->TTL('time_to_say_goodbye'); # (int) 297
echo '<br>';


$redis->PERSIST('time_to_say_goodbye');  # 移除生存时间
echo $redis->TTL('time_to_say_goodbye');  # 移除成功  //int(-1)












SORT


 


SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern ...]] [ASC | DESC] [ALPHA] [STORE destination]


排序,分页等
參数


array(
‘by’ => ‘some_pattern_*’,
‘limit’ => array(0, 1),
‘get’ => ‘some_other_pattern_*’ or an array of patterns,
‘sort’ => ‘asc’ or ‘desc’,
‘alpha’ => TRUE,
‘store’ => ‘external-key’
)


返回或保存给定列表、集合、有序集合key中经过排序的元素。


排序默认以数字作为对象,值被解释为双精度浮点数,然后进行比較。


 


一般SORT使用方法


最简单的SORT用法是SORT key。


如果today_cost是一个保存数字的列表,SORT命令默认会返回该列表值的递增(从小到大)排序结果。


 








# 将数据一一增加到列表中
$redis->LPUSH('today_cost', 30);
$redis->LPUSH('today_cost', 1.5);
$redis->LPUSH('today_cost', 10);
$redis->LPUSH('today_cost', 8);
# 排序
var_dump($redis->SORT('today_cost')); //array(4) { [0]=> string(3) "1.5" [1]=> string(1) "8" [2]=> string(2) "10" [3]=> string(2) "30" }










当数据集中保存的是字符串值时,你能够用ALPHA修饰符(modifier)进行排序。








# 将数据一一增加到列表中
$redis->LPUSH('website', "www.reddit.com");
$redis->LPUSH('website', "www.slashdot.com");
$redis->LPUSH('website', "www.infoq.com");
# 默认排序
var_dump($redis->SORT('website'));//array(3) { [0]=> string(13) "www.infoq.com" [1]=> string(16) "www.slashdot.com" [2]=> string(14) "www.reddit.com" }


# 按字符排序 ALPHA=true
var_dump($redis->SORT('website', array('ALPHA'=>TRUE))); //array(3) { [0]=> string(13) "www.infoq.com" [1]=> string(14) "www.reddit.com" [2]=> string(16) "www.slashdot.com" }










假设你正确设置了!LC_COLLATE环境变量的话,Redis能识别UTF-8编码。
排序之后返回的元素数量能够通过LIMIT修饰符进行限制。
LIMIT修饰符接受两个參数:offset和count。
offset指定要跳过的元素数量,count指定跳过offset个指定的元素之后,要返回多少个对象。


下面样例返回排序结果的前5个对象(offset为0表示没有元素被跳过)。








# 将数据一一增加到列表中
$redis->LPUSH('rank', 30); //(integer) 1
$redis->LPUSH('rank', 56); //(integer) 2
$redis->LPUSH('rank', 42); //(integer) 3
$redis->LPUSH('rank', 22); //(integer) 4
$redis->LPUSH('rank', 0);  //(integer) 5
$redis->LPUSH('rank', 11); //(integer) 6
$redis->LPUSH('rank', 32); //(integer) 7
$redis->LPUSH('rank', 67); //(integer) 8
$redis->LPUSH('rank', 50); //(integer) 9
$redis->LPUSH('rank', 44); //(integer) 10
$redis->LPUSH('rank', 55); //(integer) 11


# 排序
$redis_sort_option=array('LIMIT'=>array(0,5));
var_dump($redis->SORT('rank',$redis_sort_option));   # 返回排名前五的元素 // array(5) { [0]=> string(1) "0" [1]=> string(2) "11" [2]=> string(2) "22" [3]=> string(2) "30" [4]=> string(2) "32" }










修饰符能够组合使用。下面样例返回降序(从大到小)的前5个对象。






$redis_sort_option=array(
            'LIMIT'=>array(0,5),
            'SORT'=>'DESC'
            );
var_dump($redis->SORT('rank',$redis_sort_option)); //array(5) { [0]=> string(2) "67" [1]=> string(2) "56" [2]=> string(2) "55" [3]=> string(2) "50" [4]=> string(2) "44" }








 


使用外部key进行排序


有时候你会希望使用外部的key作为权重来比較元素,取代默认的对例如法。


如果如今实用户(user)数据例如以下:


id     name    level
-------------------------------
1    admin     9999
2    huangz   10
59230  jack        3
222    hacker      9999


id数据保存在key名为user_id的列表中。
name数据保存在key名为user_name_{id}的列表中
level数据保存在user_level_{id}的key中。








# 先将要使用的数据增加到数据库中


# admin
$redis->LPUSH('user_id', 1);//(integer) 1
$redis->SET('user_name_1', 'admin');
$redis->SET('user_level_1',9999);


# huangz
$redis->LPUSH('user_id', 2);//(integer) 2
$redis->SET('user_name_2', 'huangz');
$redis->SET('user_level_2', 10);


# jack
$redis->LPUSH('user_id', 59230);//(integer) 3
$redis->SET('user_name_59230','jack');
$redis->SET('user_level_59230', 3);


# hacker
$redis->LPUSH('user_id', 222);  //(integer) 4
$redis->SET('user_name_222', 'hacker');
$redis->SET('user_level_222', 9999);










 


假设希望按level从大到小排序user_id,能够使用下面命令:








$redis_sort_option=array('BY'=>'user_level_*',
            'SORT'=>'DESC'
            );
var_dump($redis->SORT('user_id',$redis_sort_option)); //array(4) { [0]=> string(3) "222" [1]=> string(1) "1" [2]=> string(1) "2" [3]=> string(5) "59230" }


#---------------------------
#1) "222"    # hacker
#2) "1"      # admin
#3) "2"      # huangz
#4) "59230"  # jack










可是有时候仅仅是返回相应的id没有什么用,你可能更希望排序后返回id相应的username,这样更友好一点,使用GET选项能够做到这一点:


 








$redis_sort_option=array('BY'=>'user_level_*',
            'SORT'=>'DESC',
            'GET'=>'user_name_*'
            );
var_dump($redis->SORT('user_id', $redis_sort_option)); //array(4) { [0]=> string(6) "hacker" [1]=> string(5) "admin" [2]=> string(6) "huangz" [3]=> string(4) "jack" }


#1) "hacker"
#2) "admin"
#3) "huangz"
#4) "jack"










能够多次地、有序地使用GET操作来获取很多其它外部key。


比方你不但希望获取username,还希望连用户的password也一并列出,能够使用下面命令:


 








# 先加入一些測试数据
$redis->SET('user_password_222', "hey,im in");
$redis->SET('user_password_1', "a_long_long_password");
$redis->SET('user_password_2', "nobodyknows");
$redis->SET('user_password_59230', "jack201022");


# 获取name和password
$redis_sort_option=array('BY'=>'user_level_*',
            'SORT'=>'DESC',
            'GET'=>array('user_name_*','user_password_*')
            );
var_dump($redis->SORT('user_id',$redis_sort_option));//array(8) { [0]=> string(6) "hacker" [1]=> string(9) "hey,im in" [2]=> string(5) "admin" [3]=> string(20) "a_long_long_password" [4]=> string(6) "huangz" [5]=> string(11) "nobodyknows" [6]=> string(4) "jack" [7]=> string(10) "jack201022" }


#------------------------------------
#1) "hacker"       # username
#2) "hey,im in"    # password
#3) "jack"
#4) "jack201022"
#5) "huangz"
#6) "nobodyknows"
#7) "admin"
#8) "a_long_long_password"










# 注意GET操作是有序的,GET user_name_* GET user_password_* 和 GET user_password_* GET user_name_*返回的结果位置不同


 








# 获取name和password 注意GET操作是有序的
$redis_sort_option=array('BY'=>'user_level_*',
            'SORT'=>'DESC',
            'GET'=>array('user_password_*','user_name_*')
            );
var_dump($redis->SORT('user_id',$redis_sort_option));// array(8) { [0]=> string(9) "hey,im in" [1]=> string(6) "hacker" [2]=> string(20) "a_long_long_password" [3]=> string(5) "admin" [4]=> string(11) "nobodyknows" [5]=> string(6) "huangz" [6]=> string(10) "jack201022" [7]=> string(4) "jack" }










GET另一个特殊的规则——"GET #",用于获取被排序对象(我们这里的样例是user_id)的当前元素。


比方你希望user_id按level排序,还要列出id、name和password,能够使用下面命令:


 








$redis_sort_option=array('BY'=>'user_level_*',
            'SORT'=>'DESC',
            'GET'=>array('#','user_password_*','user_name_*')
            );
var_dump($redis->SORT('user_id',$redis_sort_option));//array(12) { [0]=> string(3) "222" [1]=> string(9) "hey,im in" [2]=> string(6) "hacker" [3]=> string(1) "1" [4]=> string(20) "a_long_long_password" [5]=> string(5) "admin" [6]=> string(1) "2" [7]=> string(11) "nobodyknows" [8]=> string(6) "huangz" [9]=> string(5) "59230" [10]=> string(10) "jack201022" [11]=> string(4) "jack" }


#--------------------------------------------------------------
#1) "222"          # id
#2) "hacker"       # name
#3) "hey,im in"    # password
#4) "1"
#5) "admin"
#6) "a_long_long_password"
#7) "2"
#8) "huangz"
#9) "nobodyknows"
#10) "59230"
#11) "jack"
#12) "jack201022"










仅仅获取对象而不排序


BY修饰符能够将一个不存在的key当作权重,让SORT跳过排序操作。


该方法用于你希望获取外部对象而又不希望引起排序开销时使用。


 








# 确保fake_key不存在
$redis->EXISTS('fake_key');//(integer) 0


# 以fake_key作BY參数,不排序,仅仅GET name 和 GET password
$redis_sort_option=array('BY'=>'fake_key',
            'SORT'=>'DESC',
            'GET'=>array('#','user_name_*','user_password_*')
            );
var_dump($redis->SORT('user_id',$redis_sort_option));//array(12) { [0]=> string(3) "222" [1]=> string(6) "hacker" [2]=> string(9) "hey,im in" [3]=> string(5) "59230" [4]=> string(4) "jack" [5]=> string(10) "jack201022" [6]=> string(1) "2" [7]=> string(6) "huangz" [8]=> string(11) "nobodyknows" [9]=> string(1) "1" [10]=> string(5) "admin" [11]=> string(20) "a_long_long_password" }


#----------------------------------------------
#1) "222"        # id
#2) "hacker"     # user_name
#3) "hey,im in"  # password
#4) "59230"
#5) "jack"
#6) "jack201022"
#7) "2"
#8) "huangz"
#9) "nobodyknows"
#10) "1"
#11) "admin"
#12) "a_long_long_password"










保存排序结果


默认情况下,SORT操作仅仅是简单地返回排序结果,假设你希望保存排序结果,能够给STORE选项指定一个key作为參数,排序结果将以列表的形式被保存到这个key上。(若指定key已存在,则覆盖。)








$redis->EXISTS('user_info_sorted_by_level');  # 确保指定key不存在   //(integer) 0
$redis_sort_option=array('BY'=>'user_level_*',
            'GET'=>array('#','user_name_*','user_password_*'),
            'STORE'=>'user_info_sorted_by_level'
            );


var_dump($redis->SORT('user_id',$redis_sort_option)); //int(12)
var_dump($redis->LRANGE('user_info_sorted_by_level', 0 ,11));  # 查看排序结果  //array(12) { [0]=> string(5) "59230" [1]=> string(4) "jack" [2]=> string(10) "jack201022" [3]=> string(1) "2" [4]=> string(6) "huangz" [5]=> string(11) "nobodyknows" [6]=> string(3) "222" [7]=> string(6) "hacker" [8]=> string(9) "hey,im in" [9]=> string(1) "1" [10]=> string(5) "admin" [11]=> string(20) "a_long_long_password" }


#-----------------------------------------------------------------
#1) "59230"
#2) "jack"
#3) "jack201022"
#4) "2"
#5) "huangz"
#6) "nobodyknows"
#7) "222"
#8) "hacker"
#9) "hey,im in"
#10) "1"
#11) "admin"
#12) "a_long_long_password"










一个有趣的使用方法是将SORT结果保存,用EXPIRE为结果集设置生存时间,这样结果集就成了SORT操作的一个缓存。


这样就不必频繁地调用SORT操作了,仅仅有当结果集过期时,才须要再调用一次SORT操作。


有时候为了正确实现这一使用方法,你可能须要加锁以避免多个client同一时候进行缓存重建(也就是多个client,同一时间进行SORT操作,并保存为结果集),详细參见SETNX命令。


在GET和BY中使用哈希表


能够使用哈希表特有的语法,在SORT命令中进行GET和BY操作。








# 如果如今我们的用户表新增了一个serial项来为作为每一个用户的序列号
# 序列号以哈希表的形式保存在serial哈希域内。


$redis_hash_testdata_array=array(1=>'23131283',
                2=>'23810573',
                222=>'502342349',
                59230=>'2435829758'
                );


$redis->HMSET('serial',$redis_hash_testdata_array);


# 我们希望以比較serial中的大小来作为排序user_id的方式
$redis_sort_option=array('BY'=>'*->serial');
var_dump($redis->SORT('user_id', $redis_sort_option)); //array(4) { [0]=> string(3) "222" [1]=> string(5) "59230" [2]=> string(1) "2" [3]=> string(1) "1" }


#----------------------------------------
#1) "222"
#2) "59230"
#3) "2"
#4) "1"










 


符号"->"用于切割哈希表的keyword(key name)和索引域(hash field),格式为"key->field"。


除此之外,哈希表的BY和GET操作和上面介绍的其它数据结构(列表、集合、有序集合)没有什么不同。


时间复杂度:
    O(N+M*log(M)),N为要排序的列表或集合内的元素数量,M为要返回的元素数量。
    假设仅仅是使用SORT命令的GET选项获取数据而没有进行排序,时间复杂度O(N)。
返回值:
    没有使用STORE參数,返回列表形式的排序结果。
    使用STORE參数,返回排序结果的元素数量。


 
字符串(String)


SET


SET key value


将字符串值value关联到key。


假设key已经持有其它值,SET就覆写旧值,无视类型。




时间复杂度:O(1)返回值:总是返回OK(TRUE),由于SET不可能失败。








# 情况1:对字符串类型的key进行SET
$redis->SET('apple', 'www.apple.com');#OK  //bool(true)
$redis->GET('apple');//"www.apple.com"


# 情况2:对非字符串类型的key进行SET
$redis->LPUSH('greet_list', "hello");  # 建立一个列表 #(integer) 1 //int(1)
$redis->TYPE('greet_list');#list //int(3)


$redis->SET('greet_list', "yooooooooooooooooo");   # 覆盖列表类型 #OK //bool(true)
$redis->TYPE('greet_list');#string //int(1)










 
SETNX


SETNX key value


将key的值设为value,当且仅当key不存在。


若给定的key已经存在,则SETNX不做不论什么动作。


SETNX是”SET if Not eXists”(假设不存在,则SET)的简写。


时间复杂度:
    O(1)
返回值:
    设置成功,返回1。
    设置失败,返回0。








//SETNX
echo '<br><br>SETNX<br>';
$redis->EXISTS('job');  # job不存在 //bool(false);
$redis->SETNX('job', "programmer");  # job设置成功 //bool(true)
$redis->SETNX('job', "code-farmer");  # job设置失败 //bool(false)
echo $redis->GET('job');  # 没有被覆盖 //"programmer"








设计模式(Design pattern): 将SETNX用于加锁(locking)


SETNX能够用作加锁原语(locking primitive)。比方说,要对keyword(key)foo加锁,client能够尝试下面方式:


SETNX lock.foo <current Unix time + lock timeout + 1>


假设SETNX返回1,说明client已经获得了锁,key设置的unix时间则指定了锁失效的时间。之后client能够通过DEL lock.foo来释放锁。


假设SETNX返回0,说明key已经被其它client上锁了。假设锁是非堵塞(non blocking lock)的,我们能够选择返回调用,或者进入一个重试循环,直到成功获得锁或重试超时(timeout)。


处理死锁(deadlock)


上面的锁算法有一个问题:假设由于client失败、崩溃或其它原因导致没有办法释放锁的话,怎么办?


这样的状况能够通过检測发现——由于上锁的key保存的是unix时间戳,假如key值的时间戳小于当前的时间戳,表示锁已经不再有效。


可是,当有多个client同一时候检測一个锁是否过期并尝试释放它的时候,我们不能简单粗暴地删除死锁的key,再用SETNX上锁,由于这时竞争条件(race condition)已经形成了:


    C1和C2读取lock.foo并检查时间戳,SETNX都返回0,由于它已经被C3锁上了,但C3在上锁之后就崩溃(crashed)了。
    C1向lock.foo发送DEL命令。
    C1向lock.foo发送SETNX并成功。
    C2向lock.foo发送DEL命令。
    C2向lock.foo发送SETNX并成功。
    出错:由于竞争条件的关系,C1和C2两个都获得了锁。


幸好,下面算法能够避免以上问题。来看看我们聪明的C4client怎么办:


    C4向lock.foo发送SETNX命令。
    由于崩溃掉的C3还锁着lock.foo,所以Redis向C4返回0。
    C4向lock.foo发送GET命令,查看lock.foo的锁是否过期。假设不,则休眠(sleep)一段时间,并在之后重试。
    还有一方面,假设lock.foo内的unix时间戳比当前时间戳老,C4运行下面命令:


GETSET lock.foo <current Unix timestamp + lock timeout + 1>


    由于GETSET的作用,C4能够检查看GETSET的返回值,确定lock.foo之前储存的旧值仍是那个过期时间戳,假设是的话,那么C4获得锁。
    假设其它client,比方C5,比C4更快地运行了GETSET操作并获得锁,那么C4的GETSET操作返回的就是一个未过期的时间戳(C5设置的时间戳)。C4仅仅好从第一步開始重试。


注意,即便C4的GETSET操作对key进行了改动,这对未来也没什么影响。
(这里是不是有点问题?C4的确是能够重试,但C5怎么办?它的锁的过期被C4改动了。——译注)


     警告


    为了让这个加锁算法更健壮,获得锁的client应该经常检查过期时间以免锁因诸如DEL等命令的运行而被意外解开,由于client失败的情况很复杂,不不过崩溃这么简单,还可能是client由于某些操作被堵塞了相当长时间,紧接着DEL命令被尝试运行(但这时锁却在另外的client手上)。


 


SETEX
SETEX key seconds value


将值value关联到key,并将key的生存时间设为seconds(以秒为单位)。


假设key 已经存在,SETEX命令将覆写旧值。


这个命令类似于下面两个命令:


$redis->SET('key', 'value');
$redis->EXPIRE('key','seconds');  # 设置生存时间 


不同之处是,SETEX是一个原子性(atomic)操作,关联值和设置生存时间两个动作会在同一时间内完毕,该命令在Redis用作缓存时,很有用。


时间复杂度:
    O(1)
返回值:
    设置成功时返回OK。
    当seconds參数不合法时,返回一个错误。










# 情况1:key不存在
$redis->SETEX('cache_user_id', 60,10086);//bool(true)
echo $redis->GET('cache_user_id');  # 值 //"10086"


sleep(4);
echo $redis->TTL('cache_user_id');  # 剩余生存时间 //int(56)


# 情况2:key已经存在,key被覆写
$redis->SET('cd', "timeless"); //bool(true);
$redis->SETEX('cd', 3000,"goodbye my love"); //bool(true);
echo $redis->GET('cd');//"goodbye my love"










 


SETRANGE


SETRANGE key offset value


用value參数覆写(Overwrite)给定key所储存的字符串值,从偏移量offset開始。


不存在的key当作空白字符串处理。


SETRANGE命令会确保字符串足够长以便将value设置在指定的偏移量上,假设给定key原来储存的字符串长度比偏移量小(比方字符串仅仅有5个字符长,但你设置的offset是10),那么原字符和偏移量之间的空白将用零比特(zerobytes,"\x00")来填充。


注意你能使用的最大偏移量是2^29-1(536870911),由于Redis的字符串被限制在512兆(megabytes)内。假设你须要使用比这更大的空间,你得使用多个key。


时间复杂度:
    对小(small)的字符串,平摊复杂度O(1)。(关于什么字符串是”小”的,请參考APPEND命令)
    否则为O(M),M为value參数的长度。
返回值:
    被SETRANGE改动之后,字符串的长度。


     警告


     当生成一个非常长的字符串时,Redis须要分配内存空 间,该操作有时候可能会造成server堵塞(block)。在2010年的Macbook Pro上,设置偏移量为536870911(512MB内存分配),耗费约300毫秒, 设置偏移量为134217728(128MB内存分配),耗费约80毫秒,设置偏移量33554432(32MB内存分配),耗费约30毫秒,设置偏移量 为8388608(8MB内存分配),耗费约8毫秒。 注意若首次内存分配成功之后,再对同一个key调用SETRANGE操作,无须再又一次内存。


模式


由于有了SETRANGE和GETRANGE命令,你能够将Redis字符串用作具有O(1)随机訪问时间的线性数组。这在非常多真有用例中都是非常高速且高效的储存方式。








# 情况1:对非空字符串进行SETRANGE
$redis->SET('greeting', "hello world");
$redis->SETRANGE('greeting', 6, "Redis"); //int(11)
$redis->GET('greeting');//"hello Redis"


# 情况2:对空字符串/不存在的key进行SETRANGE
$redis->EXISTS('empty_string');//bool(false)
$redis->SETRANGE('empty_string', 5 ,"Redis!");  # 对不存在的key使用SETRANGE //int(11)
var_dump($redis->GET('empty_string'));  # 空白处被"\x00"填充  #"\x00\x00\x00\x00\x00Redis!"   //return string(11) "Redis!"










MSET 
MSET key value [key value ...]


同一时候设置一个或多个key-value对。


当发现同名的key存在时,MSET会用新值覆盖旧值,假设你不希望覆盖同名key,请使用MSETNX命令。


MSET是一个原子性(atomic)操作,全部给定key都在同一时间内被设置,某些给定key被更新而还有一些给定key没有改变的情况,不可能发生。


时间复杂度:
    O(N),N为要设置的key数量。
返回值:
    总是返回OK(由于MSET不可能失败)










#MSET
echo '<br><br>MSET<br>';
$redis->select(0);
$redis->flushdb();
$array_mset=array('date'=>'2012.3.5',
        'time'=>'9.09a.m.',
        'weather'=>'sunny'
        );
$redis->MSET($array_mset); //bool(true)


var_dump($redis->KEYS('*'));   # 确保指定的三个key-value对被插入 //array(3) { [0]=> string(4) "time" [1]=> string(7) "weather" [2]=> string(4) "date" }


# MSET覆盖旧值的样例 可是经过測试覆盖不了
var_dump($redis->SET('google', "google.cn"));   //bool(true)
var_dump($redis->MSET('google',"google.hk")); //bool(false)
echo $redis->GET('google'); //google.cn  与redis手冊的演示样例结果不符










 
MSETNX


MSETNX key value [key value ...]


同一时候设置一个或多个key-value对,当且仅当key不存在。


即使仅仅有一个key已存在,MSETNX也会拒绝全部传入key的设置操作


MSETNX是原子性的,因此它能够用作设置多个不同key表示不同字段(field)的唯一性逻辑对象(unique logic object),全部字段要么全被设置,要么全不被设置。


时间复杂度:
    O(N),N为要设置的key的数量。
返回值:
    当全部key都成功设置,返回1。
    假设全部key都设置失败(最少有一个key已经存在),那么返回0。










# 情况1:对不存在的key进行MSETNX
$array_mset=array('rmdbs'=>'MySQL',
        'nosql'=>'MongoDB',
        'key-value-store'=>'redis'
        );
$redis->MSETNX($array_mset);//bool(true)




# 情况2:对已存在的key进行MSETNX
$array_mset=array('rmdbs'=>'Sqlite',
        'language'=>'python'
        );
var_dump($redis->MSETNX($array_mset));  # rmdbs键已经存在,操作失败 //bool(false)
var_dump($redis->EXISTS('language'));  # 由于操作是原子性的,language没有被设置  bool(false)


echo $redis->GET('rmdbs');  # rmdbs没有被改动 //"MySQL"


$array_mset_keys=array( 'rmdbs', 'nosql', 'key-value-store');
print_r($redis->MGET($array_mset_keys)); //Array ( [0] => MySQL [1] => MongoDB [2] => redis )










 
APPEND


APPEND key value


假设key已经存在而且是一个字符串,APPEND命令将value追加到key原来的值之后。


假设key不存在,APPEND就简单地将给定key设为value,就像运行SET key value一样。


时间复杂度:
    平摊复杂度O(1)
返回值:
    追加value之后,key中字符串的长度。










# 情况1:对不存在的key运行APPEND


$redis->EXISTS('myphone');  # 确保myphone不存在 //bool(false)
$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"








GET


GET key


返回key所关联的字符串值。


假设key不存在则返回特殊值nil。


假如key储存的值不是字符串类型,返回一个错误,由于GET仅仅能用于处理字符串值。


时间复杂度:
    O(1)
返回值:
    key的值。
    假设key不存在,返回nil。


 


//GET
var_dump($redis->GET('fake_key')); #(nil) //return bool(false)
$redis->SET('animate', "anohana"); //return bool(true)
var_dump($redis->GET('animate')); //return string(7) "anohana"


 
MGET


MGET key [key ...]


返回全部(一个或多个)给定key的值。


假设某个指定key不存在,那么返回特殊值nil。因此,该命令永不失败。


时间复杂度:
    O(1)
返回值:
    一个包括全部给定key的值的列表。










//MGET
echo '<br><br>MGET<br>';
$redis_mget_data_array=array('name'=>'ikodota','blog'=>'cnblogs.com/ikodota');
$redis->MSET($redis_mget_data_array);#用MSET一次储存多个值 


$redis_mget_key_array=array('name','blog');
var_dump($redis->MGET($redis_mget_key_array)); //array(2) { [0]=> string(7) "ikodota" [1]=> string(19) "cnblogs.com/ikodota" }


$redis->EXISTS('fake_key'); //bool(false)


$redis_mget_key_array=array('name','fake_key');
var_dump($redis->MGET($redis_mget_key_array));  # 当MGET中有不存在key的情况   //array(2) { [0]=> string(7) "ikodota" [1]=> bool(false) }








GETRANGE


GETRANGE key start end


返回key中字符串值的子字符串,字符串的截取范围由start和end两个偏移量决定(包含start和end在内)。


负数偏移量表示从字符串最后開始计数,-1表示最后一个字符,-2表示倒数第二个,以此类推。


GETRANGE通过保证子字符串的值域(range)不超过实际字符串的值域来处理超出范围的值域请求。


时间复杂度:
    O(N),N为要返回的字符串的长度。
    复杂度终于由返回值长度决定,但由于从已有字符串中建立子字符串的操作很便宜(cheap),所以对于长度不大的字符串,该操作的复杂度也可看作O(1)。
返回值:
    截取得出的子字符串。


    注解:在<=2.0的版本号里,GETRANGE被叫作SUBSTR。










//GETRANGE
echo '<br><br>GETRANGE<br>';
$redis->SET('greeting', "hello, my friend");
echo $redis->GETRANGE('greeting', 0, 4).'<br>';  # 返回索引0-4的字符,包含4。 //"hello"
echo $redis->GETRANGE('greeting', -1 ,-5).'<br>';  # 不支持回绕操作  //""
echo $redis->GETRANGE('greeting', -3 ,-1).'<br>';  # 负数索引 //"end"
echo $redis->GETRANGE('greeting', 0, -1).'<br>';  # 从第一个到最后一个 //"hello, my friend"
echo $redis->GETRANGE('greeting', 0, 1008611).'<br>';  # 值域范围不超过实际字符串,超过部分自己主动被符略 //"hello, my friend"










 
GETSET


GETSET key value


将给定key的值设为value,并返回key的旧值。


当key存在但不是字符串类型时,返回一个错误。


时间复杂度:
    O(1)
返回值:
    返回给定key的旧值(old value)。
    当key没有旧值时,返回nil。








//GETSET
echo '<br><br>GETSET<br>';
var_dump($redis->EXISTS('mail'));//return bool(false);
var_dump($redis->GETSET('mail','xxx@google.com'));  # 由于mail之前不存在,没有旧值,返回nil ,#(nil)   //bool(false)


var_dump($redis->GETSET('mail','xxx@yahoo.com'));  # mail被更新,旧值被返回 //string(14) "xxx@google.com"








设计模式


GETSET能够和INCR组合使用,实现一个有原子性(atomic)复位操作的计数器(counter)。


举例来说,每次当某个事件发生时,进程可能对一个名为mycount的key调用INCR操作,通常我们还要在一个原子时间内同一时候完毕获得计数器的值和将计数器值复位为0两个操作。


能够用命令GETSET mycounter 0来实现这一目标。








$redis->SELECT(2);
echo $redis->INCR('mycount').'<br>'; #(integer) 11


if($redis->GET('mycount')>19){
    echo $redis->GETSET('mycount', 0).'<br>';  # 一个原子内完毕GET mycount和SET mycount 0操作 #"11" 
}
echo $redis->GET('mycount'); #"0"










 
STRLEN


STRLEN key


返回key所储存的字符串值的长度。


当key储存的不是字符串值时,返回一个错误。


复杂度:
    O(1)
返回值:
    字符串值的长度。
    当 key不存在时,返回0。


$redis->SET('mykey', "Hello world");
echo $redis->STRLEN('mykey'); //int(11)
echo $redis->STRLEN('nonexisting'); # 不存在的key长度视为0  //int(0)


INCR


INCR key


将key中储存的数字值增一。


假设key不存在,以0为key的初始值,然后运行INCR操作。


假设值包括错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。


本操作的值限制在64位(bit)有符号数字表示之内。


时间复杂度:
    O(1)
返回值:
    运行INCR命令之后key的值。


    注解:这是一个针对字符串的操作,由于Redis没有专用的整数类型,所以key内储存的字符串被解释为十进制64位有符号整数来运行INCR操作。


$redis->SET('page_view', 20);
var_dump($redis->INCR('page_view')); //int(21) 
var_dump($redis->GET('page_view'));    # 数字值在Redis中以字符串的形式保存 //string(2) "21




INCRBY


INCRBY key increment


将key所储存的值加上增量increment。


假设key不存在,以0为key的初始值,然后运行INCRBY命令。


假设值包括错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。


本操作的值限制在64位(bit)有符号数字表示之内。


关于很多其它递增(increment)/递减(decrement)操作信息,參见INCR命令。


时间复杂度:
    O(1)
返回值:
    加上increment之后,key的值。










//INCRBY
echo '<br><br>INCRBY<br>';
# 情况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'); #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)










 
DECR


DECR key


将key中储存的数字值减一。


假设key不存在,以0为key的初始值,然后运行DECR操作。


假设值包括错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。


本操作的值限制在64位(bit)有符号数字表示之内。


关于很多其它递增(increment)/递减(decrement)操作信息,參见INCR命令。


时间复杂度:
    O(1)
返回值:
    运行DECR命令之后key的值。










//DECR
$redis->SELECT(3);
$redis->flushdb();
echo '<br><br>DECR<br>';
# 情况1:对存在的数字值key进行DECR
$redis->SET('failure_times', 10);
$redis->DECR('failure_times'); //int(9)
echo $redis->GET('failure_times').'<br>';  //string(1) "9"


# 情况2:对不存在的key值进行DECR
$redis->EXISTS('count'); #(integer) 0 //bool(false)
$redis->DECR('count');  //int(-1) 
echo $redis->GET('count').'<br>'; //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').'<br>'; //YOUR_CODE_SUCKS.LLC










 
DECRBY


DECRBY key decrement


将key所储存的值减去减量decrement。


假设key不存在,以0为key的初始值,然后运行DECRBY操作。


假设值包括错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。


本操作的值限制在64位(bit)有符号数字表示之内。


关于很多其它递增(increment)/递减(decrement)操作信息,參见INCR命令。


时间复杂度:
    O(1)
返回值:
    减去decrement之后,key的值。










# 情况1:对存在的数值key进行DECRBY
$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


SETBIT key offset value


对key所储存的字符串值,设置或清除指定偏移量上的位(bit)。


位的设置或清除取决于value參数,能够是0也能够是1。


当key不存在时,自己主动生成一个新的字符串值。


字符串会增长(grown)以确保它能够将value保存在指定的偏移量上。当字符串值增长时,空白位置以0填充。


offset參数必须大于或等于0,小于2^32(bit映射被限制在512MB内)。


时间复杂度:
    O(1)
返回值:
    指定偏移量原来储存的位("0"或"1").


    警告:对使用大的offset的SETBIT操作来说,内存分配可能造成Redisserver被堵塞。详细參考SETRANGE命令,warning(警告)部分。










//SETBIT
echo '<br><br>SETBIT<br>';
$bit_val=67;
echo decbin($bit_val).'<br>'; //1000011
var_dump($redis->SETBIT('bit',1,1));//int(0)  空位上都是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(0)


var_dump($redis->GET('bit')); //string(1) "C" ,二进制为:1000011 ,ASCII:67


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


var_dump($redis->SETBIT('bit',5,1));//int(0)  把第5位的0改为1
var_dump($redis->SETBIT('bit',6,0));//int(1)  把第6位的1改为0


var_dump($redis->GET('bit')); //string(1) "E ,二进制为:1000101,ASCII:69l














GETBIT


GETBIT key offset


对key所储存的字符串值,获取指定偏移量上的位(bit)。


当offset比字符串值的长度大,或者key不存在时,返回0。


时间复杂度:
    O(1)
返回值:
    字符串值指定偏移量上的位(bit)。


#參见SETBIT的演示样例


 
哈希表(Hash)
HSET


HSET key field value


将哈希表key中的域field的值设为value。


假设key不存在,一个新的哈希表被创建并进行HSET操作。


假设域field已经存在于哈希表中,旧值将被覆盖。


时间复杂度:
    O(1)
返回值:
    假设field是哈希表中的一个新建域,而且值设置成功,返回1。
    假设哈希表中域field已经存在且旧值已被新值覆盖,返回0。


 
HSETNX


HSETNX key field value


将哈希表key中的域field的值设置为value,当且仅当域field不存在。


若域field已经存在,该操作无效。


假设key不存在,一个新哈希表被创建并运行HSETNX命令。


时间复杂度:
    O(1)
返回值:
    设置成功,返回1。
    假设给定域已经存在且没有操作被运行,返回0。


 
HMSET


HMSET key field value [field value ...]


同一时候将多个field - value(域-值)对设置到哈希表key中。


此命令会覆盖哈希表中已存在的域。


假设key不存在,一个空哈希表被创建并运行HMSET操作。


时间复杂度:
    O(N),N为field - value对的数量。
返回值:
    假设命令运行成功,返回OK。
    当key不是哈希表(hash)类型时,返回一个错误。


 


 
HGET


HGET key field


返回哈希表key中给定域field的值。


时间复杂度:
    O(1)
返回值:
    给定域的值。
    当给定域不存在或是给定key不存在时,返回nil。


 
HMGET


HMGET key field [field ...]


返回哈希表key中,一个或多个给定域的值。


假设给定的域不存在于哈希表,那么返回一个nil值。


由于不存在的key被当作一个空哈希表来处理,所以对一个不存在的key进行HMGET操作将返回一个仅仅带有nil值的表。


时间复杂度:
    O(N),N为给定域的数量。
返回值:
    一个包括多个给定域的关联值的表,表值的排列顺序和给定域參数的请求顺序一样。


 


 
HGETALL


HGETALL key


返回哈希表key中,全部的域和值。


在返回值里,紧跟每一个域名(field name)之后是域的值(value),所以返回值的长度是哈希表大小的两倍。


时间复杂度:
    O(N),N为哈希表的大小。
返回值:
    以列表形式返回哈希表的域和域的值。 若key不存在,返回空列表。


 


 
HDEL


HDEL key field [field ...]


删除哈希表key中的一个或多个指定域,不存在的域将被忽略。


时间复杂度:
    O(N),N为要删除的域的数量。
返回值:
    被成功移除的域的数量,不包含被忽略的域。


    注解:在Redis2.4下面的版本号里,HDEL每次仅仅能删除单个域,假设你须要在一个原子时间内删除多个域,请将命令包括在MULTI/ EXEC块内。


 
HLEN


HLEN key


返回哈希表key中域的数量。


时间复杂度:
    O(1)
返回值:
    哈希表中域的数量。
    当key不存在时,返回0。


 
HEXISTS


HEXISTS key field


查看哈希表key中,给定域field是否存在。


时间复杂度:
    O(1)
返回值:
    假设哈希表含有给定域,返回1。
    假设哈希表不含有给定域,或key不存在,返回0。


 
HINCRBY


HINCRBY key field increment


为哈希表key中的域field的值加上增量increment。


增量也能够为负数,相当于对给定域进行减法操作。


假设key不存在,一个新的哈希表被创建并运行HINCRBY命令。


假设域field不存在,那么在运行命令前,域的值被初始化为0。


对一个储存字符串值的域field运行HINCRBY命令将造成一个错误。


本操作的值限制在64位(bit)有符号数字表示之内。


时间复杂度:
    O(1)
返回值:
    运行HINCRBY命令之后,哈希表key中域field的值。


 
HKEYS


HKEYS key


返回哈希表key中的全部域。


时间复杂度:
    O(N),N为哈希表的大小。
返回值:
    一个包括哈希表中全部域的表。
    当key不存在时,返回一个空表。


 
HVALS


HVALS key


返回哈希表key中的全部值。


时间复杂度:
    O(N),N为哈希表的大小。
返回值:
    一个包括哈希表中全部值的表。
    当key不存在时,返回一个空表。


 
表(List)


头元素和尾元素


头元素指的是列表左端/前端第一个元素,尾元素指的是列表右端/后端第一个元素。


举个样例,列表list包括三个元素:x, y, z,当中x是头元素,而z则是尾元素。


空列表


指不包括不论什么元素的列表,Redis将不存在的key也视为空列表。


 
LPUSH


LPUSH key value [value ...]


将一个或多个值value插入到列表key的表头。


假设有多个value值,那么各个value值按从左到右的顺序依次插入到表头:比方对一个空列表(mylist)运行LPUSH mylist a b c,则结果列表为c b a,等同于运行运行命令LPUSH mylist a、LPUSH mylist b、LPUSH mylist c。


假设key不存在,一个空列表会被创建并运行LPUSH操作。


当key存在但不是列表类型时,返回一个错误。


时间复杂度:
    O(1)
返回值:
    运行LPUSH命令后,列表的长度。


 


    注解:在Redis 2.4版本号曾经的LPUSH命令,都仅仅接受单个value值。


 
LPUSHX


LPUSHX key value


将值value插入到列表key的表头,当且仅当key存在而且是一个列表。


和LPUSH命令相反,当key不存在时,LPUSHX命令什么也不做。


时间复杂度:
    O(1)
返回值:
    LPUSHX命令运行之后,表的长度。


 
RPUSH


RPUSH key value [value ...]


将一个或多个值value插入到列表key的表尾。


假设有多个value值,那么各个value值按从左到右的顺序依次插入到表尾:比方对一个空列表(mylist)运行RPUSH mylist a b c,则结果列表为a b c,等同于运行命令RPUSHmylist a、RPUSH mylist b、RPUSH mylist c。


假设key不存在,一个空列表会被创建并运行RPUSH操作。


当key存在但不是列表类型时,返回一个错误。


时间复杂度:
    O(1)
返回值:
    运行RPUSH操作后,表的长度。


    注解:在Redis 2.4版本号曾经的RPUSH命令,都仅仅接受单个value值。


 
RPUSHX


RPUSHX key value


将值value插入到列表key的表尾,当且仅当key存在而且是一个列表。


和RPUSH命令相反,当key不存在时,RPUSHX命令什么也不做。


时间复杂度:
    O(1)
返回值:
    RPUSHX命令运行之后,表的长度。


 
LPOP


LPOP key


移除并返回列表key的头元素。


时间复杂度:
    O(1)
返回值:
    列表的头元素。
    当key不存在时,返回nil。


 
RPOP


RPOP key


移除并返回列表key的尾元素。


时间复杂度:
    O(1)
返回值:
    列表的尾元素。
    当key不存在时,返回nil。


 
BLPOP


BLPOP key [key ...] timeout


BLPOP是列表的堵塞式(blocking)弹出原语。


它是LPOP命令的堵塞版本号,当给定列表内没有不论什么元素可供弹出的时候,连接将被BLPOP命令堵塞,直到等待超时或发现可弹出元素为止。


当给定多个key參数时,按參数key的先后顺序依次检查各个列表,弹出第一个非空列表的头元素。


非堵塞行为


当BLPOP被调用时,假设给定key内至少有一个非空列表,那么弹出遇到的第一个非空列表的头元素,并和被弹出元素所属的列表的名字一起,组成结果返回给调用者。


当存在多个给定key时,BLPOP按给定key參数排列的先后顺序,依次检查各个列表。


如果如今有job、 command和request三个列表,当中job不存在,command和request都持有非空列表。考虑下面命令:


BLPOP job command request 0


BLPOP保证返回的元素来自command,由于它是按”查找job -> 查找command -> 查找request“这种顺序,第一个找到的非空列表。


 


 


堵塞行为


假设全部给定key都不存在或包括空列表,那么BLPOP命令将堵塞连接,直到等待超时,或有还有一个client对给定key的随意一个运行LPUSH或RPUSH命令为止。


超时參数timeout接受一个以秒为单位的数字作为值。超时參数设为0表示堵塞时间能够无限期延长(block indefinitely) 。


 


 


同样的key被多个client同一时候堵塞
同样的key能够被多个client同一时候堵塞。
不同的client被放进一个队列中,按”先堵塞先服务”(first-BLPOP,first-served)的顺序为key运行BLPOP命令。


在MULTI/EXEC事务中的BLPOP


BLPOP能够用于流水线(pipline,批量地发送多个命令并读入多个回复),但把它用在MULTI/EXEC块其中没有意义。由于这要求整个server被堵塞以保证块运行时的原子性,该行为阻止了其它client运行LPUSH或RPUSH命令。


因此,一个被包裹在MULTI/EXEC块内的BLPOP命令,行为表现得就像LPOP一样,对空列表返回nil,对非空列表弹出列表元素,不进行不论什么堵塞操作。


 


 


时间复杂度:O(1)返回值:
假设列表为空,返回一个nil。
反之,返回一个含有两个元素的列表,第一个元素是被弹出元素所属的key,第二个元素是被弹出元素的值。


 


 
BRPOP


BRPOP key [key ...] timeout


BRPOP是列表的堵塞式(blocking)弹出原语。


它是RPOP命令的堵塞版本号,当给定列表内没有不论什么元素可供弹出的时候,连接将被BRPOP命令堵塞,直到等待超时或发现可弹出元素为止。


当给定多个key參数时,按參数key的先后顺序依次检查各个列表,弹出第一个非空列表的尾部元素。


关于堵塞操作的很多其它信息,请查看BLPOP命令,BRPOP除了弹出元素的位置和BLPOP不同之外,其它表现一致。


时间复杂度:
    O(1)
返回值:
    假如在指定时间内没有不论什么元素被弹出,则返回一个nil和等待时长。
    反之,返回一个含有两个元素的列表,第一个元素是被弹出元素所属的key,第二个元素是被弹出元素的值。


 
LLEN


LLEN key


返回列表key的长度。


假设key不存在,则key被解释为一个空列表,返回0.


假设key不是列表类型,返回一个错误。


时间复杂度:
    O(1)
返回值:
    列表key的长度。


 
LRANGE


LRANGE key start stop


返回列表key中指定区间内的元素,区间以偏移量start和stop指定。


下标(index)參数start和stop都以0为底,也就是说,以0表示列表的第一个元素,以1表示列表的第二个元素,以此类推。


你也能够使用负数下标,以-1表示列表的最后一个元素,-2表示列表的倒数第二个元素,以此类推。


注意LRANGE命令和编程语言区间函数的差别


假如你有一个包括一百个元素的列表,对该列表运行LRANGE list 0 10,结果是一个包括11个元素的列表,这表明stop下标也在LRANGE命令的取值范围之内(闭区间),这和某些语言的区间函数可能不一致,比方Ruby的Range.new、Array#slice和Python的range()函数。


超出范围的下标


超出范围的下标值不会引起错误。


假设start下标比列表的最大下标end(LLEN list减去1)还要大,或者start > stop,LRANGE返回一个空列表。


假设stop下标比end下标还要大,Redis将stop的值设置为end。


时间复杂度:
    O(S+N),S为偏移量start,N为指定区间内元素的数量。
返回值:
    一个列表,包括指定区间内的元素。


 
LREM


LREM key count value


依据參数count的值,移除列表中与參数value相等的元素。


count的值能够是下面几种:


        count > 0: 从表头開始向表尾搜索,移除与value相等的元素,数量为count。
        count < 0: 从表尾開始向表头搜索,移除与value相等的元素,数量为count的绝对值。
        count = 0: 移除表中全部与value相等的值。


时间复杂度:
    O(N),N为列表的长度。
返回值:
    被移除元素的数量。
    由于不存在的key被视作空表(empty list),所以当key不存在时,LREM命令总是返回0。


 
LSET


LSET key index value


将列表key下标为index的元素的值甚至为value。


很多其它信息请參考LINDEX操作。


当index參数超出范围,或对一个空列表(key不存在)进行LSET时,返回一个错误。


时间复杂度:
    对头元素或尾元素进行LSET操作,复杂度为O(1)。
    其它情况下,为O(N),N为列表的长度。
返回值:
    操作成功返回ok,否则返回错误信息


 
LTRIM


LTRIM key start stop


对一个列表进行修剪(trim),就是说,让列表仅仅保留指定区间内的元素,不在指定区间之内的元素都将被删除。


举个样例,运行命令LTRIM list 0 2,表示仅仅保留列表list的前三个元素,其余元素所有删除。


下标(index)參数start和stop都以0为底,也就是说,以0表示列表的第一个元素,以1表示列表的第二个元素,以此类推。


你也能够使用负数下标,以-1表示列表的最后一个元素,-2表示列表的倒数第二个元素,以此类推。


当key不是列表类型时,返回一个错误。


LTRIM命令通常和LPUSH命令或RPUSH命令配合使用,举个样例:


 


 


这个样例模拟了一个日志程序,每次将最新日志newest_log放到log列表中,而且仅仅保留最新的100项。注意当这样使用LTRIM命令时,时间复杂度是O(1),由于平均情况下,每次仅仅有一个元素被移除。


注意LTRIM命令和编程语言区间函数的差别


假如你有一个包括一百个元素的列表list,对该列表运行LTRIM list 0 10,结果是一个包括11个元素的列表,这表明stop下标也在LTRIM命令的取值范围之内(闭区间),这和某些语言的区间函数可能不一致,比方Ruby的Range.new、Array#slice和Python的range()函数。


超出范围的下标


超出范围的下标值不会引起错误。


假设start下标比列表的最大下标end(LLEN list减去1)还要大,或者start > stop,LTRIM返回一个空列表(由于LTRIM已经将整个列表清空)。


假设stop下标比end下标还要大,Redis将stop的值设置为end。


时间复杂度:
    O(N),N为被移除的元素的数量。
返回值:
    命令运行成功时,返回ok。


 


 
LINDEX


LINDEX key index


返回列表key中,下标为index的元素。


下标(index)參数start和stop都以0为底,也就是说,以0表示列表的第一个元素,以1表示列表的第二个元素,以此类推。


你也能够使用负数下标,以-1表示列表的最后一个元素,-2表示列表的倒数第二个元素,以此类推。


假设key不是列表类型,返回一个错误。


时间复杂度:
    O(N),N为到达下标index过程中经过的元素数量。
    因此,对列表的头元素和尾元素运行LINDEX命令,复杂度为O(1)。
返回值:
    列表中下标为index的元素。
    假设index參数的值不在列表的区间范围内(out of range),返回nil。


 
LINSERT


LINSERT key BEFORE|AFTER pivot value


将值value插入到列表key其中,位于值pivot之前或之后。


当pivot不存在于列表key时,不运行不论什么操作。


当key不存在时,key被视为空列表,不运行不论什么操作。


假设key不是列表类型,返回一个错误。


时间复杂度:
    O(N),N为寻找pivot过程中经过的元素数量。
返回值:
    假设命令运行成功,返回插入操作完毕之后,列表的长度。
    假设没有找到pivot,返回-1。
    假设key不存在或为空列表,返回0。


 


 
RPOPLPUSH


RPOPLPUSH source destination


命令RPOPLPUSH在一个原子时间内,运行下面两个动作:


        将列表source中的最后一个元素(尾元素)弹出,并返回给client。
        将source弹出的元素插入到列表destination,作为destination列表的的头元素。


举个样例,你有两个列表source和destination,source列表有元素a, b, c,destination列表有元素x, y, z,运行RPOPLPUSH source destination之后,source列表包括元素a, b,destination列表包括元素c, x, y, z ,而且元素c被返回。


假设source不存在,值nil被返回,而且不运行其它动作。


假设source和destination同样,则列表中的表尾元素被移动到表头,并返回该元素,能够把这样的特殊情况视作列表的旋转(rotation)操作。


时间复杂度:
    O(1)
返回值:
    被弹出的元素。




 


设计模式: 一个安全的队列


Redis的列表常常被用作队列(queue),用于在不同程序之间有序地交换消息(message)。一个程序(称之为生产者,producer)通过LPUSH命令将消息放入队列中,而还有一个程序(称之为消费者,consumer)通过RPOP命令取出队列中等待时间最长的消息。


不幸的是,在这个过程中,一个消费者可能在获得一个消息之后崩溃,而未运行完毕的消息也因此丢失。


使用RPOPLPUSH命令能够解决问题,由于它在返回一个消息之余,还将该消息加入到还有一个列表其中,另外的这个列表能够用作消息的备份表:假如一切正常,当消费者完毕该消息的处理之后,能够用LREM命令将该消息从备份表删除。


还有一方面,助手(helper)程序能够通过监视备份表,将超过一定处理时限的消息又一次放入队列中去(负责处理该消息的消费者可能已经崩溃),这样就不会丢失不论什么消息了。


 
BRPOPLPUSH


BRPOPLPUSH source destination timeout


BRPOPLPUSH是RPOPLPUSH的堵塞版本号,当给定列表source不为空时,BRPOPLPUSH的表现和RPOPLPUSH一样。


当列表source为空时,BRPOPLPUSH命令将堵塞连接,直到等待超时,或有还有一个client对source运行LPUSH或RPUSH命令为止。


超时參数timeout接受一个以秒为单位的数字作为值。超时參数设为0表示堵塞时间能够无限期延长(block indefinitely) 。


很多其它相关信息,请參考RPOPLPUSH命令。


时间复杂度:
    O(1)
返回值:
    假如在指定时间内没有不论什么元素被弹出,则返回一个nil和等待时长。
    反之,返回一个含有两个元素的列表,第一个元素是被弹出元素的值,第二个元素是等待时长。


 


 
集合(Set)


 附录,经常使用集合运算:


       A = {'a', 'b', 'c'}
    B = {'a', 'e', 'i', 'o', 'u'}


    inter(x, y): 交集,在集合x和集合y中都存在的元素。
    inter(A, B) = {'a'}


    union(x, y): 并集,在集合x中或集合y中的元素,假设一个元素在x和y中都出现,那仅仅记录一次就可以。
    union(A,B) = {'a', 'b', 'c', 'e', 'i', 'o', 'u'}


    diff(x, y): 差集,在集合x中而不在集合y中的元素。
    diff(A,B) = {'b', 'c'}


    card(x): 基数,一个集合中元素的数量。
    card(A) = 3


    空集: 基数为0的集合。


 
SADD


SADD key member [member ...]


将一个或多个member元素增加到集合key其中,已经存在于集合的member元素将被忽略。


假如key不存在,则创建一个仅仅包括member元素作成员的集合。


当key不是集合类型时,返回一个错误。


时间复杂度:
    O(N),N是被加入的元素的数量。
返回值:
    被加入到集合中的新元素的数量,不包含被忽略的元素。


    注解:在Redis2.4版本号曾经,SADD仅仅接受单个member值。


 


 
SREM


SREM key member [member ...]


移除集合key中的一个或多个member元素,不存在的member元素会被忽略。


当key不是集合类型,返回一个错误。


时间复杂度:
    O(N),N为给定member元素的数量。
返回值:
    被成功移除的元素的数量,不包含被忽略的元素。


    注解:在Redis2.4版本号曾经,SREM仅仅接受单个member值。


 


 
SMEMBERS


SMEMBERS key


返回集合key中的全部成员。


时间复杂度:
    O(N),N为集合的基数。
返回值:
    集合中的全部成员。


 


 
SISMEMBER


SISMEMBER key member


推断member元素是否是集合key的成员。


时间复杂度:
    O(1)
返回值:
    假设member元素是集合的成员,返回1。
    假设member元素不是集合的成员,或key不存在,返回0。


 


 
SCARD


SCARD key


返回集合key的基数(集合中元素的数量)。


时间复杂度:
    O(1)
返回值:
    集合的基数。
    当key不存在时,返回0。


 


 
SMOVE


SMOVE source destination member


将member元素从source集合移动到destination集合。


SMOVE是原子性操作。


假设source集合不存在或不包括指定的member元素,则SMOVE命令不运行不论什么操作,仅返回0。否则,member元素从source集合中被移除,并加入到destination集合中去。


当destination集合已经包括member元素时,SMOVE命令仅仅是简单地将source集合中的member元素删除。


当source或destination不是集合类型时,返回一个错误。


时间复杂度:
    O(1)
返回值:
    假设member元素被成功移除,返回1。
    假设member元素不是source集合的成员,而且没有不论什么操作对destination集合运行,那么返回0。


 


 
SPOP


SPOP key


移除并返回集合中的一个随机元素。


时间复杂度:
    O(1)
返回值:
    被移除的随机元素。
    当key不存在或key是空集时,返回nil。


 


 


    也能够參考:假设仅仅想获取一个随机元素,但不想该元素从集合中被移除的话,能够使用SRANDMEMBER命令。


 
SRANDMEMBER


SRANDMEMBER key


返回集合中的一个随机元素。


该操作和SPOP相似,但SPOP将随机元素从集合中移除并返回,而SRANDMEMBER则只返回随机元素,而不正确集合进行不论什么修改。


时间复杂度:
    O(1)
返回值:
    被选中的随机元素。 当key不存在或key是空集时,返回nil。


 


 
SINTER


SINTER key [key ...]


返回一个集合的所有成员,该集合是所有给定集合的交集。


不存在的key被视为空集。


当给定集合其中有一个空集时,结果也为空集(依据集合运算定律)。


时间复杂度:
    O(N * M),N为给定集合其中基数最小的集合,M为给定集合的个数。
返回值:
    交集成员的列表。


 


 
SINTERSTORE


SINTERSTORE destination key [key ...]


此命令等同于SINTER,但它将结果保存到destination集合,而不是简单地返回结果集。


假设destination集合已经存在,则将其覆盖。


destination能够是key本身。


时间复杂度:
    O(N * M),N为给定集合其中基数最小的集合,M为给定集合的个数。
返回值:
    结果集中的成员数量。


 


 
SUNION


SUNION key [key ...]


返回一个集合的所有成员,该集合是所有给定集合的并集。


不存在的key被视为空集。


时间复杂度:
    O(N),N是全部给定集合的成员数量之和。
返回值:
    并集成员的列表。


 


 
SUNIONSTORE


SUNIONSTORE destination key [key ...]


此命令等同于SUNION,但它将结果保存到destination集合,而不是简单地返回结果集。


假设destination已经存在,则将其覆盖。


destination能够是key本身。


时间复杂度:
    O(N),N是全部给定集合的成员数量之和。
返回值:
    结果集中的元素数量。


 


 
SDIFF


SDIFF key [key ...]


返回一个集合的所有成员,该集合是所有给定集合的差集 。


不存在的key被视为空集。


时间复杂度:
    O(N),N是全部给定集合的成员数量之和。
返回值:
    交集成员的列表。


 


 
SDIFFSTORE


SDIFFSTORE destination key [key ...]


此命令等同于SDIFF,但它将结果保存到destination集合,而不是简单地返回结果集。


假设destination集合已经存在,则将其覆盖。


destination能够是key本身。


时间复杂度:
    O(N),N是全部给定集合的成员数量之和。
返回值:
    结果集中的元素数量。


 


 
有序集(Sorted Set)
ZADD


 


ZADD key score member [[score member] [score member] ...]


将一个或多个member元素及其score值增加到有序集key其中。


假设某个member已经是有序集的成员,那么更新这个member的score值,并通过又一次插入这个member元素,来保证该member在正确的位置上。


score值能够是整数值或双精度浮点数。


假设key不存在,则创建一个空的有序集并运行ZADD操作。


当key存在但不是有序集类型时,返回一个错误。


对有序集的很多其它介绍请參见sorted set。


时间复杂度:
    O(M*log(N)),N是有序集的基数,M为成功加入的新成员的数量。
返回值:
    被成功加入的新成员的数量,不包含那些被更新的、已经存在的成员。


 


     


    注解:在Redis2.4版本号曾经,ZADD每次仅仅能加入一个元素。


 


 
ZREM


ZREM key member [member ...]


移除有序集key中的一个或多个成员,不存在的成员将被忽略。


当key存在但不是有序集类型时,返回一个错误。


时间复杂度:
    O(M*log(N)),N为有序集的基数,M为被成功移除的成员的数量。
返回值:
    被成功移除的成员的数量,不包含被忽略的成员。


    注解:在Redis2.4版本号曾经,ZREM每次仅仅能删除一个元素。


 


 
ZCARD


ZCARD key


返回有序集key的基数。


时间复杂度:
    O(1)
返回值:
    当key存在且是有序集类型时,返回有序集的基数。
    当key不存在时,返回0。


 
ZCOUNT


ZCOUNT key min max


返回有序集key中,score值在min和max之间(默认包含score值等于min或max)的成员。


关于參数min和max的具体用法,请參考ZRANGEBYSCORE命令。


时间复杂度:
    O(log(N)+M),N为有序集的基数,M为值在min和max之间的元素的数量。
返回值:
    score值在min和max之间的成员的数量。


 
ZSCORE


ZSCORE key member


返回有序集key中,成员member的score值。


假设member元素不是有序集key的成员,或key不存在,返回nil。


时间复杂度:
    O(1)
返回值:
    member成员的score值,以字符串形式表示。


 
ZINCRBY


ZINCRBY key increment member


为有序集key的成员member的score值加上增量increment。


你也能够通过传递一个负数值increment,让score减去对应的值,比方ZINCRBY key -5 member,就是让member的score值减去5。


当key不存在,或member不是key的成员时,ZINCRBY key increment member等同于ZADD key increment member。


当key不是有序集类型时,返回一个错误。


score值能够是整数值或双精度浮点数。


时间复杂度:
    O(log(N))
返回值:
    member成员的新score值,以字符串形式表示。


 


 
ZRANGE


ZRANGE key start stop [WITHSCORES]


返回有序集key中,指定区间内的成员。


当中成员的位置按score值递增(从小到大)来排序。


具有同样score值的成员按字典序(lexicographical order)来排列。


假设你须要成员按score值递减(从大到小)来排列,请使用ZREVRANGE命令。
下标參数start和stop都以0为底,也就是说,以0表示有序集第一个成员,以1表示有序集第二个成员,以此类推。
你也能够使用负数下标,以-1表示最后一个成员,-2表示倒数第二个成员,以此类推。
超出范围的下标并不会引起错误。
比方说,当start的值比有序集的最大下标还要大,或是start > stop时,ZRANGE命令仅仅是简单地返回一个空列表。
还有一方面,假如stop參数的值比有序集的最大下标还要大,那么Redis将stop当作最大下标来处理。
能够通过使用WITHSCORES选项,来让成员和它的score值一并返回,返回列表以value1,score1, ..., valueN,scoreN的格式表示。
client库可能会返回一些更复杂的数据类型,比方数组、元组等。


时间复杂度:
    O(log(N)+M),N为有序集的基数,而M为结果集的基数。
返回值:
    指定区间内,带有score值(可选)的有序集成员的列表。


 
ZREVRANGE


ZREVRANGE key start stop [WITHSCORES]


返回有序集key中,指定区间内的成员。
当中成员的位置按score值递减(从大到小)来排列。
具有同样score值的成员按字典序的反序(reverse lexicographical order)排列。


除了成员按score值递减的次序排列这一点外,ZREVRANGE命令的其它方面和ZRANGE命令一样。


时间复杂度:
    O(log(N)+M),N为有序集的基数,而M为结果集的基数。
返回值:
    指定区间内,带有score值(可选)的有序集成员的列表。


 


 
ZRANGEBYSCORE


ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]


返回有序集key中,全部score值介于min和max之间(包含等于min或max)的成员。有序集成员按score值递增(从小到大)次序排列。


具有同样score值的成员按字典序(lexicographical order)来排列(该属性是有序集提供的,不须要额外的计算)。


可选的LIMIT參数指定返回结果的数量及区间(就像SQL中的SELECT LIMIT offset, count),注意当offset非常大时,定位offset的操作可能须要遍历整个有序集,此过程最坏复杂度为O(N)时间。
可选的WITHSCORES參数决定结果集是单单返回有序集的成员,还是将有序集成员及其score值一起返回。
该选项自Redis 2.0版本号起可用。


区间及无限


min和max能够是-inf和+inf,这样一来,你就能够在不知道有序集的最低和最高score值的情况下,使用ZRANGEBYSCORE这类命令。


默认情况下,区间的取值使用闭区间(小于等于或大于等于),你也能够通过给參数前添加(符号来使用可选的开区间(小于或大于)。


举个样例:


 


返回全部符合条件1 < score <= 5的成员;


 


返回全部符合条件5 < score < 10的成员。


时间复杂度:
    O(log(N)+M),N为有序集的基数,M为被结果集的基数。
返回值:
    指定区间内,带有score值(可选)的有序集成员的列表。


 


 
ZREVRANGEBYSCORE


ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]


返回有序集key中,score值介于max和min之间(默认包含等于max或min)的全部的成员。有序集成员按score值递减(从大到小)的次序排列。


具有同样score值的成员按字典序的反序(reverse lexicographical order)排列。


除了成员按score值递减的次序排列这一点外,ZREVRANGEBYSCORE命令的其它方面和ZRANGEBYSCORE命令一样。


时间复杂度:
    O(log(N)+M),N为有序集的基数,M为结果集的基数。
返回值:
    指定区间内,带有score值(可选)的有序集成员的列表。


 


 
ZRANK


ZRANK key member


返回有序集key中成员member的排名。当中有序集成员按score值递增(从小到大)顺序排列。


排名以0为底,也就是说,score值最小的成员排名为0。


使用ZREVRANK命令能够获得成员按score值递减(从大到小)排列的排名。


时间复杂度:
    O(log(N))
返回值:
    假设member是有序集key的成员,返回member的排名。
    假设member不是有序集key的成员,返回nil。


 
ZREVRANK


ZREVRANK key member


返回有序集key中成员member的排名。当中有序集成员按score值递减(从大到小)排序。


排名以0为底,也就是说,score值最大的成员排名为0。


使用ZRANK命令能够获得成员按score值递增(从小到大)排列的排名。


时间复杂度:
    O(log(N))
返回值:
    假设member是有序集key的成员,返回member的排名。
    假设member不是有序集key的成员,返回nil。


 


 
ZREMRANGEBYRANK


ZREMRANGEBYRANK key start stop


移除有序集key中,指定排名(rank)区间内的全部成员。


区间分别下面标參数start和stop指出,包括start和stop在内。
下标參数start和stop都以0为底,也就是说,以0表示有序集第一个成员,以1表示有序集第二个成员,以此类推。
你也能够使用负数下标,以-1表示最后一个成员,-2表示倒数第二个成员,以此类推。


时间复杂度:
    O(log(N)+M),N为有序集的基数,而M为被移除成员的数量。
返回值:
    被移除成员的数量。


 


 
ZREMRANGEBYSCORE


ZREMRANGEBYSCORE key min max


移除有序集key中,全部score值介于min和max之间(包含等于min或max)的成员。


自版本号2.1.6開始,score值等于min或max的成员也能够不包含在内,详情请參见ZRANGEBYSCORE命令。


时间复杂度:
    O(log(N)+M),N为有序集的基数,而M为被移除成员的数量。
返回值:
    被移除成员的数量。


 


 
ZINTERSTORE


ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]


计算给定的一个或多个有序集的交集,当中给定key的数量必须以numkeys參数指定,并将该交集(结果集)储存到destination。


默认情况下,结果集中某个成员的score值是全部给定集下该成员score值之和。


关于WEIGHTS和AGGREGATE选项的描写叙述,參见ZUNIONSTORE命令。


时间复杂度:
    O(N*K)+O(M*log(M)),N为给定key中基数最小的有序集,K为给定有序集的数量,M为结果集的基数。
返回值:
    保存到destination的结果集的基数。


 


 
ZUNIONSTORE


ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX]


计算给定的一个或多个有序集的并集,当中给定key的数量必须以numkeys參数指定,并将该并集(结果集)储存到destination。


默认情况下,结果集中某个成员的score值是全部给定集下该成员score值之和。


WEIGHTS


使用WEIGHTS选项,你能够为每一个给定有序集分别指定一个乘法因子(multiplication factor),每一个给定有序集的全部成员的score值在传递给聚合函数(aggregation function)之前都要先乘以该有序集的因子。


假设没有指定WEIGHTS选项,乘法因子默认设置为1。


AGGREGATE


使用AGGREGATE选项,你能够指定并集的结果集的聚合方式。


默认使用的參数SUM,能够将全部集合中某个成员的score值之和作为结果集中该成员的score值;使用參数MIN,能够将全部集合中某个成员的最小score值作为结果集中该成员的score值;而參数MAX则是将全部集合中某个成员的最大score值作为结果集中该成员的score值。


时间复杂度:
    O(N)+O(M log(M)),N为给定有序集基数的总和,M为结果集的基数。
返回值:
    保存到destination的结果集的基数。


 


 
公布/订阅(Pub/Sub)
PUBLISH


PUBLISH channel message


将信息 message 发送到指定的频道 channel 。


时间复杂度:
    O(N+M),当中 N 是频道 channel 的订阅者数量,而 M 则是使用模式订阅(subscribed patterns)的client的数量。
返回值:
    接收到信息 message 的订阅者数量。


 


 
SUBSCRIBE


SUBSCRIBE channel [channel ...]


订阅给定频道的信息。


时间复杂度:
    O(N),当中 N 是订阅的频道的数量。
返回值:
    接收到的信息(请參见以下的代码说明)。


 


 
PSUBSCRIBE


PSUBSCRIBE pattern [pattern ...]


订阅符合给定模式的频道。


每一个模式以 * 作为匹配符,比方 huangz* 匹配全部以 huangz 开头的频道( huangzmsg 、 huangz-blog 、 huangz.tweets 等等), news.* 匹配全部以 news. 开头的频道(news.it 、 news.global.today 等等),诸如此类。


时间复杂度:
    O(N), N 是订阅的模式的数量。
返回值:
    接收到的信息(请參见以下的代码说明)。


 


 
UNSUBSCRIBE


    警告:此命令在新版 Redis 中似乎已经被废弃?


PUNSUBSCRIBE


    警告:此命令在新版 Redis 中似乎已经被废弃?


 
事务(Transaction)
WATCH


ATCH key [key ...]


监视一个(或多个) key ,假设在事务运行之前这个(或这些) key 被其它命令所修改,那么事务将被打断。


时间复杂度:
    O(1)。
返回值:
    总是返回 OK 。


 
UNWATCH


UNWATCH


取消 WATCH 命令对全部 key 的监视。


假设在运行 WATCH 命令之后, EXEC 命令或 DISCARD 命令先被运行了的话,那么就不须要再运行 UNWATCH 了。


由于 EXEC 命令会运行事务,因此 WATCH 命令的效果已经产生了;而 DISCARD 命令在取消事务的同一时候也会取消全部对 key 的监视,因此这两个命令运行之后,就没有必要运行 UNWATCH 了。


时间复杂度:
    O(1)
返回值:
    总是 OK 。


 
MULTI


MULTI


标记一个事务块的開始。


事务块内的多条命令会依照先后顺序被放进一个队列其中,最后由 EXEC 命令在一个原子时间内运行。


时间复杂度:
    O(1)。
返回值:
    总是返回 OK 。


 


 
EXEC


EXEC


运行全部事务块内的命令。


假如某个(或某些) key 正处于 WATCH 命令的监视之下,且事务块中有和这个(或这些) key 相关的命令,那么 EXEC 命令仅仅在这个(或这些) key 没有被其它命令所修改的情况下运行并生效,否则该事务被打断(abort)。


时间复杂度:
    事务块内全部命令的时间复杂度的总和。
返回值:
    事务块内全部命令的返回值,按命令运行的先后顺序排列。
    当操作被打断时,返回空值 nil 。


 


 
DISCARD


DISCARD


取消事务,放弃运行事务块内的全部命令。


假设正在使用 WATCH 命令监视某个(或某些) key ,那么取消全部监视,等同于运行命令 UNWATCH 。


时间复杂度:
    O(1)。
返回值:
    总是返回 OK 。


 


 
连接(Connection)
AUTH


AUTH password


通过设置配置文件里 requirepass 项的值(使用命令 CONFIG SET requirepass password ),能够使用密码来保护 Redis server。


假设开启了password保护的话,在每次连接 Redis server之后,就要使用 AUTH 命令解锁,解锁之后才干使用其它 Redis 命令。


假设 AUTH 命令给定的password password 和配置文件里的password相符的话,server会返回 OK 并開始接受命令输入。


反之,假设password不匹配的话,server将返回一个错误,并要求client需又一次输入password。


 


    警告:由于 Redis 高性能的特点,在非常短时间内尝试推測非常多个password是有可能的,因此请确保使用的password足够复杂和足够长,以免遭受password推測攻击。


时间复杂度:
    O(1)
返回值:
    password匹配时返回 OK ,否则返回一个错误。


 
PING


PING


client向server发送一个 PING ,然后server返回client一个 PONG 。


通经常使用于測试与server的连接是否仍然生效,或者用于測量延迟值。


时间复杂度:
    O(1)
返回值:
    PONG


 


 
SELECT


SELECT index


切换到指定的数据库,数据库索引號用数字值指定,以 0 作为起始索引值。


新的链接总是使用 0 号数据库。


时间复杂度:
    O(1)


返回值:
    OK


 
ECHO


ECHO message


打印一个特定的信息 message ,測试时使用。


时间复杂度:
    O(1)
返回值:
    message 自身。


 


 
QUIT


QUIT


请求server关闭与当前client的连接。


一旦全部等待中的回复(假设有的话)顺利写入到client,连接就会被关闭。


时间复杂度:
    O(1)
返回值:
    总是返回 OK (可是不会被打印显示,由于当时 Redis-cli 已经退出)。


 


 
server(Server)
BGREWRITEAOF


BGREWRITEAOF


异步(Asynchronously)重写 AOF 文件以反应当前数据库的状态。


即使 BGREWRITEAOF 命令运行失败,旧 AOF 文件里的数据也不会因此丢失或改变。


时间复杂度:
    O(N), N 为要追加到 AOF 文件里的数据数量。
返回值:
    反馈信息。


 
BGSAVE


在后台异步保存当前数据库的数据到磁盘。


BGSAVE 命令运行之后马上返回 OK ,然后 Redis fork出一个新子进程,原来的 Redis 进程(父进程)继续处理client请求,而子进程则负责将数据保存到磁盘,然后退出。


client能够通过 LASTSAVE 命令查看相关信息,推断 BGSAVE 命令是否运行成功。


时间复杂度:
    O(N), N 为要保存到数据库中的 key 的数量。
返回值:
    反馈信息。


 
SAVE


SAVE


同步保存当前数据库的数据到磁盘。


时间复杂度:
    O(N), N 为要保存到数据库中的 key 的数量。
返回值:
    总是返回 OK 。


 


 
LASTSAVE


LASTSAVE


返回近期一次 Redis 成功运行保存操作的时间点( SAVE 、 BGSAVE 等),以 UNIX 时间戳格式表示。


时间复杂度:
    O(1)
返回值:
    一个 UNIX 时间戳。


 


 
DBSIZE


DBSIZE


返回当前数据库的 key 的数量。


时间复杂度:
    O(1)
返回值:
    当前数据库的 key 的数量。


 


 
SLAVEOF


SLAVEOF host port


SLAVEOF 命令用于在 Redis 执行时动态地改动复制(replication)功能的行为。


通过运行 SLAVEOF host port 命令,能够将当前server转变为指定server的从属server(slave server)。


假设当前server已经是某个主server(master server)的从属server,那么运行 SLAVEOF host port 将使当前server停止对旧主server的同步,丢弃旧数据集,转而開始对新主server进行同步。


另外,对一个从属server运行命令 SLAVEOF NO ONE 将使得这个从属server关闭复制功能,并从从属server转变回主server,原来同步所得的数据集不会被丢弃。


利用“ SLAVEOF NO ONE 不会丢弃同步所得数据集”这个特性,能够在主server失败的时候,将从属server用作新的主server,从而实现无间断执行。


时间复杂度:
    SLAVEOF host port ,O(N), N 为要同步的数据数量。
    SLAVEOF NO ONE , O(1) 。
返回值:
    总是返回 OK 。


 


 
FLUSHALL


FLUSHALL


清空整个 Redis server的数据(删除全部数据库的全部 key)。


此命令从不失败。


时间复杂度:
    尚未明白
返回值:
    总是返回 OK 。


 


 
FLUSHDB


FLUSHDB


清空当前数据库中的全部 key 。


此命令从不失败。


时间复杂度:
    O(1)
返回值:
    总是返回 OK 。


 


 
SHUTDOWN


SHUTDOWN


SHUTDOWN 命令运行下面操作:


    停止全部client
    假设有最少一个保存点在等待,运行 SAVE 命令
    假设 AOF 选项被打开,更新 AOF 文件
    server关闭


假设持久化被打开的话, SHUTDOWN 命令会保证server正常关闭而不丢失不论什么数据。


假如仅仅是单纯地运行 SAVE 命令,然后再运行 QUIT 命令,则没有这一保证 —— 由于在运行 SAVE 之后、运行 QUIT 之前的这段时间中间,其它client可能正在和server进行通讯,这时假设运行 QUIT 就会造成数据丢失。


时间复杂度:
    不明白
返回值:
    运行失败时返回错误。
    运行成功时不返回不论什么信息,server和client的连接断开,client自己主动退出。


 


 
SLOWLOG


SLOWLOG subcommand [argument]


什么是 SLOWLOG


Slow log 是 Redis 用来记录查询运行时间的日志系统。


查询运行时间指的是不包含像client响应(talking)、发送回复等 IO 操作,而单单是运行一个查询命令所耗费的时间。


另外,slow log 保存在内存里面,读写速度很快,因此你能够放心地使用它,不必操心由于开启 slow log 而损害 Redis 的速度。


设置 SLOWLOG


Slow log 的行为由两个配置參数(configuration parameter)指定,能够通过改写 redis.conf 文件或者用 CONFIG GET 和 CONFIG SET 命令对它们动态地进行改动。


第一个选项是 slowlog-log-slower-then ,它决定要对运行时间大于多少微秒(microsecond,1秒 = 1,000,000 微秒)的查询进行记录。


比方运行下面命令将让 slow log 记录全部查询时间大于等于 100 微秒的查询:


CONFIG SET slowlog-log-slower-then 100 ,


而下面命令记录全部查询时间大于 1000 微秒的查询:


CONFIG SET slowlog-log-slower-then 1000 。


还有一个选项是 slowlog-max-len ,它决定 slow log 最多能保存多少条日志, slow log 本身是一个 LIFO 队列,当队列大小超过 slowlog-max-len 时,最旧的一条日志将被删除,而最新的一条日志增加到 slow log ,以此类推。


下面命令让 slow log 最多保存 1000 条日志:


CONFIG SET slowlog-max-len 1000 。


使用 CONFIG GET 命令能够查询两个选项的当前值:


 


 


查看 slow log


要查看 slow log ,能够使用 SLOWLOG GET 或者 SLOWLOG GET number 命令,前者打印全部 slow log ,最大长度取决于 slowlog-max-len 选项的值,而 SLOWLOG GET number 则仅仅打印指定数量的日志。


最新的日志会最先被打印:


 


 


日志的唯一 id 仅仅有在 Redis server重新启动的时候才会重置,这样能够避免对日志的反复处理(比方你可能会想在每次发现新的慢查询时发邮件通知你)。


查看当前日志的数量


使用命令 SLOWLOG LEN 能够查看当前日志的数量。


请注意这个值和 slower-max-len 的差别,它们一个是当前日志的数量,一个是同意记录的最大日志的数量。


 


清空日志


使用命令 SLOWLOG RESET 能够清空 slow log 。


 


 


时间复杂度:O(1)


返回值:取决于不同命令,返回不同的值。


 
INFO


INFO


返回关于 Redis server的各种信息和统计值。


时间复杂度:
    O(1)
返回值:
    详细请參见以下的測试代码。


 


 
CONFIG GET


CONFIG GET parameter


CONFIG GET 命令用于取得执行中的 Redis server的配置參数(configuration parameters),只是并不是全部配置參数都被 CONFIG GET 命令所支持。


CONFIG GET 接受单个參数 parameter 作为搜索keyword,查找全部匹配的配置參数,当中參数和值以“键-值对”(key-value pairs)的方式排列。


比方运行 CONFIG GET s* 命令,server就会返回全部以 s 开头的配置參数及參数的值:


 


 


假设你仅仅是寻找特定的某个參数的话,你当然也能够直接指定參数的名字:


 


使用命令 CONFIG GET * ,能够列出 CONFIG GET 命令支持的全部參数:


 


全部被 CONFIG SET 所支持的配置參数都能够在配置文件 redis.conf 中找到,只是 CONFIG GET 和 CONFIG SET 使用的格式和 redis.conf 文件所使用的格式有下面两点不同:


    10kb 、 2gb 这些在配置文件里所使用的储存单位缩写,不能够用在 CONFIG 命令中, CONFIG SET 的值仅仅能通过数字值显式地设定。
     
    像 CONFIG SET xxx 1k 这种命令是错误的,正确的格式是 CONFIG SET xxx 1000 。
    save 选项在 redis.conf 中是用多行文字储存的,但在 CONFIG GET 命令中,它仅仅打印一行文字。
     
    下面是 save 选项在 redis.conf 文件里的表示:
     
    save 900 1
    save 300 10
    save 60 10000
     
    可是 CONFIG GET 命令的输出仅仅有一行:
     
    redis> CONFIG GET save
    1) "save"
    2) "900 1 300 10 60 10000"
     
    上面 save 參数的三个值表示:在 900 秒内最少有 1 个 key 被修改,或者 300 秒内最少有 10 个 key 被修改,又或者 60 秒内最少有 1000 个 key 被修改,以上三个条件随便满足一个,就触发一次保存操作。


时间复杂度:
    不明白
返回值:
    给定配置參数的值。


 
CONFIG SET


CONFIG SET parameter value


CONFIG SET 命令能够动态地调整 Redis server的配置(configuration)而无须重新启动。


你能够使用它改动配置參数,或者改变 Redis 的持久化(Persistence)方式。


CONFIG SET 能够改动的配置參数能够使用命令 CONFIG GET * 来列出,全部被 CONFIG SET 改动的配置參数都会马上生效。


关于 CONFIG SET 命令的很多其它消息,请參见命令 CONFIG GET 的说明。


关于怎样使用 CONFIG SET 命令改动 Redis 持久化方式,请參见 Redis Persistence 。


时间复杂度:
    不明白
返回值:
    当设置成功时返回 OK ,否则返回一个错误。


 
CONFIG RESETSTAT


CONFIG RESETSTAT


重置 INFO 命令中的某些统计数据,包含:


    Keyspace hits (键空间命中次数)
    Keyspace misses (键空间不命中次数)
    Number of commands processed (运行命令的次数)
    Number of connections received (连接server的次数)
    Number of expired keys (过期key的数量)


时间复杂度:
    O(1)
返回值:
    总是返回 OK 。


 
DEBUG OBJECT


DEBUG OBJECT key


返回给定 key 的调试信息。


时间复杂度:
    O(1)
返回值:
    当 key 存在时,返回有关信息。
    当 key 不存在时,返回一个错误。


 
DEBUG SEGFAULT


DEBUG SEGFAULT


令 Redis server崩溃,调试用。


时间复杂度:
    不明白
返回值:
    无


 
MONITOR


MONITOR


实时打印出 Redis server接收到的命令,调试用。


时间复杂度:
    不明白
返回值:
    总是返回 OK 。


 
SYNC


YNC


用于复制功能(replication)的内部命令。


时间复杂度:
    不明白
返回值:
    不明白

php redis操作具体解释


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论