## 一、通用命令
| 名称 | 范例 | 描述 |
| --- | --- | --- |
| keys | keys ( * ) | 遍历(获取)所有 正则匹配的key |
| dbsize | dbsize ( ) | 计算key的总数 |
| exists | exists( $key ) | 检查key是否存在 |
| del | del( $key1, $key2 = null, $key3 = null ) | 删除指定key-value |
| expire | expire( $key, $ttl ) | key 在 ttl 秒后过期 |
| ttl | ttl( $key ) | 查看 key 剩余的过期时间 |
| persist | persist ( $key ) | 去掉 key 的过期时间,永生 |
| type | type($key) | 返回 key 的类型 |
## 二、数据结构和内部编码
## 三、单线程
* 一次只运行一条命令
* 拒绝长(慢)命令
* keys,flushall,flushdb,slow lua script , mutil/exec , operate big value( collection )
* 其实不是单线程
* fysnc file descriptor
* close file descriptor
* 单线程为什么这么快?
* 纯内存
* 非阻塞IO
* 避免线程切换和竞态消耗
## 四、字符串
* 字符串键值结构
* string类型是二进制安全的。意思是redis的string可以包含任何数据。比如jpg图片或者序列化的对象 。
* 一个键最大能存储512MB
* 场景
* 缓存 (用户信息,需要序列化)
* 计数器(网站访问量、点击量)
* 分布式锁(分布式自增ID,例如有三个 service 并发去获取 ,每次获取到的ID是自增的唯一的。利用到了redis的单线程和原子性 )
* 命令
| 名称 | 范例 | 说明 |
| --- | --- | --- |
| * get | get( $key ) | 获取 key 对应的 value |
| * set | set( $key, $value, $timeout = 0 ) | 设置 key - value 和 过期时间 timeout |
| * del | del( $key1, $key2 = null, $key3 = null ) | 删除key |
| * incr | incr( $key ) | key 自增 1,如果key 不存在,自增后 get(key)=1|
| * decr | decr( $key ) | key 自减 1,如果key 不存在,自减后get(key)=-1 |
| incrby | incrBy( $key, $value ) | key 自增 value,如果 key 不存在,自增后get(key)= value |
| decrby | decrBy( $key, $value ) | key 自减 value,如果key不存在,自减后 get(key)= - value |
| * mget | mget( array $array ) | 批量获取key ,原子操作 |
| * mset | mset( array $array ) | 批量设置 key - value |
| getset | getSet( $key, $value ) | set key NewValue并返回旧的value |
| append | append( $key, $value ) | 将 value 追加到旧的 value |
| strlen | strlen( $key ) | 返回字符串的长度(注意中文 ) |
| incrbyfloat | incrByFloat( $key, $increment ) | 增加 key 对应的值 ,例:3.5 |
| getrange | getRange( $key, $start, $end ) | 获取字符串指定下标所有的值 |
| setrange | setRange( $key, $offset, $value ) | 设置指定下标所有对应的值 |
## 五、哈希
* 哈希键值结构
![hash结构图](https://box.kancloud.cn/2291e15dd5b583bd43ffea2acce2cd40_611x216.png =300x100)
* 每一个field都是单独的属性,可以进行添加删除更改。
* key 可以看作一张关系表的一行,field是其中的列或者属性。
* field不能相同
* 命令
| 名称 | 范例 | 描述 |
| --- | --- | --- |
| hget | hGet($key, $hashKey) | 获取 key 对应的 hashKey 的 value |
| hset | hSet( $key, $hashKey, $value ) | 设置 key 对应的 hashKey 的value |
| hdel | hDel( $key, $hashKey1, $hashKey2 = null, $hashKeyN = null ) | 删除 key 对应的 hashKey 的value |
| hexists | hExists( $key, $hashKey ) | 判断 key 是否有 hashKey |
| hlen | hLen( $key ) | 获取 key 的 hashKey的数量 |
| hmget | hMGet( $key, $hashKeys ) | 批量获取 key 的一批 hashKeys对应的值 |
| hmset | hMset( $key, $hashKeys ) | 批量设置 key 的一批 hashKeys对应的值 |
| hgetall | hGetAll( $key ) | 返回 key 对应所有的 hashKey 和 value |
| hvals | hVals( $key ) | 返回 key 对应所有 hashKey 的 value |
| hkeys | hKeys( $key ) | 返回 key 对应所有 hashKey |
* 实战
* 记录网站每个用户个人主页的访问量?
* 缓存视频的基本信息
* string需要进行序列化和反序列号,更新操作时开销大
* hash 存储时可以针对某个值进行更新,开销小
* 3种方案比较
| 命令 | 优点 | 缺点 |
| --- | --- | --- |
| string v1 <br>(序列化为json或其他格式) | 编程简单 <br> 可能节约内存 | 1.序列化开销 <br> 2.设置属性要操作整个数据。 |
| string v2 <br>(每个key都是一个属性 ) | 直观<br> 可以部分更新 | 1.内存占用较大 <br> 2.key较为分散 |
| hash | 直观 <br> 节省空间 <br> 可以部分更新 | 1.编程稍微复杂 <br> 2.ttl不好控制 |
* 查漏补缺
| 名称 | 范例 | 描述 |
| --- | --- | --- |
| hsetnx | hSetNx( $key, $hashKey, $value ) | 设置 key 对应 hashKey 的 value(如 hashKey 已经存在,则失败) |
| hincrby | hIncrBy( $key, $hashKey, $value ) | hashKey 自增 value,如果 hashKey 不存在,自增后hget(key,hashKey)= value |
| hincrbyfloat | hIncrByFloat( $key, $field, $increment ) | hincrby 浮点数版 |
## 六、列表
* 列表结构
* 特点
* 有序的
* 可以重复的
* 左右两边插入弹出
* 命令
| 名称 | 范例 | 描述 |
| --- | --- | --- |
| rpush | rPush( $key, $value1, $value2 = null, $valueN = null ) | 从列表右端插入值(1-N) |
| lpush | lPush( $key, $value1, $value2 = null, $valueN = null ) | 从列表左端插入值(1-N) |
| linsert | lInsert( $key, $position, $pivot, $value ) | 在 list 指定的值($pivot)前\|后($position = Redis::BEFORE\|Redis::AFTER)插入newValue($value) |
| lpop | lPop( $key ) | 从列表左侧弹出一个itme |
| rpop | rPop( $key ) | 从列表右侧弹出一个itme |
| lrem | lRem( $key, $value, $count ) | 根据 count 值,从列表中删除所有 value 相等的项。 <br> count > 0 , 从左到右,删除最多 count 个 value 相等的项; <br> count < 0 , 从右到左,删除最多Math.abs(count) 个 value 相等的项; <br> count = 0 , 删除所有value相等的项。 |
| ltrim | lTrim( $key, $start, $stop ) | 按照索引范围修剪列表,key值中保留从start 到stop 范围的下标 |
* 查询
| 名称 | 范例 | 描述 |
| --- | --- | --- |
| lrange | lRange( $key, $start, $end ) | 获取列表指定索引范围所有 item |
| lindex | lIndex( $key, $index ) | 获取列表指定索引的 item |
| llen | lLen( $key ) | 获取列表长度 |
* 改
| 名称 | 范例 | 描述 |
| --- | --- | --- |
| lset | lSet( $key, $index, $value ) | 设置列表指定索引为 value |
* 实战
* 更新微博的排列顺序,有人更新的时候,把他的微博排在首位。
* 查漏补缺
| 名称 | 范例 | 描述 |
| --- | --- | --- |
| blpop | blPop( array $keys ) | lpop阻塞版本,timeout是阻塞超时时间,timeout = 0 为永远不阻塞 |
| brpop | brPop( array $keys ) | rpop阻塞版本,timeout是阻塞超时时间,timeout = 0为永远不阻塞 |
* 总结
* 栈功能:lrush + lpop = stack
* 队列功能: lpush + rpop = queue
* 控制有固定数量的列表: lpush + ltrim = Capped Collection
* 消息队列: Lpush + brpop = Message Queue
## 集合
* 特点
* 无序的
* 无重复
* 集合间操作
* 集合内的命令
| 名称 | 范例 | 描述 |
| --- | --- | --- |
| sadd | sAdd( $key, $value1, $value2 = null, $valueN = null ) | 向集合key添加 value (如果value已存在,添加失败) |
| srem | sRem( $key, $member1, $member2 = null, $memberN = null ) | 将集合key 中的 member 移除掉 |
| srcard | sCard( $key ) | 计算集合大小 |
| sismember | sIsMember( $key, $value ) | 判断 value 是否在集合中 |
| srandmember | sRandMember( $key ) | 从集合中随机取出一个元素,不破环原集合 |
| spop | sPop( $key ) | 从集合中随机取出一个元素,并从原集合消失 |
| smembers | sMembers( $key ) | 从集合中随机弹出一个元素,返回剩余的元素 |
* 集合内实战
* 抽奖系统
* 给用户添加标签tag
* 给标签添加用户
* Like、赞、踩都可以放在集合中
* 集合间的命令
| 名称 | 范例 | 描述 |
| --- | --- | --- |
| sdiff | sDiff( $key1, $key2, $keyN = null ) | 差集 |
| sinter | sInter( $key1, $key2, $keyN = null ) | 交集 |
| sunion | sUnion( $key1, $key2, $keyN = null ) | 并集 |
* 集合间的实战
* 共同关注的好友或兴趣
* 总结
* SADD = Tagging 标签
* SPOP/SRANDMEMBER = Random item 随机数
* SADD + SINTER = Social Graph 社交相关的应用
## 有序集合
* 结构
![](https://box.kancloud.cn/920018840c359c77f82e6cd79db998dc_851x350.png =400x150)
* 集合 VS 有序集合
| 集合 | 有序集合 |
| --- | --- |
| 无重复元素 | 无重复元素 |
| 无序 | 有序 |
| element(集合内元素) | element(集合内元素) + score(分值) |
* 列表 VS 有序集合
| 列表 | 有序集合 |
| --- | --- |
| 可以有重复元素 | 无重复元素 |
| 有序 | 有序 |
| element | element + score |
* 命令
| 名称 | 范例 | 描述 |
| --- | --- | --- |
| zadd | zAdd( $key, $score1, $value1, $score2 = null, $value2 = null, $scoreN = null, $valueN = null ) | 添加score 和 value |
| zrem | zRem( $key, $member1, $member2 = null, $memberN = null ) | 删除元素 |
| zscore | zScore( $key, $member ) | 返回元素的分值,升序,从低到高 |
| zincrby | zIncrBy( $key, $value, $member ) | 增加或减少元素的分值 |
| zcard | zCard( $key ) | 返回元素的总个数 |
| zrange | zRange( $key, $start, $end, $withscores = null ) | 返回指定索引范围内的升序元素,$withscores = ture 返回分值 |
| zrangebyscore | zRangeByScore( $key, $start, $end, array $options = array() ) | 返回指定分值范围内的升序元素,$options = array('withscores' => TRUE, 'limit' => array(1, 1)) |
| zcount | zCount( $key, $start, $end ) | 返回有序集合内在指定分数范围内的个数 |
| zremrangebyrank | zRemRangeByRank( $key, $start, $end ) | 删除指定排名内的升序元素 |
| zremrangebyscore | zDeleteRangeByRank( $key, $start, $end ) | 删除指定分数内的升序元素 |
* 实战
* 排行榜
* 查漏补缺
| 名称 | 范例 | 描述 |
| --- | --- | --- |
| zrevrank | zRevRank( $key, $member ) | 返回元素的分值,降序,从高到地。|
| zrevrange | zRevRange( $key, $start, $end, $withscore = null ) | 返回指定索引范围内的降序元素,$withscores = ture 返回分值 |
| zrevrangebyscore | zRevRangeByScore( $key, $start, $end, array $options = array() ) | 返回指定分值范围内的降序元素,$options = array('withscores' => TRUE, 'limit' => array(1, 1)) |
| zinterstore | zInter($Output, $ZSetKeys, array $Weights = null, $aggregateFunction = 'SUM') | 交集 |
| zunionstore | zUnion($Output, $ZSetKeys, array $Weights = null, $aggregateFunction = 'SUM') | 并集 |
* 总结
| 操作类型 | 命令 |
| --- | --- |
| 基本操作 | zadd、zrem、zcard、zincrby、zscore |
| 范围操作 | zrange、zrangebyscore、zcount、zremrangebyrank|
| 集合操作 | zunionstore、zinterstore |