redis数据类型
string
append key value 在字符串后面追加value,返回数字,如果key不存在,就相当于set keystrlen key 返回key的值的字符串长度incr key 给这个key的值+1。如果这个key不存在,则相当于set key 1.如果这个key的值不是一个数字,则返回ERR value is not an integer or out of range。value不是一个数字或超出范围,范围是多大我也不知道,应该是integer的取值范围2147483648decr key 给这个key减一incrby key 10 给这个key设置每次增加10,设置步长,指定增量decrby key 5 给这个key设置每次自减5。getrange key 0 3 获取key对应字符串的部分,相当于java的substring,如果是getranger key 0 -1 则表示获取key的所有=GET KEY,而不是截取的部分setrange key 2 xx 将字符串中下标为2的值替换为xx,例如set key1 abcde setrange key1 2 xx get key1返回abxxcd。相当于java的replacesetex key second value 表示设置后多少秒过期,seconds表示过期时间。ex就是expire。setnx key value 表示如果这个key不存在才设置,如果存在则不设置。nx就是 not exist。mset k1 v1 k2 v2 k3 v3 ... 表示同时设置多个键值对mget k1 k2 k3 同时获取多个msetnx k1 v1 k2 v2 k3 v3 k4 v4.. 如果不存在则设置,如果key有一个存在的,则所有的都设置不成功。这是一个原子性的操作,redis的事务是不保证原子性操作的,但是msetnx是保证原子性操作的
举例: 当我们要在redis中保存一个用户的信息的时候,一般情况下是将user对象转为json串保存到redis中 mset user:1 {name:zhangsan,age:10...} ,表示设置id为1的用户信息是一个json,同时也可以mset user:1:name zhangsan user:1:age 10 ... 这相当于将这个user的每个属性都分开设置到redis中了。
getset key value 先get 再set,当key不存在时,返回null 并设置这个key和value,当key存在时,返回key的值并用value覆盖之前的value。
string类型的使用场景
value除了可以是字符串还可以是数字,因此可以用到以下场景:
- 计数器:比如浏览量、粉丝数等等,当该对象被浏览了之后,可以使用
incr article title ;或者粉丝数 incr user fans 或 decr 。
List
在redis中可以将List作为一个栈、队列、阻塞队列来实现。所有的命令都是用L开头的。
Lpush list one 1 2 3 给list左边添加一个或多个元素Rpush list value v1 v2 v3... 给list右边添加一个或多个元素Lpop list 从列表的左边弹出一个元素Rpop list 从列表的右边弹出一个元素,弹出后元素内容-1Lindex list 0 获取list中下标为0的元素Llen list 获取list长度Lrem list count value 表示移除list中count个value元素Ltrim list start stop 表示根据下标截取队列rpoplpush list1 list2 将list1中最后一个元素移除,并将其放入list2中lset 将列表中指定下标的值替换为另一个值,更新操作,如果列表不存在或下标不存在会报错Linsert list befor/after value newvalue 往list中的value的before或after插入一个newvalue处插入一个值
还可以将List当作队列和栈来使用
Lpush Rpop 左边进右边出,这是一个队列Lpush Lpop 左边进左边出,这是一个栈
Set
set不能重复。
sadd set v1 v2 v3.... 往set集合中添加一个或多个元素,重复元素只能添加进一个smembers set 获取所有元素sismember set value 判断value是否存在scard set 获取set中元素的个数srem set value 将value移除set集合srandmember set count 随机返回count个数的元素,count默认1spop set count 从set中随机移除一个或count个元素smove set newset member 将set中的指定元素移动到newset中
应用场景: 微博、b站 共同关注(并集)
sdiff set1 set2 差集sinter set1 set2 交集 共同关注就可以这么实现sunion set1 set2 并集
Hash(map)
hset hash key value key1 value1 ... 与string类似,命令以H开头,只不过值是k-v hget hash key1 key2... hmset hash key value key1 value1 ... 多个操作 hmget hash key1 key2... hgetall hash 获取所有的键值对
hdel hash key 删除指定的key的字段,对应的value也就没有了hlen hash 获取这个hash中有多少个键值对hexists hsah key 判断这个key是否存在hkeys hash 获取所有keyhvals hash 获取所有valuehincrby hash key 1 自增hdecrby hash key 1 自减hsetnx hash key 如果不存在可以设置,如果存在,则不能设置保存变更的数据,可以将一个用户变形为hashset hash user:id:name zhangsan ,因此hash更适合存储对象,而string比较适合存储字符串
Zset(有序不重复集合)
zadd key score1 member1 [score2 member2] 向有序集合添加一个或多个成员,或者更新已存在成员的分数zcard key 获取有序集合的成员数zcount key min max 计算在有序集合中指定区间分数的成员数zincrby key increment member 有序集合中对指定成员的分数加上增量 incrementzrange key start stop [WITHSCORES] 通过索引区间返回有序集合指定区间内的成员zrangebyscore key min max [withscores] [limit] 通过分数返回有序集合指定区间内的成员zrem key member [member ...] 移除有序集合中的一个或多个成员zscore key member 返回有序集中,成员的分数值
geospatial地理位置
使用场景: 朋友的定位,附近的 人,打车距离,比如两地之间的距离等等。
geoadd
添加数据 规则:两级无法添加,我们一般会下载城市数据,直接通过java程序一次性导入! 参数(纬度 经度 名称) 超过有效的经度纬度就会报错
127.0.0.1:6379> geoadd china:city 116.40 39.90 beijin
(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 chongqi
(integer) 1
127.0.0.1:6379> geoadd china:city 114.05 22.52 shengzhen
(integer) 1
127.0.0.1:6379> geoadd china:city 120.16 30.24 hangzhou 118.96 34.26 xian
(integer) 2
127.0.0.1:6379>
geopos
获取当前定位:一定是一个坐标值
127.0.0.1:6379> geopos china:city beijin
1) 1) "116.39999896287918091"
2) "39.90000009167092543"
127.0.0.1:6379> geopos china:city beijin chongqi
1) 1) "116.39999896287918091"
2) "39.90000009167092543"
2) 1) "106.49999767541885376"
2) "29.52999957900659211"
127.0.0.1:6379>
geodist
两人之间的距离
127.0.0.1:6379> geodist china:city beijin shanghai
"1067378.7564" #北京上海的==直线距离,默认单位为米==
127.0.0.1:6379> geodist china:city beijin shanghai km
"1067.3788"
georadius
已给定的经纬度为中心,找某一半径内的元素
127.0.0.1:6379> georadius china:city 110 30 1000 km #以100经度30纬度为中心1000km为半径的圆内城市
1) "chongqi"
2) "shengzhen"
3) "hangzhou"
4) "xian"
127.0.0.1:6379> georadius china:city 110 30 500 km
1) "chongqi"
127.0.0.1:6379> georadius china:city 110 30 500 km withdist #显示到中心位置的距离
1) 1) "chongqi"
2) "341.9374"
127.0.0.1:6379> georadius china:city 110 30 500 km withcoord #显示他人的定位信息
1) 1) "chongqi"
2) 1) "106.49999767541885376"
2) "29.52999957900659211"
127.0.0.1:6379> georadius china:city 110 30 500 km withdist withcoord count 1 #筛选出指定数量的结果
1) 1) "chongqi"
2) "341.9374"
3) 1) "106.49999767541885376"
2) "29.52999957900659211"
127.0.0.1:6379> georadius china:city 110 30 500 km withdist withcoord count 2
1) 1) "chongqi"
2) "341.9374"
3) 1) "106.49999767541885376"
2) "29.52999957900659211"
127.0.0.1:6379> georadius china:city 110 30 500 km withdist withcoord count 3
1) 1) "chongqi"
2) "341.9374"
3) 1) "106.49999767541885376"
2) "29.52999957900659211"
127.0.0.1:6379>
georadiusbymember
找出指定城市周围的位置
127.0.0.1:6379> georadiusbymember china:city beijin 1000 km
1) "xian"
2) "beijin"
127.0.0.1:6379>
geohash
该命令返回长度为11的字符串
127.0.0.1:6379> geohash china:city beijin chongqi
1) "wx4fbxxfke0" #将二维的经纬度转换为一维的字符串,如果字符串月接近,那么距离则越近
2) "wm5xzrybty0"
geo底层实现原理
原理其实就是zset,我们可以使用zset命令操作geo
127.0.0.1:6379> zrange china:city 0 -1 ##查看元素
- “chongqi”
- “shengzhen”
- “hangzhou”
- “shanghai”
- “xian”
- “beijin”
127.0.0.1:6379> zrem china:city beijin (integer) 1 127.0.0.1:6379> zrange china:city 0 -1 - “chongqi”
- “shengzhen”
- “hangzhou”
- “shanghai”
- “xian”
127.0.0.1:6379>
hyperloglog
什么是基数? A{1,2,3,6,7,8,9} B{a,3,5,4,6,1}.基数就是不重复的元素,因此这两个集合的基数就是9。
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 #统计mykey元素基数数量
(integer) 10
127.0.0.1:6379> pfcount mykey2 i j z x c v b n m #
(integer) 0
127.0.0.1:6379> pfadd mykey2 i j z x c v b n m
(integer) 1
127.0.0.1:6379> pfcount mykey2
(integer) 9
127.0.0.1:6379> pfmerge mykey3 mykey mykey2 #合并两组到mykey3
OK
127.0.0.1:6379> pfcount mykey3
(integer) 15
127.0.0.1:6379>
如果允许容错统计数量,可以使用hyperloglog 如果不允许使用set或者其他数据类型。
bitmap
位存储 统计用户信息,活跃,不活跃,登入,为登入,打卡,365打卡!两个状态的都可以使用bitmaps bitmaps位图,数据结构,都是操作二进制位来进行记录的,就只有0,1两个状态 365=365bit 1字节=8bit 46字节左右! 测试 记录周一到周日打卡 周一:1,周二:0,周三:0.。。。
127.0.0.1:6379> setbit sign 0 0
(integer) 0
127.0.0.1:6379> setbit sign 1 0
(integer) 0
127.0.0.1:6379> setbit sign 2 0
(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 0
(integer) 0
127.0.0.1:6379> setbit sign 6 0
(integer) 0
127.0.0.1:6379>
查看某一天是否打卡
127.0.0.1:6379> getbit sign 3
(integer) 0
127.0.0.1:6379> getbit sign 4
(integer) 1
127.0.0.1:6379>
统计打卡天数,可以看到是否有缺勤
127.0.0.1:6379> bitcount sign
(integer) 1
|