一、Redis介绍
Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。
二、五大基本数据类型
Redis在互联网公司一般有以下应用:
● String:缓存、限流、计数器、统计多单位数量、分布式锁、分布式session
● Hash:存储对象、存储用户信息、用户主页访问量、组合查询
● List:微博关注人时间轴列表、栈(LPUSH - LPOP)、队列(LPUSH - RPOP)和 阻塞队列
● Set:赞、踩、标签、好友关系
● Zset:排行榜
KEYS *:查看所有的key
SELECT 0:选择第一个库
FLUSH db:清除指定库
DEL key:该命令用于在 key 存在是删除 key。
DUMP key:序列化给定 key ,并返回被序列化的值。
EXISTS key:检查给定 key 是否存在。
EXPIRE key seconds:为给定 key 设置过期时间。
EXPIREAT key timestamp:EXPIREAT 的作用和 EXPIRE 类似,都用于为 key 设置过期时间。 不同在于 EXPIREAT 命令接受的时间参数是 UNIX 时间戳(unix timestamp)。
PEXPIRE key milliseconds:设置 key 的过期时间亿以毫秒计。
PEXPIREAT key milliseconds-timestamp:设置 key 过期时间的时间戳(unix timestamp) 以毫秒计
KEYS pattern:查找所有符合给定模式( pattern)的 key 。
MOVE key db:将当前数据库的 key 移动到给定的数据库 db 当中。
PERSIST key:移除 key 的过期时间,key 将持久保持。
PTTL key:以毫秒为单位返回 key 的剩余的过期时间。
TTL key:以秒为单位,返回给定 key 的剩余生存时间(TTL, time to live)。
RANDOMKEY:从当前数据库中随机返回一个 key 。
RENAME key newkey:修改 key 的名称
RENAMENX key newkey:仅当 newkey 不存在时,将 key 改名为 newkey 。
TYPE key:返回 key 所储存的值的类型。
127.0.0.1:6379> KEYS * // 查看所有的key (empty list or set) 127.0.0.1:6379> SET name cyan // set key OK 127.0.0.1:6379> KEYS * 1) "name" 127.0.0.1:6379> SET age 18 OK 127.0.0.1:6379> KEYS * 1) "name" 2) "age" 127.0.0.1:6379> EXISTS name // 判断当前的key是否存在 (integer) 1 127.0.0.1:6379> EXISTS name1 (integer) 0 127.0.0.1:6379> MOVE name 1 // 将当前数据库中的key移动到某个数据库,目标有则不能移动 (integer) 1 127.0.0.1:6379> KEYS * 1) "age" 127.0.0.1:6379> SET name cyan OK 127.0.0.1:6379> KEYS * 1) "name" 2) "age" 127.0.0.1:6379> GET name // 获取key "cyan" 127.0.0.1:6379> EXPIRE name 10 // 设置10秒过期 (integer) 1 127.0.0.1:6379> TTL name // 查看当前key的剩余过期时间 (integer) 7 127.0.0.1:6379> TTL name (integer) 1 127.0.0.1:6379> TTL name (integer) -2 127.0.0.1:6379> GET name (nil) 127.0.0.1:6379> KEYS * 1) "age" 127.0.0.1:6379> TYPE age // 查看当前key的类型 string
1)String(字符串)
string类型是二进制安全的。意思是redis的string可以包含任何数据。比如jpg图片或者序列化的对象 。
string类型是Redis最基本的数据类型,一个键最大能存储512MB。
基本命令:
SET key value...:设置key
GET key...:获取key
DEL key...:删除key
GETRANGE key 0 -1:截取字符串
GETSET key value:先GET后SET,如果不存在则返回空 然后创建,如果存在返回旧的 然后设置新的
MSET key1 v1 key2 v2:批量设置
MGET key1 key2:批量获取
SETNX key value:不存在就插入(not exists)
SETEX key time value:设置key的过期时间(expire)
SETRANGE key index value:从index开始替换value
INCR value:递增1
INCRBY value int:递增n
DECR value:递减1
DECYBY value int:递减n
INCRBYFLOAT key float:浮点数递增
APPEND key value:追加字符串,不存在就添加
STRLEN key:获得长度
127.0.0.1:6379> SET key1 v1 // 设置key OK 127.0.0.1:6379> GET key1 // 获取key值 "v1" 127.0.0.1:6379> KEYS * // 查看所有的key 1) "key1" 127.0.0.1:6379> EXISTS key1 // 判断该key是否存在 (integer) 1 127.0.0.1:6379> APPEND key1 "hello" // 追加字符串,如果当前key不存在,相当于设置key (integer) 7 127.0.0.1:6379> GET key1 "v1hello" 127.0.0.1:6379> STRLEN key1 // 获得字符串的长度 (integer) 7 127.0.0.1:6379> APPEND key1 ",cyan" (integer) 12 127.0.0.1:6379> STRLEN key1 (integer) 12 // ####################################### 127.0.0.1:6379> set age 1 // age设置初始值为1 OK 127.0.0.1:6379> get age "1" 127.0.0.1:6379> incr age // age自增1 (integer) 2 127.0.0.1:6379> incrby age 10 // age自增n (integer) 12 127.0.0.1:6379> decr age // age自减1 (integer) 11 127.0.0.1:6379> decrby age 7 // age自减n (integer) 4 // ####################################### 127.0.0.1:6379> get key1 "v1hello,cyan" 127.0.0.1:6379> getrange key1 0 3 // 截取字符串[0,3] "v1he" 127.0.0.1:6379> getrange key1 0 -1 // 获取全部的字符串 与 get key一样 "v1hello,cyan" 127.0.0.1:6379> setrange key1 0 xx // 替换自定位置开始的字符串 (integer) 12 127.0.0.1:6379> get key1 "xxhello,cyan" // ####################################### // setex(set with expire)// 设置过期时间 // setnx(set if not exist) // 不存在则设置(在分布式锁中常用) 127.0.0.1:6379> setex haha 20 xiaole // 设置key haha ,20秒后过期 OK 127.0.0.1:6379> ttl haha (integer) 17 127.0.0.1:6379> ttl haha (integer) -2 127.0.0.1:6379> setnx mykey ccccc // 如果mykey,不存在,创建mykey (integer) 1 127.0.0.1:6379> keys * 1) "key1" 2) "age" 3) "mykey" 127.0.0.1:6379> setnx mykey aaaaa // 如果mykey存在,创建失败 (integer) 0 127.0.0.1:6379> get mykey "ccccc" 127.0.0.1:6379> // ####################################### 127.0.0.1:6379> KEYS * (empty list or set) 127.0.0.1:6379> mset k1 v1 k2 v2 k3 v3 k4 v4 k5 v5 // 批量设置key OK 127.0.0.1:6379> KEYS * 1) "k1" 2) "k2" 3) "k3" 4) "k4" 5) "k5" 127.0.0.1:6379> mget k1 k2 k3 k4 k5 // 批量获取key 1) "v1" 2) "v2" 3) "v3" 4) "v4" 5) "v5" 127.0.0.1:6379> msetnx k1 v1 k6 v6 // msetnx 是一个原子性的操作,要么一起成功,要么一起失败 (integer) 0 127.0.0.1:6379> keys * 1) "k1" 2) "k2" 3) "k3" 4) "k4" 5) "k5" // 对象 - 设置一个user:1 对象 值为json字符串来保存一个对象 127.0.0.1:6379> set user:1 {name:zhangsan,age:3} OK 127.0.0.1:6379> get user:1 "{name:zhangsan,age:3}" // 这里使用一个巧妙的设计:user:1:name zhangsan user:1:age 12 127.0.0.1:6379> mset user:1:name zhangshan user:1:age 12 OK 127.0.0.1:6379> keys * 1) "user:1:age" 2) "user:1:name" 127.0.0.1:6379> mget user:1:name user:1:age 1) "zhangshan" 2) "12" // ####################################### // getset # 先get然后set 127.0.0.1:6379> getset db redis // 如果不存在则返回nil (nil) 127.0.0.1:6379> get db "redis" 127.0.0.1:6379> getset db mongodb // 如果存在,先获取值,然后再设置新的值 "redis" 127.0.0.1:6379> get db "mongodb"
数据结构是相同的!
String类似的使用场景:value除了是我们的字符串还可以是数字!
- 计数器
- 统计多单位数量
- 粉丝数
- 对象缓存存储
2)List(列表)
Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边),在Redis中,可以把list当做,栈、队列、阻塞队列来使用!
基本命令:所有的list命令都是l开头的
LPUSH key value...:左插入,将一个或多个value插入头部
RPUSH key value...:右插入,将一个或多个value插入尾部
LRANGE key 0 -1:数据集合,
LPOP key:弹出元素,移除list的左边第一个元素
RPOP key:弹出元素,移除list的右边第一个元素
LLEN key:list长度
LREM key count value:删除指定个数元素
LINDEX key index:返回指定index索引的值
LSET key index value:更新索引的值,如果不存在则报错
LIRIM key start stop:通过下标截取指定的长度(删除元素)
LINSERT key [ before | after ] povit value:在已有元素pivot前面或后面插入value
RPOPLPUSH source destination:移除source列表的最后一个元素,将它移动到destination列表中(剪切)
127.0.0.1:6379> LPUSH list one // 将一个或多个值插入到列表的头部(左) (integer) 1 127.0.0.1:6379> LPUSH list two# (integer) 2 127.0.0.1:6379> LPUSH list three# (integer) 3 127.0.0.1:6379> LRANGE list 0 -1 // 获取list中的值 1) "three" 2) "two" 3) "one" 127.0.0.1:6379> LRANGE list 0 1 // 通过区间获取list中的值 1) "three" 2) "two" 127.0.0.1:6379> RPUSH list right // 将一个或多个值插入到列表的头部(右) (integer) 4 127.0.0.1:6379> LRANGE list 0 -1 1) "three" 2) "two" 3) "one" 4) "right" // ####################################### 127.0.0.1:6379> LPOP list // 移除list的第一个元素 "three" 127.0.0.1:6379> RPOP list // 移除list的最后一个元素 "right" 127.0.0.1:6379> LRANGE list 0 -1 1) "two" 2) "one" // ####################################### 127.0.0.1:6379> LINDEX list 0 // 通过index下标获取list中的值 "two" 127.0.0.1:6379> LINDEX list 1 "one" 127.0.0.1:6379> LLEN list // 获取列表的长度 (integer) 2 // ####################################### 127.0.0.1:6379> LRANGE list 0 -1 1) "three" 2) "three" 3) "two" 4) "one" 127.0.0.1:6379> LREM list 1 one // 移除list中指定个数的value,精确匹配 (integer) 1 127.0.0.1:6379> LRANGE list 0 -1 1) "three" 2) "three" 3) "two" 127.0.0.1:6379> LREM list 2 three // 移除两个value (integer) 2 127.0.0.1:6379> LRANGE list 0 -1 1) "two" // ####################################### 127.0.0.1:6379> LRANGE list 0 -1 1) "hello0" 2) "hello1" 3) "hello2" 4) "hello3" 127.0.0.1:6379> LTRIM list 1 2 // 通过下标截取指定的长度(删除元素) OK 127.0.0.1:6379> LRANGE list 0 -1 1) "hello1" 2) "hello2" // ####################################### 127.0.0.1:6379> LRANGE list 0 -1 1) "hello0" 2) "hello1" 3) "hello2" 127.0.0.1:6379> RPOPLPUSH list mylist // 移除列表的最后一个元素,将它移动到新的列表中 "hello2" 127.0.0.1:6379> LRANGE list 0 -1 // 查看原来的列表 1) "hello0" 2) "hello1" 127.0.0.1:6379> LRANGE mylist 0 -1 // 查看目标列表 1) "hello2" // ####################################### 127.0.0.1:6379> LRANGE list 0 -1 1) "value3" 2) "value2" 3) "value1" 127.0.0.1:6379> EXISTS list // 判断这个列表是否存在 (integer) 1 127.0.0.1:6379> LSET list 1 hahahaha // 如果存在,更新当前下标的值 OK 127.0.0.1:6379> LRANGE list 0 -1 1) "value3" 2) "hahahaha" 3) "value1" 127.0.0.1:6379> LSET list 5 value5 // 如果不存在则会报错 (error) ERR index out of range // ####################################### // linsert # 插入,在列表中的某个value前面或者后面插入一个新的value 127.0.0.1:6379> LRANGE mylist 0 -1 1) "hello" 2) "word" 127.0.0.1:6379> LINSERT mylist before hello haha // 在hello前面插入haha (integer) 3 127.0.0.1:6379> LRANGE mylist 0 -1 1) "haha" 2) "hello" 3) "word" 127.0.0.1:6379> LINSERT mylist after word new // 在word后面插入new (integer) 4 127.0.0.1:6379> LRANGE mylist 0 -1 1) "haha" 2) "hello" 3) "word" 4) "new"
小结:
- 它实际上是一个链表,before Node after,left right 都可以插入值
- 如果 key 不存在,创建新的链表
- 如果 key 存在,新增内容
- 如果移除了所有值,空链表,也代表不存在!
- 在两边插入或改动值,效率最高!中间元素,相对来说效率会低一点~
消息队列!消息队列(LPUSH、RPOP),栈(LPUSH、LPOP)
3)Set(集合)
Redis的Set是string类型的无序集合。
集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是O(1)。
基本命令:
SADD key member...:添加一个或多个成员
SREM key member...:删除一个或多个成员
SMEMBERS key:数据集合
SCERD key:获取个数
SISMEMBER key member:判断元素是否在集合中
SIDFF| SINTER | SUNION:集合间运算 - 差集 | 交集 | 并集
SRANDMEMBER key [count]:随机获取集合中一个或多个元素
SPOP key:随机删除集合中的一个元素
SMOVE key1 key2 value:将key1中的某一个值移动到另key2集合中
127.0.0.1:6379> SADD myset "hello" // set集合中添加元素 (integer) 1 127.0.0.1:6379> SADD myset "cyan" "hahaha" (integer) 2 127.0.0.1:6379> SMEMBERS myset // 查看指定set的所有值 1) "hahaha" 2) "cyan" 3) "hello" 127.0.0.1:6379> SISMEMBER myset hello // 判断元素是否在集合中 (integer) 1 127.0.0.1:6379> SISMEMBER myset hehe (integer) 0 // ####################################### 127.0.0.1:6379> SCARD myset // 获取集合中的个数 (integer) 3 // ####################################### 127.0.0.1:6379> SREM myset hahaha // 删除set中的元素 (integer) 1 127.0.0.1:6379> SCARD myset (integer) 2 127.0.0.1:6379> SMEMBERS myset 1) "cyan" 2) "hello" // ####################################### 127.0.0.1:6379> SMEMBERS myset 1) "value3" 2) "value1" 3) "value6" 4) "value7" 5) "value4" 6) "value5" 7) "value2" 127.0.0.1:6379> SRANDMEMBER myset // 随机抽取出一个元素 "value1" 127.0.0.1:6379> SRANDMEMBER myset "value3" 127.0.0.1:6379> SRANDMEMBER myset "value5" 127.0.0.1:6379> SRANDMEMBER myset 3 // 随机抽取除n个元素 1) "value6" 2) "value7" 3) "value3" // ####################################### 127.0.0.1:6379> SMEMBERS myset 1) "value3" 2) "value1" 3) "value6" 4) "value7" 5) "value4" 6) "value5" 7) "value2" 127.0.0.1:6379> SPOP myset // 随机删除集合中的一个元素 "value6" 127.0.0.1:6379> SPOP myset 2 // 随机删除集合中的n个元素 1) "value7" 2) "value2" 127.0.0.1:6379> SMEMBERS myset 1) "value1" 2) "value3" 3) "value4" 4) "value5" // ####################################### 127.0.0.1:6379> SMEMBERS myset 1) "value2" 2) "value3" 3) "value1" 127.0.0.1:6379> SMEMBERS myset2 1) "haha" 127.0.0.1:6379> SMOVE myset myset2 value1 // 将一个指定的值移动到另一个set集合中 (integer) 1 127.0.0.1:6379> SMEMBERS myset 1) "value2" 2) "value3" 127.0.0.1:6379> SMEMBERS myset2 1) "haha" 2) "value1" // ####################################### 127.0.0.1:6379> SADD set1 v1 v2 v3 v4 (integer) 4 127.0.0.1:6379> SADD set2 v3 v4 v5 v6 v7 (integer) 5 127.0.0.1:6379> SDIFF set1 set2 // 差集 1) "v2" 2) "v1" 127.0.0.1:6379> SDIFF set2 set1 1) "v6" 2) "v5" 3) "v7" 127.0.0.1:6379> SINTER set1 set2 // 交集 - 共同好友可以这样实现 1) "v3" 2) "v4" 127.0.0.1:6379> SUNION set1 set2 // 并集 1) "v6" 2) "v3" 3) "v2" 4) "v5" 5) "v7" 6) "v4" 7) "v1"
微博,A用户将所有关注的人放在一个set集合中!将他的粉丝也放在一个集合中
共同关注,共同爱好,二度好友,推荐好友!
4)Hash(哈希)
Redis hash 是一个键值(key=>value)对集合,本质和String类型没有太大区别。
Redis hash是一个string类型的field和value的映射表,hash特别适合用于存储对象。
基本命令:
HSET key field value:添加字段
HGET key field:获取字段
HMSET key field1 value1 field2 value2...:批量添加字段
HMGET key field1 field2... :批量获取字段
HGETALL key:获取所有的field字段
HEXISTS key field:判断field是否存在
HSETNX key field:如果不存在的就添加成功,存在就添加失败
HINCRBY key field int:数值操作,加减
HDEL key field:删除
HKEYS key:只取key
HVALS key:只取value
HLED key:长度
127.0.0.1:6379> HSET user name cyan // hash添加一个 key-value (integer) 1 127.0.0.1:6379> HMSET user age 11 address shenzhen // hash添加多个key-value OK 127.0.0.1:6379> HGET user name // 获取一个hash-key的值 "cyan" 127.0.0.1:6379> HMGET user age address // 获取多个hash-key的value 1) "11" 2) "shenzhen" 127.0.0.1:6379> HGETALL user // 获取全部hash的key-value 1) "name" 2) "cyan" 3) "age" 4) "11" 5) "address" 6) "shenzhen" 127.0.0.1:6379> HDEL user address // 删除指定的key,对应的value也会删除 (integer) 1 127.0.0.1:6379> HGETALL user 1) "name" 2) "cyan" 3) "age" 4) "11" 127.0.0.1:6379> HLEN user // 获取hash的字段数量 (integer) 2 127.0.0.1:6379> HEXISTS user name // 判断hash指定字段是否存在 (integer) 1 127.0.0.1:6379> HEXISTS user address (integer) 0 127.0.0.1:6379> HKEYS user // 获取指定hash所有的key 1) "name" 2) "age" 127.0.0.1:6379> HVALS user // 获取指定hash所有的value 1) "cyan" 2) "11" 127.0.0.1:6379> HINCRBY user age 1 // 整数指定增量 (integer) 12 127.0.0.1:6379> 127.0.0.1:6379> HINCRBY user age 1 // +1 (integer) 13 127.0.0.1:6379> HINCRBY user age -4 // -4 (integer) 9 127.0.0.1:6379> HSETNX user address shenzhen // 如果不存在则 可以添加 (integer) 1 127.0.0.1:6379> HSETNX user address shenzhen // 如果不存在 不可以添加 (integer) 0
hash变更的数据 user name age ,尤其是用户信息之类的,经常变动的信息!hash更适合于对象的存储,String更加适合字符串存储!
5)Zset(有序集合)
Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。
不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
zset的成员是唯一的,但分数(score)却可以重复。
基本命令:
ZADD key score member:添加number成员并且标记score分数
ZINCRBY key score member:增长number成员score分数
ZSCORE key member:获取member成员的分数
ZRANGE key start stop [WITHSCORES]:按照升序,获取指定范围的成员,选参withscores显示分数
ZREVRANGE key start stop [WITHSCORES]:按照降序,获取指定范围的成员,选参withscores显示分数
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]: 按照升序,通过分数返回有序集合指定区间内的成员,选参 withscores 显示数值,limit 分页
ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]:按照降序,通过分数返回有序集合指定区间内的成员,选参 withscores 显示数值,limit 分页
ZCARD key:返回成员数量
ZCOUNT key min max:获得指定score数值范围内的member成员个数
ZREM key member...:删除一个或多个元素
ZREMRANGEBYRANK key start stop:移除有序集合中给定的排名区间的所有成员
ZREMRANGEBYSCORE key min max:移除有序集合中给定的分数区间的所有成员
ZRANK key member:按照升序,返回有序集合中指定成员的索引
ZREVRANK key member:按照降序,返回有序集合中指定成员的排名
ZINTERSTORE new_key numkeys key1 key2:计算给定的一个或多个有序集的交集并将结果集存储在新的有序集合 key 中
ZUNIONSTORE new_key numkeys key2 key3:计算给定的一个或多个有序集的并集,并存储在新的 key 中
127.0.0.1:6379> ZADD zset 1 one // 添加一个值 (integer) 1 127.0.0.1:6379> ZADD zset 2 two 3 three // 添加多个值 (integer) 2 127.0.0.1:6379> ZRANGE zset 0 -1 // 查看所有值 - 升序 1) "one" 2) "two" 3) "three" 127.0.0.1:6379> ZREVRANGE zset 0 -1 // 查看所有值 - 降序 1) "three" 2) "two" 3) "one" // ####################################### 127.0.0.1:6379> ZADD salary 7000 xiaohong // 根据薪水排序添加3个用户 (integer) 1 127.0.0.1:6379> ZADD salary 2500 diaomao (integer) 1 127.0.0.1:6379> ZADD salary 5000 shadiao (integer) 1 127.0.0.1:6379> ZRANGEBYSCORE salary -inf +inf // 显示全部的用户 从小到大 1) "diaomao" 2) "shadiao" 3) "xiaohong" 127.0.0.1:6379> ZRANGEBYSCORE salary -inf +inf withscores // 显示全部的用户并且附带薪水值 1) "diaomao" 2) "2500" 3) "shadiao" 4) "5000" 5) "xiaohong" 6) "7000" 127.0.0.1:6379> ZRANGEBYSCORE salary -inf 5000 withscores // 显示工资小于5000的员工与工资值,升序 1) "diaomao" 2) "2500" 3) "shadiao" 4) "5000" // ####################################### 127.0.0.1:6379> ZCOUNT salary -inf +inf // 获取指定区间中的个数 (integer) 3 127.0.0.1:6379> ZREM salary diaomao // 移除元素 (integer) 1 127.0.0.1:6379> ZCARD salary // 获取有序集合中的个数 (integer) 2 test
zset总结:排序,存储班级成绩表,工资表排序,排行榜实现,取Top N 测试!
普通消息 1 ,重要消息 2 ,带权重进行判断!
三、特殊数据类型
1)geospatial(地理位置)
朋友的定位,附近的人,打车距离计算?
Redis的Geo在Redis3.2版本就推出了!这个功能可以推算地理位置的信息,两地之间的距离,方圆几里的人!
经纬度查询:http://www.jsons.cn/lngcode/
相关命令:
GEOADD key longitude latitude member [longitude latitude member ...]:添加地理位置
GEODIST key member1 member2 [unit]:返回两个位置之间的距离
GEOHASH key member [member ...]:返回11个字符串的Geohash字符串
GEOPOS key member [member ...]:返回给定位置的经纬度
GEORADIUS key longitude latitude radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count]:根据给定的经纬度为中心,获得指定半径距离内的元素
GEORADIUSBYMEMBER key member radius m|km|ft|mi [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count]:根据给定的位置为中心,获得指定半径距离内的元素
● GEOADD key 经度 纬度 值:添加地理位置
127.0.0.1:6379> GEOADD china 116.405285 39.904989 beijing (integer) 1 127.0.0.1:6379> GEOADD china 121.472644 31.231706 shanghai (integer) 1 127.0.0.1:6379> GEOADD china 113.280637 23.125178 guangzhou (integer) 1 127.0.0.1:6379> GEOADD china 114.085947 22.547 shenzhen (integer) 1 127.0.0.1:6379> GEOADD china 120.153576 30.287459 hangzhou (integer) 1 127.0.0.1:6379> GEOADD china 114.298572 30.584355 wuhan (integer) 1
● GEOPOS key 值:从key里返回所有给定位置元素的位置(经度和纬度)。
127.0.0.1:6379> GEOPOS china beijing shanghai 1) 1) "116.40528291463851929" 2) "39.9049884229125027" 2) 1) "121.47264629602432251" 2) "31.23170490709807012"
● GEODIST 键 value1 value2 [ m | km | mi | ft ]:返回两个给定位置之间的距离,如果有一个不存在 就命令返回空值。默认单位米m;
127.0.0.1:6379> GEODIST china beijing shanghai m "1067597.9668" 127.0.0.1:6379> GEODIST china guangzhou shenzhen m "104642.6221"
● GEORADIUS key 经度 纬度 距离 [ m | km | ft | mi ] [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count]:根据key以给定的经纬度为中心,获得指定半径距离内的元素
127.0.0.1:6379> GEORADIUS china 115 30 700 km // 根据 china 以 115 30 这个经纬度为中心,寻找方圆700km内的城市 1) "wuhan" 2) "hangzhou" 3) "shanghai" 127.0.0.1:6379> GEORADIUS china 115 30 700 km withcoord // 显示他人的地理位置信息 1) 1) "wuhan" 2) 1) "114.29857403039932251" 2) "30.58435486605102227" 2) 1) "hangzhou" 2) 1) "120.15357345342636108" 2) "30.28745790721532671" 3) 1) "shanghai" 2) 1) "121.47264629602432251" 2) "31.23170490709807012" 127.0.0.1:6379> GEORADIUS china 115 30 700 km withdist // 显示到中心距离的位置 1) 1) "wuhan" 2) "93.6075" 2) 1) "hangzhou" 2) "496.6834" 3) 1) "shanghai" 2) "634.4295" 127.0.0.1:6379> GEORADIUS china 115 30 700 km count 2 // 限制获取数量 1) "wuhan" 2) "hangzhou" 127.0.0.1:6379> GEORADIUS china 115 30 700 km desc // 降序 1) "shanghai" 2) "hangzhou" 3) "wuhan" 127.0.0.1:6379> GEORADIUS china 115 30 700 km asc // 升序 1) "wuhan" 2) "hangzhou" 3) "shanghai"
● GEORADIUSBYMEMBER key member 距离 [ m | km | ft | mi ]:找出位于key中指定member范围距离内的元素
127.0.0.1:6379> GEORADIUSBYMEMBER china hangzhou 1000 km 1) "wuhan" 2) "hangzhou" 3) "shanghai"
● GEOHASH key member:返回11个字符串的Geohash字符串
127.0.0.1:6379> GEOHASH china beijing 1) "wx4g0b7xrt0" 127.0.0.1:6379> GEOHASH china beijing shanghai 1) "wx4g0b7xrt0" 2) "wtw3sjt9vg0"
Geo底层的实现原理其实就是Zset!我们可以使用Zset命令来操作Geo!
127.0.0.1:6379> ZRANGE china 0 -1 1) "shenzhen" 2) "guangzhou" 3) "wuhan" 4) "hangzhou" 5) "shanghai" 6) "beijing" 127.0.0.1:6379> ZREM china hangzhou (integer) 1 127.0.0.1:6379> ZRANGE china 0 -1 1) "shenzhen" 2) "guangzhou" 3) "wuhan" 4) "shanghai" 5) "beijing"
2)hyperloglog
Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。
在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。
但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。
Hyperloglog命令:
PFADD key element [element ...]:添加指定元素到 HyperLogLog 中。
PFCOUNT key [key ...]:返回给定 HyperLogLog 的基数估算值。
PFMERGE destkey sourcekey [sourcekey ...]:将多个 HyperLogLog 合并为一个 HyperLogLog
127.0.0.1:6379> PFADD mykey1 a b c d e f g h i// 添加元素 (integer) 1 127.0.0.1:6379> PFADD mykey2 g h i j k l m n o p q r s t (integer) 1 127.0.0.1:6379> PFCOUNT mykey1 // 基数统计 (integer) 9 127.0.0.1:6379> PFCOUNT mykey2 (integer) 13 127.0.0.1:6379> PFMERGE mykey3 mykey1 mykey2 // 合并 OK 127.0.0.1:6379> PFCOUNT mykey3 (integer) 19
3)bitmaps
位存储:
统计用户信息,活跃,不活跃,登录、未登录,打卡,365打卡。两个状态的,都可以使用Bitmaps。
Bitmaps 位图数据结构,都是操作二进制来进行记录,就只有0和1两个状态。
365天 = 365bit 1字节 = 8bit 46个字节左右
命令:GETBIT | SETBIT | BITCOUNT | BITOP
记录打卡:周一:1、周二:1、周三:1、周四:0、周五:1...
127.0.0.1:6379> SETBIT sign 0 1 (integer) 0 127.0.0.1:6379> SETBIT sign 1 1 (integer) 0 127.0.0.1:6379> SETBIT sign 2 1 (integer) 0 127.0.0.1:6379> SETBIT sign 3 0 (integer) 0 127.0.0.1:6379> SETBIT sign 4 1 (integer) 0 127.0.0.1:6379> SETBIT sign 5 1 (integer) 0 127.0.0.1:6379> SETBIT sign 6 0 (integer) 0
查看打卡记录
// 查看单日打卡 127.0.0.1:6379> GETBIT sign 0 (integer) 1 127.0.0.1:6379> GETBIT sign 3 (integer) 0 // 统计一周打卡记录 127.0.0.1:6379> BITCOUNT sign (integer) 5