原创 PHP如何操作使用redis、学习PHP使用redis的数据结构String、Hash、lists、sets、hyperloglogs、bitmap、geospatial(地理空间索引半径查询)用法

php redis
IT技术 · 继续停留 · 更新于 2018-10-09


Redis是一个开源数据缓存技术,它有很丰富的数据结构,比如字符串(string)、散列(hashes)、列表(lists)、集合(sets)、有序集合(sorted sets)

redis连接:connect 创建一个redis连接实例

$redis=new Redis();
$redis->connect('127.0.0.1', 6379);

字符串string用法:


$value="test";
$redis->set("set",$value);//设置一个键名 指定它的值
$values=$redis->get("set");//获取键名对应的值
print_r($values);//test


$values=$redis->delete("set");//删除键名对应的值 print_r($values);//false

SETNX 在指定的 key 不存在时,为 key 设置指定的值,这里是不存在才指定,存在不设置值  

$value="test";
$redis->setnx("set",$value);
$redis->setnx("set","testss");
$values=$redis->get("set");
print_r($values);//test

SETEX 指定的 key 设置值及其过期时间。如果 key 已经存在, SETEX 命令将会替换旧的值。 

$value="test";
$redis -> set('job',$value);
$redis -> setex('job',1,'testssss');//1秒过期时间
echo $redis -> get('job');//testssss

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

$array_mset = array(
'year' => 2018,
'month' => 9,
'date' => 11,
'time' => '13:04'
);
$redis -> mset($array_mset);
print_r($redis->get("year"));//2018

MSETNX  所有给定 key 都不存在的时候,同时设置一个或多个 key-value 对。当有其中一个存在的时候设置无效 

$array_mset = array(
'year' => 2017,
'month' => 9,
'date' => 11,
'time' => '13:04'
);
$redis -> msetnx($array_mset);
print_r($redis->get("year"));//2018 之前year这个对应的值为2018 当其中一个key存在的时候,设置无效

String更多操作


散列 HASH(哈希)  用法:  

HSET 用于为哈希表中的字段赋值 

HGET 获取哈希表中字段对应的值 

$redis -> hSet('test','test_a','test_values');
print_r($redis -> hGet('test','test_a')); // test_values

EXISTS 判断某个字段是否存在

if($redis -> exists('test'))
{
$redis -> hSet('test','test_a','test_values2');
print_r($redis -> hGet('test','test_a')); // test_values2
}

HDEL 用于删除哈希表 key 中的一个或多个指定字段,不存在的字段将被忽略。 

$redis -> hSet('test','test_a','aa');
print_r($redis -> hDel('test','test_a')); // int 1 成功

HMSET 用于同时将多个 field-value (字段-值)对设置到哈希表中 

HMGET 用于同时将多个 field组成的数组获取对应的值

$array_hmset = array(
'name' => 'jack',
'age' => 18,
'height' => 165
);
$redis -> hMset('myhash',$array_hmset);
$array_hmget = array('name','age','height');
print_r($redis -> hMget('myhash',$array_hmget)); //Array ( [name] => jack [age] => 18 [height] => 165 )

 Hash更多操作


列表lists用法:

LPUSH 将一个或多个值插入到列表头部  

print_r($redis -> lPush('list','job'));     // key 不存在,创建一个新的列表, 返回 int 1
print_r($redis -> lPush('list','dog')); // key 存在。但是 list 类型, 返回 int 2
print_r($redis -> lPush('list','cat')); // key 存在。但是 list 类型, 返回 int 3

$redis -> set('pats','dog');
var_dump($redis -> lPush('pats','cat')); // key 存在。但不是是 list 类型, 返回 boolean false

LPUSHX  将一个或多个值插入到列表头部,列表不存在时操作无效

RPUSH 用于将一个或多个值插入到列表的尾部。如果列表不存在,一个空列表会被创建并执行 RPUSH 操作  

RPUSHX 用于将一个或多个值插入到列表的尾部。如果列表不存在,列表不存在时操作无效

LRANGE 返回列表中指定区间内的元素,区间以偏移量 START 和 END 指定。 其中 0 表示列表的第一个元素, 1 表示列表的第二个元素,以此类推。 你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。 

print_r($redis -> lRange('list',0,-1));     //获取list的所有元素

LLEN 返回列表的长度 

LSET 通过索引设置对应位置的元素的值 当索引参数超出范围,或对一个空列表进行 LSET 时,返回一个错误

print_r($redis -> lSet('list',1,'aaaa'));   // 将位置在1的元素替换为 aaa  起始位置从0开始

LINSERT 用于在列表的元素前或者后插入元素。 当指定元素不存在于列表中时,不执行任何操作。  如果 key 不是列表类型,返回一个错误。 

$redis -> lInsert('list','before','dog','Mango');//在dog前面插入Mango

print_r($redis -> lInsert('list','before','dogs','Mango'));//在不存在的dogs 前面插入Mango 返回 -1

LREM  移除某个指定的元素,从指定的元素第一个开始移除指定的次数

$redis -> lPush('list2','dog');
$redis -> lPush('list2','dog');
$redis -> lPush('list2','dog');
$redis -> lPush('list2','cat');
$redis -> lPush('list2','cat');
$redis -> lPush('list2','cat');
print_r($redis -> lRem('list2','dogs',2));// count 0 移除所有 小于 取绝对值 移除的指定元素不存在或者列表不存在 返回0
print_r($redis -> lRange('list2',0,-1)); // Array ( [0] => cat [1] => cat [2] => cat [3] => dog )

LPOP 用于移除并返回列表的第一个元素。 

RPOP 用于移除并返回列表的最后一个元素。

 Lists列表更多操作


集合SETS用法

Redis的 Set 是 string 类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据。 

 SADD 将一个或多个成员元素加入到集合中

SMEMBERS 返回集合中的所有的成员。 不存在的集合 key 被视为空集合。 

$redis -> sAdd('sets','world');
$redis -> sAdd('sets','fangyao');
$redis -> sAdd('sets','fangyao');//重复添加 则只取第一个
$redis -> sAdd('sets','yinshen'); // 已存在的 key 被忽略

print_r($redis -> sMembers('sets')); //Array ( [0] => yinshen [1] => fangyao [2] => world )

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

$redis -> sAdd('sets','world');
$redis -> sAdd('sets','fangyao');
$redis -> sAdd('sets','fangyao');//重复添加 则只取第一个
$redis -> sAdd('sets','yinshen'); // 已存在的 key 被忽略
$redis->sRem("sets","fangyao","yinshen");
print_r($redis -> sMembers('sets'));//Array ( [0] => world )

SCARD 返回集合中元素的数量。 

$redis -> sAdd('sets','world');
$redis -> sAdd('sets','fangyao');
$redis -> sAdd('sets','fangyao');//重复添加 则只取第一个
$redis -> sAdd('sets','yinshen'); // 已存在的 key 被忽略

print_r($redis -> sCard('sets'));// 3

SMOVE  将指定成员 member 元素从 A 集合移动到 B 集合 

(1)SMOVE 是原子性操作。

(2)如果  A   集合不存在或不包含指定的 member 元素,则 SMOVE 命令不执行任何操作,仅返回 0 。否则, member 元素从  A   集合中被移除,并添加到  B   集合中去。

(3)当   B   集合已经包含 member 元素时, SMOVE 命令只是简单地将 A 集合中的 member 元素删除。

(4)当 A 或 B 不是集合类型时,返回一个错误。

$redis -> sAdd('A','world');
$redis -> sAdd('A','fangyao');
$redis -> sAdd('A','yinshen');
$redis -> sAdd('B','aiqing');
$redis->sMove("A","B","yinshen");
print_r($redis -> sMembers('B'));//Array ( [0] => yinshen [1] => aiqing )
print_r("<br>");
print_r($redis -> sMembers('A'));//Array ( [0] => fangyao [1] => world )

SPOP 用于移除并集合中的一个随机元素 

$redis -> sAdd('A','world');
$redis -> sAdd('A','fangyao');
$redis -> sAdd('A','yinshen');
$redis -> sPop('A');
print_r($redis -> sMembers('A'));//Array ( [0] => yinshen [1] => world )

SET更多操作


Sorted-set(有序集合)  

通过数值进行默认从小到大排序

ZADD 用于将一个或多个成员元素及其数值加入到有序集当中  

ZRANGE  指定区间内的成员。(其中成员的位置按数值递增(从小到大)来排序。具有相同分数值的成员按字典序(lexicographical order )来排列。)

$redis -> zAdd('zset',0,'hello');
$redis -> zAdd('zset',1,'world');
$redis -> zAdd('zset',1,'foo'); // 集合中的元素唯一,但是数值可以重复
$redis -> zAdd('zset',2,'hi');
$redis -> zAdd('zset',2.5,'welcome');

print_r($redis -> zRange('zset',0,-1));//Array ( [0] => hello [1] => foo [2] => world [3] => hi [4] => welcome )

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

$redis -> zAdd('zset',0,'hello');
$redis -> zAdd('zset',1,'world');
$redis -> zAdd('zset',1,'foo'); // 集合中的元素唯一,但是数值可以重复
$redis -> zAdd('zset',2,'hi');
$redis -> zAdd('zset',2.5,'welcome');
$redis->zRem('zset',"welcome");
print_r($redis -> zRange('zset',0,-1));//Array ( [0] => hello [1] => foo [2] => world [3] => hi)

ZCARD 用于计算集合中元素的数量。 

$redis -> zAdd('zset',0,'hello');
$redis -> zAdd('zset',1,'world');
$redis -> zAdd('zset',1,'foo'); // 集合中的元素唯一,但是数值可以重复
$redis -> zAdd('zset',2,'hi');
$redis -> zAdd('zset',2.5,'welcome');

print_r($redis->zCard('zset'));// 5

ZCOUNT 用于计算有序集合中指定分数区间的成员数量 也就是指定数值在min到max之间的元素个数

$redis -> zAdd('zset',0,'hello');
$redis -> zAdd('zset',1,'world');
$redis -> zAdd('zset',1,'foo'); // 集合中的元素唯一,但是数值可以重复
$redis -> zAdd('zset',2,'hi');
$redis -> zAdd('zset',2.5,'welcome');

print_r($redis->zCount('zset',1,3));// 4

ZSCORE 返回有序集中指定成员的数值。 如果成员元素不是有序集 key 的成员,或 key 不存在,返回 0

$redis -> zAdd('zset',0,'hello');
$redis -> zAdd('zset',1,'world');
$redis -> zAdd('zset',1,'foo'); // 集合中的元素唯一,但是数值可以重复
$redis -> zAdd('zset',2,'hi');
$redis -> zAdd('zset',2.5,'welcome');

print_r($redis->zScore('zset',"welcome"));// 2.5

ZRANGEBYSCORE 用于移除有序集中,指定分数(score)区间内的所有成员。  

$redis -> zAdd('zset',0,'hello');
$redis -> zAdd('zset',1,'world');
$redis -> zAdd('zset',1,'foo'); // 集合中的元素唯一,但是数值可以重复
$redis -> zAdd('zset',2,'hi');
$redis -> zAdd('zset',2.5,'welcome');

print_r($redis->zRangeByScore('zset',0,1));// Array ( [0] => hello [1] => foo [2] => world )

ZREVRANGEBYSCORE 返回有序集中指定分数区间内的所有的成员。有序集成员按分数值递减(从大到小)的次序排列。 

$redis -> zAdd('zset',0,'hello');
$redis -> zAdd('zset',1,'world');
$redis -> zAdd('zset',1,'foo'); // 集合中的元素唯一,但是数值可以重复
$redis -> zAdd('zset',2,'hi');
$redis -> zAdd('zset',2.5,'welcome');

print_r($redis->zRevRangeByScore('zset',2,0));// Array ( [0] => hi [1] => world [2] => foo [3] => hello )

更多有序集合

BitMap使用

允许使用二进制数据的Key(binary keys) 和二进制数据的Value。Bitmap就是二进制数据的value(只能是1或者0)

使用场景:计算任意数量的统计

SETBIT   对指定的key的value的指定偏移(offset)的位置1或0,setbit(key, offset, value)操作对指定的key的value的指定偏移(offset)的位置1或0,时间复杂度是O(1)。 

GETBIT   获取offset设置的值,未设置过默认返回0

BITCOUNT   统计指定key位置为1的数量

BITOP   支持四种表达式运算: AND(交集), OR(并集), XOR(异或) 和NOT(取非), 用法如下:
bitop("AND","取名",$key1,$key2...)
bitop("OR","取名",$key1,$key2,$key3...)
bitop("XOR","取名",$key1,$key2....)
bitop("NOT","取名",$key)
BITPOS   返回设置为1或0的一个字符串中的第一个点的位置

示例:计算用户的活跃数量




HyperLogLogs

是一个用于统计唯一性事物数量的概率性数据结构,统计结果并不是完全精确,存在一定误差,对于精确度要求高的统计不适用。可以接受多个元素作为输入,并给出输入元素的基数估算值
基数:集合中不同元素的数量。比如 {'apple', 'banana', 'cherry', 'banana', 'apple'} 的基数就是 3 。  
估算值:算法给出的基数并不是精确的,可能会比实际稍微多一些或者稍微少一些,但会控制在合理的范围之内。  
HyperLogLog 的优点是,即使输入元素的数量或者体积非常非常大,计算基数所需的空间总是固定的、并且是很小的。在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以HyperLogLog 不能像集合那样,返回输入的各个元素。(即所占的空间相对于集合来说比较小)

PFADD    添加一个新元素
PFCOUNT  统计一个HyperLogLog中大概的基数元素的个数

示例: 由下列代码可以看出,MD5是唯一的,但是对于HyperLogLog 计算的唯一性事物数量来说循环1万次基数缺少于1万次由此得出不完全精确的
 


地理空间(geospatial)索引半径查询(3.2版本)

把某个具体的位置信息(经度,纬度,名称)添加到指定的key中(命令geoadd),使用标准的x,y形式,所以经度(longitude)必须放在纬度(latitude)之前.

经度有效范围:-180度到180度

纬度有效范围:-85.05112878度到85.05112878度

如果使用了超出有效范围的经纬度,此命令会返回一个错误。
提示:之所以没有GEODEL命令,是因为你可以用ZREM来删除一个元素,GEO索引结构实际上就是一个sorted set

GEOADD 添加一个或多个地理位置元素到一个key中 
$redis->rawCommand('geoadd', 'cities', '116.404269', '39.91582', 'beijing', '121.478799', '31.235456', 'shanghai') 
GEODIST 返回一个key中指定两个位置之间的距离  
$redis->rawCommand('geodist', 'cities', 'beijing', 'shanghai', 'km') //1068.5677  (指定长度单位:m,km,ft等 默认为m)

GEOHASH  返回一个或多个位置元素的 Geohash 表示,Geohash是一种经纬度散列算法  

$redis->rawCommand('geohash', 'cities', 'beijing') 

GEOPOS 返回一个或多个位置的经纬度信息,由于采用了geohash算法,返回的经纬度和添加时的数据可能会有细小误差  

$redis->rawCommand('geopos', 'cities', 'shanghai');//
结果:
array(1) {
[0]=>
array(2) {
[0]=>
string(21) "121.47879928350448608" //经度
[1]=>
string(20) "31.23545629441388627" //纬度
}
}
GEORADIUS    以给定位置为中心,半径不超过给定半径的附近所有位置  
$redis->rawCommand('GEORADIUS', 'cities', '120', '31', '300', 'km'); 120经度 31纬度 300半径
  • GEORADIUSBYMEMBER 和GEORADIUS相似,只是中心点不是指定经纬度,而是指定已添加的某个位置作为中心  
  • 格式: GEORADIUSBYMEMBER key member radius m|km|ft|mi 




  • |0 收藏|0

    思考你要发的内容