事务 / bitmap 位图 / 地理位置
最后更新于:2022-04-02 04:00:30
[TOC]
## 事务
批量指令并非原子化的操作,中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做。
### 接口
```
$redis->multi(Redis::MULTI); //开启事务,事务块内的多条命令会按照先后顺序被放进一个队列当中,最后由 EXEC 命令在一个原子时间内执行。
$redis->multi(Redis::PIPELINE); //开启管道,事务块内的多条命令会按照先后顺序被放进一个队列当中,最后由 EXEC 命令在一个原子时间内执行。
$redis->exec(); //执行所有事务块内的命令,;【事务块内所有命令的返回值,按命令执行的先后顺序排列,当操作被打断时,返回空值 false】
```
### demo
```
$ret = $redis->multi()
->set('key1', 'val1')
->get('key1')
->set('key2', 'val2')
->get('key2')
->exec();
//$ret == array (
// 0 => TRUE,
// 1 => 'val1',
// 2 => TRUE,
// 3 => 'val2');
```
## bitmap 位图
`SETBIT key offset value`
1. 位的设置或清除取决于 value 参数,可以是 0 也可以是 1 。
2. 字符串会自动进行伸展(grown),当字符串值进行伸展时,空白位置以 0 填充
3. offset >=0 ,< 2^32 (bit 映射被限制在 512 MB 之内)。
应用 实现用户上线次数统计
```
> setbit demo 234 1 //设置 234
(integer) 0
> getbit demo 234 //判断 234 是否存在
(integer) 1
> setbit demo 234 0 // value 为 0 清除
(integer) 1
> getbit demo 234 //判断 234 是否存在
(integer) 0
> bitcount demo 0 235 // 判断存储了几个
(integer) 0
```
## 地理位置
> [参考](http://redisdoc.com/geo/georadius.html)
Redis > 3.2
| 命令 | 说明 |
| --- | --- |
| 1. GEOADD | 将指定的地理空间位置(纬度、经度、名称)添加到指定的 key 中 |
| 2. GEODIST | 返回两个给定位置之间的距离 |
| 3. GEOHASH | 返回一个或多个位置元素的 Geohash 表示 |
| 4. GEOPOS | 从 key 里返回所有给定位置元素的位置(经度和纬度) |
| 5. GEORADIUS | 以给定的经纬度为中心, 找出某一半径内的元素 |
| 6. GEORADIUSBYMEMBER | 找出位于指定范围内的元素,中心点是由给定的位置元素决定 |
```
$redis = new Redis();
if ( ! $redis->connect('127.0.0.1', 6379)) {
die($redis->getLastError());
}
$redis->rawCommand('geoadd', 'hangzhou', '120.118007', '30.259293', '桃园岭');
$redis->rawCommand('geoadd', 'hangzhou', '120.119445','30.255082', '农耕科普园');
$redis->rawCommand('geoadd', 'hangzhou', '120.071655','30.272893', '西溪湿地');
$redis->rawCommand('geoadd', 'hangzhou', '120.114321','30.221218', '龙井村');
$redis->rawCommand('geoadd', 'hangzhou', '120.145012','30.205586', '白塔公园');
$redis->rawCommand('geoadd', 'hangzhou', '120.112912','30.224221', '十里琅珰');
$redis->rawCommand('geoadd', 'hangzhou', '120.107264','30.206997', '狮峰');
$redis->rawCommand('geoadd', 'hangzhou', '120.117936','30.227969', '真迹寺');
$redis->rawCommand('geoadd', 'hangzhou', '120.10826','30.246569', '灵隐寺');
$redis->rawCommand('geoadd', 'hangzhou', '120.114123','30.264152', '状元峰');
// 返回两个给定位置之间的距离
$ret = $redis->rawCommand('GEODIST', 'hangzhou','西溪湿地', '龙井村', 'm');
var_dump($ret); //7060.0083
// 批量获取地点经纬度
$ret = $redis->rawCommand('GEOPOS', 'hangzhou','灵隐寺', '状元峰');
var_export($ret);
//[[ '120.10826021432877', '30.24656778547287',], [ '120.11412352323532', '30.264151146155207',],]
//返回 距离 hangzhou 指定经纬度坐标的距离最近的值
$ret = $redis->rawCommand('GEORADIUS', 'hangzhou','120.10836','30.246569', 2, 'km', 'WITHDIST','WITHCOORD','ASC');
var_export($ret); //7060.0083
/*[
['灵隐寺', '0.0096', ['120.10826021432877', '30.24656778547287',],],
['农耕科普园', '1.4251', ['120.11944502592087', '30.255081913847086',],],
['桃园岭', '1.6917', ['120.11800736188889', '30.259292085692756',],]
]*/
//清除 地址位置key
$redis->del("hangzhou");
```
';