String类型使用场景:
计数器统计多单位数量uid:123123:follow粉丝数对象缓存基本数据类型,列表。 在redis中可以将list用作栈、队列、阻塞队列! 所有的list命令以 l l l开头
插入数据 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 # 通过区间获取具体的值 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> lrange list 0 -1 1) "three" 2) "two" 3) "one" 4) "right" 127.0.0.1:6379> lpop list # 从左侧移除数据 "three" 127.0.0.1:6379> lrange list 0 -1 1) "two" 2) "one" 3) "right" 127.0.0.1:6379> rpop list # 从右侧移除数据 "right" 127.0.0.1:6379> lrange list 0 -1 1) "two" 2) "one" 通过下标获得某一个值 127.0.0.1:6379> lrange list 0 -1 1) "two" 2) "one" 127.0.0.1:6379> lindex list 1 "one" 127.0.0.1:6379> lindex list 0 "two" 127.0.0.1:6379> list有多少元素 127.0.0.1:6379> llen list (integer) 2 移除指定的值 127.0.0.1:6379> lpush list three (integer) 3 127.0.0.1:6379> lpush list three (integer) 4 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 (integer) 2 127.0.0.1:6379> lrange list 0 -1 1) "two" 只保留某一部分的元素 127.0.0.1:6379> rpush mylist "hello" (integer) 1 127.0.0.1:6379> rpush mylist "hello1" (integer) 2 127.0.0.1:6379> rpush mylist "hello12" (integer) 3 127.0.0.1:6379> rpush mylist "hello13" (integer) 4 127.0.0.1:6379> ltrim mylist 1 2 # 通过下标截取指定长度,只保留截取的元素 OK 127.0.0.1:6379> lrange mylist 0 -1 1) "hello1" 2) "hello12" 组合操作rpoplpush 27.0.0.1:6379> lrange mylist 0 -1 1) "hello1" 2) "hello12" 127.0.0.1:6379> rpoplpush mylist mylist # 从尾部弹出,并从头部加入指定list "hello12" 127.0.0.1:6379> lrange mylist 0 -1 1) "hello12" 2) "hello1" 更新list中的值 127.0.0.1:6379> lpush list value1 (integer) 1 127.0.0.1:6379> lrange list 0 -1 1) "value1" 127.0.0.1:6379> lset list 0 item # 设置list下标为0的值为item OK 127.0.0.1:6379> lrange list 0 -1 1) "item" 127.0.0.1:6379> lset list 1 a # 值不存在无法设置 (error) ERR index out of range 插入操作 127.0.0.1:6379> lpush mylist hello (integer) 1 127.0.0.1:6379> lpush mylist world (integer) 2 127.0.0.1:6379> lrange mylist 0 -1 1) "world" 2) "hello" 127.0.0.1:6379> linsert mylist before world other # 在列表某个值前插入 (integer) 3 127.0.0.1:6379> lrange mylist 0 -1 1) "other" 2) "world" 3) "hello" 127.0.0.1:6379> linsert mylist after world new # 在列表某个值后插入 (integer) 4 127.0.0.1:6379> lrange mylist 0 -1 1) "other" 2) "world" 3) "new" 4) "hello"小结
list实际上是一个链表如果key不存在则创建新链表如果key存在则新增内容如果移除了所有值则代表空链表,也不存在可以作为消息队列、栈使用set中的值不能重复 set命令以s开头
添加元素、查看元素、判断值是否存在 127.0.0.1:6379> sadd myset hello # set集合中添加元素 (integer) 1 127.0.0.1:6379> smembers myset # 查看指定set的所有值 1) "hello" 127.0.0.1:6379> sismember myset hello # 判断某个值是否在集合中 (integer) 1 获取集合元素个数 127.0.0.1:6379> scard myset (integer) 1 移除元素 127.0.0.1:6379> sadd myset nihao (integer) 1 127.0.0.1:6379> srem myset hello # 移除myset中的hello (integer) 1 127.0.0.1:6379> smembers myset 1) "nihao" set为无序不重复集合,可以抽随机 127.0.0.1:6379> sadd myset v1 (integer) 1 127.0.0.1:6379> sadd myset v2 (integer) 1 127.0.0.1:6379> sadd myset v3 (integer) 1 127.0.0.1:6379> srandmember myset # 随机抽一个元素 "nihao" 127.0.0.1:6379> srandmember myset "v2" 127.0.0.1:6379> srandmember myset 2 # 随机抽选指定个数的元素 1) "v1" 2) "v2" 随机删除元素 127.0.0.1:6379> smembers myset 1) "v3" 2) "v1" 3) "v2" 4) "nihao" 127.0.0.1:6379> spop myset # 随机删除元素 "v3" 将一个指定的值移动到另外一个set中 127.0.0.1:6379> sadd myset hello (integer) 1 127.0.0.1:6379> sadd myset world (integer) 1 127.0.0.1:6379> sadd myset warms (integer) 1 127.0.0.1:6379> sadd myset2 set2 (integer) 1 127.0.0.1:6379> smembers myset 1) "hello" 2) "warms" 3) "world" 127.0.0.1:6379> smembers myset2 1) "set2" 127.0.0.1:6379> smove myset myset2 warms # 将指定的值移动到另一个集合中 (integer) 1 127.0.0.1:6379> smembers myset2 1) "warms" 2) "set2" 127.0.0.1:6379> smembers myset 1) "hello" 2) "world" 并集、差集、交集 127.0.0.1:6379> sadd k1 a (integer) 1 127.0.0.1:6379> sadd k1 b (integer) 1 127.0.0.1:6379> sadd k1 c (integer) 1 127.0.0.1:6379> sadd k2 c (integer) 1 127.0.0.1:6379> sadd k2 d (integer) 1 127.0.0.1:6379> sadd k2 e (integer) 1 127.0.0.1:6379> sdiff k1 k2 # 差集 1) "b" 2) "a" 127.0.0.1:6379> sinter k1 k2 # 交集 (共同好友可以这样实现) 1) "c" 127.0.0.1:6379> sunion k1 k2 # 并集 1) "b" 2) "c" 3) "e" 4) "a" 5) "d"Map集合, Key - Map,这时候的值为一个Map集合!本质和String类型没有太大区别,还是简单的Key-Value。 所有的Hash命令以h开头
设置与获取 127.0.0.1:6379> hset myhash field1 warms # 设置一个 key-value (integer) 1 127.0.0.1:6379> hget myhash field1 # 获取1个字段值 "warms" 127.0.0.1:6379> hmset myhash field1 hello field2 world # set多个key-value OK 127.0.0.1:6379> hmget myhash field1 field2 # 获取多个字段值 1) "hello" 2) "world" 127.0.0.1:6379> hgetall myhash # 获取全部数据 1) "field1" 2) "hello" 3) "field2" 4) "world" 删除字段 127.0.0.1:6379> hdel myhash field1 # 删除hash指定的key字段 (integer) 1 127.0.0.1:6379> hgetall myhash 1) "field2" 2) "world" 获取hash中有几个键值对 127.0.0.1:6379> hgetall myhash 1) "field2" 2) "world" 3) "field1" 4) "hello" 127.0.0.1:6379> hlen myhash (integer) 2 判断某个字段是否存在 127.0.0.1:6379> hexists myhash field1 # 判断hash中的指定字段是否存在 (integer) 1 只获得所有的field、只获得所有的value 127.0.0.1:6379> hkeys myhash # 只获得所有的field 1) "field2" 2) "field1" 127.0.0.1:6379> hvals myhash # 只获得所有的value 1) "world" 2) "hello" 指定增量、如果不存在则可以设置 127.0.0.1:6379> 127.0.0.1:6379> hset myhash field3 5 (integer) 1 127.0.0.1:6379> hincrby myhash field3 1 (integer) 6 127.0.0.1:6379> hget myhash field3 "6" 127.0.0.1:6379> hincrby myhash field3 -1 (integer) 5 127.0.0.1:6379> hget myhash field3 "5" 127.0.0.1:6379> hsetnx myhash field4 hello (integer) 1 127.0.0.1:6379> hsetnx myhash field4 hello (integer) 0hash应用: 存储变更数据,尤其是用户信息的保存,以及经常变动的信息。hash更适合对象的存储,String更加适合字符串存储。
在set的基础上增加了一个值, set k1 v1 zset k1 score1 v1 Zset命令以z开头
设置与获取 127.0.0.1:6379> zadd myset 1 one # 添加一个值 (integer) 1 127.0.0.1:6379> zadd myset 2 two (integer) 1 127.0.0.1:6379> zrange myset 0 -1 # 获取所有值 1) "one" 2) "two" 实现排序 127.0.0.1:6379> zadd salary 2500 xiaohong # 添加三个用户 (integer) 1 127.0.0.1:6379> zadd salary 5000 zhangsan (integer) 1 127.0.0.1:6379> zadd salary 500 warms (integer) 1 127.0.0.1:6379> zrange salary 0 -1 1) "warms" 2) "xiaohong" 3) "zhangsan" 127.0.0.1:6379> zrangebyscore salary -inf +inf # 递增显示全部用户 1) "warms" 2) "xiaohong" 3) "zhangsan" 127.0.0.1:6379> zrangebyscore salary -inf +inf withscores # 带score显示 1) "warms" 2) "500" 3) "xiaohong" 4) "2500" 5) "zhangsan" 6) "5000" 127.0.0.1:6379> zrangebyscore salary -inf 2500 withscores # 显示工资小于2500员工的升序排序 1) "warms" 2) "500" 3) "xiaohong" 4) "2500" 127.0.0.1:6379> zrevrange salary 0 -1 # 降序排序 1) "zhangsan" 2) "warms" 127.0.0.1:6379> zrevrange salary 0 -1 withscores 1) "zhangsan" 2) "5000" 3) "warms" 4) "500" 移除元素 127.0.0.1:6379> zrange salary 0 -1 1) "warms" 2) "xiaohong" 3) "zhangsan" 127.0.0.1:6379> zrem salary xiaohong # 移除集合中的指定元素 (integer) 1 127.0.0.1:6379> zrange salary 0 -1 1) "warms" 2) "zhangsan" 查看元素数量 127.0.0.1:6379> zcard salary # 获取有序集合中的个数 (integer) 2 统计某区间内的成员数量 127.0.0.1:6379> zcount salary 0 5000 (integer) 2应用思路:
班级成绩表、工资表带权重:普通消息、重要消息排行榜、top N 测试!应用:朋友定位、附近的人、打车距离计算
可以查询一些测试数据:http://www.jsons.cn/lngcode/
Geo底层为Zset实现
geoadd添加地理位置 规则:两极无法添加,我们一般会加载城市数据通过java程序一次性导入 参数: key 值 (纬度、经度、名称) 127.0.0.1:6379> geoadd china:city 116.40 39.90 beiging (integer) 1 127.0.0.1:6379> geoadd china:city 121.47 31.23 shanghai (integer) 1 127.0.0.1:6379> geoadd china:city 106.50 29.53 chongqing (integer) 1 127.0.0.1:6379> geoadd china:city 114.05 22.52 shengzheng (integer) 1 127.0.0.1:6379> geoadd china:city 120.16 30.24 hangzhou (integer) 1 127.0.0.1:6379> geoadd china:city 108.96 34.26 xian (integer) 1 获取指定城市的精度和纬度 127.0.0.1:6379> geopos china:city beiging 1) 1) "116.39999896287918091" 2) "39.90000009167092543" 计算两地距离单位
m 表示米km 表示千米mi 表示英里ft 表示英尺 # 单位默认为米 127.0.0.1:6379> geodist china:city beiging shanghai "1067378.7564" 127.0.0.1:6379> geodist china:city beiging shanghai km "1067.3788" 以给定的精度纬度为中心找出某一半径内的元素 127.0.0.1:6379> georadius china:city 110 30 1000 km # 获取在以(100,30)为中心方圆1000km内的城市 1) "chongqing" 2) "xian" 3) "shengzheng" 4) "hangzhou" 127.0.0.1:6379> georadius china:city 110 30 500 km 1) "chongqing" 2) "xian" 以一个元素为中心查找指定范围内的元素 127.0.0.1:6379> georadiusbymember china:city beiging 1000 km 1) "beiging" 2) "xian" 返回一个位置或多个位置的Geohash表示 # 将二维的经纬度转化为一维的字符串,如果两个字符串越接近,那么则距离越近 127.0.0.1:6379> geohash china:city beiging 1) "wx4fbxxfke0" 查询所有元素 127.0.0.1:6379> zrange china:city 0 -1 1) "chongqing" 2) "xian" 3) "shengzheng" 4) "hangzhou" 5) "shanghai" 6) "beiging" 移除元素 127.0.0.1:6379> zrem china:city beiging (integer) 1 127.0.0.1:6379> zrange china:city 0 -1 1) "chongqing" 2) "xian" 3) "shengzheng" 4) "hangzhou" 5) "shanghai"什么是基数? A{1,3,5,7,8,7} B{1 , 3,5,7,8} 基数(不重复的元素),可以接受误差
Redis Hyperloglog 是用于基数统计的算法,该算法占用内存是固定的,2^64不同的元素的基数,只需要费12KB内存。存在0.81的错误率,统计UV的任务可以忽略不计。 网页UV (一个人访问一个网站多次,但还是算作一个人) 传统的方式,set保存用户的id,然后就可以统计set中的元素数量作为标准判断!这种方式保存了大量用户id,会很麻烦!
添加、统计、合并 127.0.0.1:6379> pfadd mykey a b c d e f g h i j (integer) 1 127.0.0.1:6379> pfcount mykey (integer) 10 127.0.0.1:6379> pfadd mykey2 i j e a w k (integer) 1 127.0.0.1:6379> pfcount mykey2 (integer) 6 127.0.0.1:6379> pfmerge mykey3 mykey mykey2 OK 127.0.0.1:6379> pfcount mykey3 (integer) 12位存储 统计用户信息,活跃,不活跃!登录、未登录!打卡!只有两个状态都可以使用Bitmap Bitmap 位图,数据结构!都是操作二进制位来记录,就只有0和1两个状态!
使用Bitmap记录打卡 127.0.0.1:6379> setbit sign 0 1 (integer) 0 127.0.0.1:6379> setbit sign 2 0 (integer) 0 127.0.0.1:6379> setbit sign 1 0 (integer) 0 查看某一天是否打卡 127.0.0.1:6379> getbit sign 0 (integer) 1 127.0.0.1:6379> getbit sign 2 (integer) 0 统计打卡天数 127.0.0.1:6379> bitcount sign # 统计打卡天数就可以判断是否全勤 (integer) 1