郑州企业建设网站有什么好处,做网站公司哪里好,用地方名字做网站,可以拔下来做的网站吗来源 | blog.itzhouq.cn/redis2最近这几天的面试每一场都问到了#xff0c;但是感觉回答的并不好#xff0c;还有很多需要梳理的知识点#xff0c;这里通过几篇 Redis 笔记整个梳理一遍。Redis 的八大数据类型官网可查看命令#xff1a;http://www.redis.cn/commands.htmlR… 来源 | blog.itzhouq.cn/redis2最近这几天的面试每一场都问到了但是感觉回答的并不好还有很多需要梳理的知识点这里通过几篇 Redis 笔记整个梳理一遍。Redis 的八大数据类型官网可查看命令http://www.redis.cn/commands.htmlRedis-key127.0.0.1:6379 keys *
(empty list or set)
127.0.0.1:6379 set name xxx
OK
127.0.0.1:6379 keys *
1) name127.0.0.1:6379 set age 1
OK
127.0.0.1:6379 keys *
1) age2) name127.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
(integer) 1
127.0.0.1:6379 keys *
1) age127.0.0.1:6379 set name yyy
OK
127.0.0.1:6379 expire name 10 # 设置key的过期时间单位是秒(integer) 1
127.0.0.1:6379 ttl name # 查看当前key的剩余过期时间(integer) 7
127.0.0.1:6379 ttl name
(integer) -2
127.0.0.1:6379 type age # 查看当前key的类型string
127.0.0.1:6379
Redis 有以下 8 种数据类型1、String字符串127.0.0.1:6379 set key1 v1 #设置值OK
127.0.0.1:6379 get key1v1127.0.0.1:6379 append key1 hello # 追加值如果不存在相当于 set key(integer) 7
127.0.0.1:6379 get key1v1hello127.0.0.1:6379 strlen key1 # 获取字符串长度(integer) 7
127.0.0.1:6379
自增、自减127.0.0.1:6379 set views 0
OK
127.0.0.1:6379 get views0127.0.0.1:6379 incr views # 自增 1(integer) 1
127.0.0.1:6379 get views1127.0.0.1:6379 decr views # 自减 1(integer) 0
127.0.0.1:6379 decr views
(integer) -1
127.0.0.1:6379 get views-1127.0.0.1:6379 incrby views 10 # 设置步长、自增 10 (integer) 9
127.0.0.1:6379 decrby views 5 # 设置步长、自减 5(integer) 4
字符串范围127.0.0.1:6379 set key1 hello,world!OK
127.0.0.1:6379 get key1hello,world!127.0.0.1:6379 getrange key1 0 3 # 截取字符串\[0, 3\]hell127.0.0.1:6379 getrange key1 0 -1 # 获取全部的字符串和 get key一样hello,world!127.0.0.1:6379
替换127.0.0.1:6379 set key2 abcdefg
OK
127.0.0.1:6379 get key2abcdefg127.0.0.1:6379 setrange key2 1 xx
(integer) 7
127.0.0.1:6379 get key2axxdefg127.0.0.1:6379
setex(set with expire)设置过期时间和setnx(set if not exist)不存在再设置在分布式锁中会经常使用127.0.0.1:6379 setex key3 30 hello # 设置 30 秒后过期OK
127.0.0.1:6379 ttl key3 # 剩余过期时间(integer) 25
127.0.0.1:6379 setnx mykey redis # mykey 不存在时设置成功(integer) 1
127.0.0.1:6379 keys *
1) key22) key13) views4) mykey127.0.0.1:6379 setnx mykey mongoDB # mykey 存在时设置失败(integer) 0
127.0.0.1:6379 get mykey # mykey 值不变redis127.0.0.1:6379
mset 和 mget
127.0.0.1:6379 mset k1 v1 k2 v2 k3 v3 # 同时设置多个值OK
127.0.0.1:6379 keys *
1) k12) k33) k2127.0.0.1:6379 mget k1 k2 k3 # 同时获取多个值1) v12) v23) v3127.0.0.1:6379 msetnx k1 v1 k4 v4 # msetnx 是一个原子性的操作要么一起成功要么都失败(integer) 0
127.0.0.1:6379 get k4
(nil)
127.0.0.1:6379
对象set user:1 {name:zhangsan, age:3} # 设置一个 user:1 对象 值为 json 字符来保存一个对象127.0.0.1:6379 mset user:1:name zhangsan user:1:age 2
OK
127.0.0.1:6379 mget user:1:name user:1:age
1) zhangsan2) 2127.0.0.1:6379
getset先 get 再 set127.0.0.1:6379 getset db redis # 如果不存在值则返回 nil(nil)
127.0.0.1:6379 get dbredis127.0.0.1:6379 getset db mongodb # 如果存在值获取原来的值并设置新的值redis127.0.0.1:6379 get dbmongodb127.0.0.1:6379
String 的使用场景value 除了是字符串以外还可以是数字计数器统计多单位的数量粉丝数对象缓存存储2、List列表基本的数据类型列表。在 Redis 中可以把 list 用作栈、队列、阻塞队列。list 命令多数以 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 # 查看全部元素1) three2) two3) one127.0.0.1:6379 lrange list 0 1 # 通过区间获取值1) three2) two127.0.0.1:6379 rpush list right # 将一个值或者多个值插入到列表的尾部右(integer) 4
127.0.0.1:6379 lrange list 0 -1
1) three2) two3) one4) right127.0.0.1:6379
弹出 pop127.0.0.1:6379 lrange list 0 -1
1) !2) world3) world4) hello127.0.0.1:6379 lpop list # 移除list的第一个元素!127.0.0.1:6379 lrange list 0 -1
1) world2) world3) hello127.0.0.1:6379 rpop list # 移除list的第一个元素hello127.0.0.1:6379 lrange list 0 -1
1) world2) world127.0.0.1:6379
索引 Lindex127.0.0.1:6379 lrange list 0 -1
1) hjk2) world3) world127.0.0.1:6379 lindex list 1 # 通过下标获取list中的某一个值world127.0.0.1:6379 lindex list 0hjk127.0.0.1:6379
Llen 长度127.0.0.1:6379 llen list
(integer) 3
127.0.0.1:6379
移除指定的值127.0.0.1:6379 lrange list 0 -1
1) hjk2) world3) world127.0.0.1:6379 lrem list 1 world # 移除list集合中指定个数的value精确匹配(integer) 1
127.0.0.1:6379 lrange list 0 -1
1) hjk2) world127.0.0.1:6379 lpush list hjk
(integer) 3
127.0.0.1:6379 lrange list 0 -1
1) hjk2) hjk3) world127.0.0.1:6379 lrem list 2 hjk
(integer) 2
127.0.0.1:6379 lrange list 0 -1
1) world127.0.0.1:6379
trim 截断127.0.0.1:6379 lrange mylist 0 -1
1) hello12) hello23) hello34) hello4127.0.0.1:6379 ltrim mylist 1 2 # 通过下标截取指定长度这个list已经被破坏了截断之后只剩下截断后的元素OK
127.0.0.1:6379 lrange mylist 0 -1
1) hello22) hello3127.0.0.1:6379
rpoplpush 移除列表的最后一个元素将他移动到新的列表中。127.0.0.1:6379 lrange mylist 0 -1
1) hello12) hello23) hello3127.0.0.1:6379 rpoplpush mylist myotherlist # 移除列表的最后一个元素将他移动到新的列表中。hello3127.0.0.1:6379 lrange mylist 0 -1 # 查看原来的列表1) hello12) hello2127.0.0.1:6379 lrange myotherlist 0 -1 # 查看目标列表中确实存在该值1) hello3127.0.0.1:6379
lset将列表中指定下标的值替换为另一个值更新操作127.0.0.1:6379 exists list # 判断这个列表是否存在(integer) 0
127.0.0.1:6379 lset list 0 item # 如果不存在的话更新会报错(error) ERR no such key
127.0.0.1:6379 lpush list value1
(integer) 1
127.0.0.1:6379 lrange list 0 0
1) value1127.0.0.1:6379 lset list 0 item # 如果存在更新当前下标的值OK
127.0.0.1:6379 lset list 1 other # 如果不存在的话更新会报错(error) ERR index out of range
127.0.0.1:6379
linsert将某个具体的value插入到列表中某个元素的前面或者后面127.0.0.1:6379 lrange mylist 0 -1
1) hello12) hello2127.0.0.1:6379 linsert mylist before hello2 hello
(integer) 3
127.0.0.1:6379 lrange mylist 0 -1
1) hello12) hello3) hello2127.0.0.1:6379 linsert mylist after hello2 hello
(integer) 4
127.0.0.1:6379 lrange mylist 0 -1
1) hello12) hello3) hello24) hello127.0.0.1:6379
小结list 实际上是一个链表前后都可以插入如果key不存在创建新的链表如果移除了所有的值空链表也代表不存在在两边插入或者改动值效率最高。3、Set 集合127.0.0.1:6379 sadd myset hello # set 集合中添加元素(integer) 1
127.0.0.1:6379 sadd myset world(integer) 1
127.0.0.1:6379 smembers myset # 查看指定Set的所有值1) world2) hello127.0.0.1:6379 sismember myset hello # 判断某一个值是不是在set中(integer) 1
127.0.0.1:6379 sismember myset hello1
(integer) 0
127.0.0.1:6379
127.0.0.1:6379 scard myset # 获取集合中的个数(integer) 2
127.0.0.1:6379 sadd myset hello2(integer) 1
127.0.0.1:6379 smembers myset
1) world2) hello23) hello127.0.0.1:6379 srem myset hello # 移除元素(integer) 1
127.0.0.1:6379 smembers myset
1) world2) hello2127.0.0.1:6379
127.0.0.1:6379 smembers myset
1) kkk2) world3) hjk4) hello2127.0.0.1:6379 srandmember myset # 随机抽取一个元素hjk127.0.0.1:6379 srandmember mysethello2127.0.0.1:6379 srandmember myset 2 # 随机抽取指定个数的元素1) world2) hello2127.0.0.1:6379 srandmember myset 2
1) hello22) hjk127.0.0.1:6379
127.0.0.1:6379 smembers myset
1) kkk2) world3) hjk4) hello2127.0.0.1:6379 spop myset # 随机删除元素hjk127.0.0.1:6379 smembers myset
1) kkk2) world3) hello2127.0.0.1:6379 spop mysethello2127.0.0.1:6379 smembers myset
1) kkk2) world127.0.0.1:6379
127.0.0.1:6379 smembers myset
1) kkk2) world127.0.0.1:6379 sadd myset2 set2
(integer) 1
127.0.0.1:6379 smove myset myset2 kkk # 将一个特定的值移动到另一个set集合中(integer) 1
127.0.0.1:6379 smembers myset
1) world127.0.0.1:6379 smembers myset2
1) kkk2) set2127.0.0.1:6379
127.0.0.1:6379 smembers key1
1) b2) a3) c127.0.0.1:6379 smembers key2
1) e2) d3) c127.0.0.1:6379 sdiff key1 key2 # 差集1) b2) a127.0.0.1:6379 sinter key1 key2 # 交集1) c127.0.0.1:6379 sunion key1 key2 # 并集1) e2) a3) c4) d5) b
4、Hash(哈希)也是 key - value 形式的但是value 是一个map。127.0.0.1:6379 hset myhash field xxx # set 一个 key-value(integer) 1
127.0.0.1:6379 hget myhash field # 获取一个字段值xxx127.0.0.1:6379 hmset myhash field1 hello field2 world # set 多个 key-valueOK
127.0.0.1:6379 hmget myhash field field1 field2 # 获取多个字段值1) xxx2) hello3) world127.0.0.1:6379 hgetall myhash # 获取全部的数据1) field2) xxx3) field14) hello5) field26) world
127.0.0.1:6379 hdel myhash field1 # 删除指定的key对应的value也就没有了(integer) 1
127.0.0.1:6379 hgetall myhash
1) field2) xxx3) field24) world127.0.0.1:6379
127.0.0.1:6379 hlen myhash # 获取长度(integer) 2
127.0.0.1:6379 hexists myhash field1 # 判断指定key是否存在(integer) 0
127.0.0.1:6379 hexists myhash field2
(integer) 1
127.0.0.1:6379 hkeys myhash # 获取所有的key1) field2) field2127.0.0.1:6379 hvals myhash # 获取所有的value1) xxx2) world127.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 hincrby myhash field3 -1
(integer) 5
127.0.0.1:6379 hsetnx myhash field4 hello # 如果不存在则可以设置(integer) 1
127.0.0.1:6379 hsetnx myhash field4 world # 如果存在则不能设置(integer) 0
127.0.0.1:6379
Hash 适合存储经常变动的对象信息String 更适合于存储字符串。5、zset (有序集合)127.0.0.1:6379 zadd myset 1 one # 添加一个值(integer) 1
127.0.0.1:6379 zadd myset 2 two 3 three # 添加多个值(integer) 2
127.0.0.1:6379 zrange myset 0 -1
1) one2) two3) three127.0.0.1:6379
实现排序127.0.0.1:6379 zadd salary 2500 xiaohong
(integer) 1
127.0.0.1:6379 zadd salary 5000 xiaoming
(integer) 1
127.0.0.1:6379 zadd salary 500 xaiozhang
(integer) 1
127.0.0.1:6379 zrange salary 0 -1
1) xaiozhang2) xiaohong3) xiaoming127.0.0.1:6379 zrangebyscore salary -inf inf # 从小到大显示全部的用户1) xaiozhang2) xiaohong3) xiaoming127.0.0.1:6379 zrevrange salary 0 -1 # 从大到小进行排序1) xiaoming2) xiaohong3) xaiozhang127.0.0.1:6379 zrangebyscore salary -inf inf withscores # 附带成绩的显示所有用户1) xaiozhang2) 5003) xiaohong4) 25005) xiaoming6) 5000127.0.0.1:6379 zrangebyscore salary -inf 2500 withscores # 显示工资小于 2500 的用户1) xaiozhang2) 5003) xiaohong4) 2500
127.0.0.1:6379 zrange salary 0 -1
1) xaiozhang2) xiaohong3) xiaoming127.0.0.1:6379 zrem salary xiaohong # 移除特定元素(integer) 1
127.0.0.1:6379 zrange salary 0 -1
1) xaiozhang2) xiaoming127.0.0.1:6379 zcard salary # 获取有序集合的个数(integer) 2
127.0.0.1:6379
127.0.0.1:6379 zadd myset 1 hello
(integer) 1
127.0.0.1:6379 zadd myset 2 world 3 !
(integer) 2
127.0.0.1:6379 zcount myset 1 3 # 获取指定区间的人员数量(integer) 3
127.0.0.1:6379 zcount myset 1 2
(integer) 2
6、geospatialRedis 在 3.2 推出 Geo 类型该功能可以推算出地理位置信息两地之间的距离。文档https://www.redis.net.cn/order/3687.html借助网站模拟一些数据http://www.jsons.cn/lngcode/geoadd 添加地理位置规则两极无法直接添加一般会下载城市数据直接通过 Java 程序一次性导入。有效的经度从 -180 度到 180 度。有效的纬度从 -85.05112878 度到 85.05112878 度。当坐标位置超出指定范围时该命令将会返回一个错误。(error) ERR invalid longitude latitude pair xxx yyy
添加一些模拟数据127.0.0.1:6379 geoadd china:city 116.40 39.90 beijing
(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 114.05 22.52 shengzhen
(integer) 2
127.0.0.1:6379 geoadd china:city 120.16 30.24 hangzhou 108.96 34.26 xian
(integer) 2
127.0.0.1:6379
geopos 获得当前定位坐标值127.0.0.1:6379 geopos china:city beijing # 获得指定城市的经纬度1) 1) 116.399998962879180912) 39.90000009167092543127.0.0.1:6379 geopos china:city shanghai
1) 1) 121.470001637935638432) 31.22999903975783553127.0.0.1:6379
geodist 获取两个位置之间的距离单位m 表示单位为米。km 表示单位为千米。mi 表示单位为英里。ft 表示单位为英尺。如果用户没有显式地指定单位参数 那么 GEODIST 默认使用米作为单位。127.0.0.1:6379 geodist china:city beijing shanghai km # 查看北京和上海直接的直线距离1067.3788127.0.0.1:6379 geodist china:city beijing chongqing km1464.0708127.0.0.1:6379
georedius 以给定的经纬度为中心找出某一半径内的元素127.0.0.1:6379 georadius china:city 110 30 1000 km # 以110, 30 这个点为中心寻找方圆 1000km 的城市1) chongqing2) xian3) shengzhen4) hangzhou127.0.0.1:6379 georadius china:city 110 30 500 km
1) chongqing2) xian127.0.0.1:6379 georadius china:city 110 30 500 km withcoord # 显示他人的定位信息1) 1) chongqing2) 1) 106.499997675418853762) 29.529999579006592112) 1) xian2) 1) 108.960001766681671142) 34.25999964418929977127.0.0.1:6379
127.0.0.1:6379 georadius china:city 110 30 500 km withdist # 显示到中心点的距离1) 1) chongqing2) 341.93742) 1) xian2) 483.8340127.0.0.1:6379 georadius china:city 110 30 500 km withdist withcoord count 1 # 指定数量1) 1) chongqing2) 341.93743) 1) 106.499997675418853762) 29.52999957900659211127.0.0.1:6379 georadius china:city 110 30 500 km withdist withcoord count 2
1) 1) chongqing2) 341.93743) 1) 106.499997675418853762) 29.529999579006592112) 1) xian2) 483.83403) 1) 108.960001766681671142) 34.25999964418929977127.0.0.1:6379
GEORADIUSBYMEMBER 找出位于指定元素周围的其他元素127.0.0.1:6379 georadiusbymember china:city shanghai 1000 km
1) hangzhou2) shanghai127.0.0.1:6379
geo 底层实现原理其实就是 zset 可以使用 zset 命令操作 geo127.0.0.1:6379 zrange china:city 0 -1
1) chongqing2) xian3) shengzhen4) hangzhou5) shanghai6) beijing127.0.0.1:6379 zrem china:city beijing # 删除一个元素(integer) 1
127.0.0.1:6379 zrange china:city 0 -1
1) chongqing2) xian3) shengzhen4) hangzhou5) shanghai127.0.0.1:6379
7、hyperloglog基数数学上集合的元素个数是不能重复的。UVUnique visitor是指通过互联网访问、浏览这个网页的自然人。访问的一个电脑客户端为一个访客一天内同一个访客仅被计算一次。Redis 2.8.9 版本更新了 hyperloglog 数据结构是基于基数统计的算法。hyperloglog 的优点是占用内存小并且是固定的。存储 2^64 个不同元素的基数只需要 12 KB 的空间。但是也可能有 0.81% 的错误率。这个数据结构常用于统计网站的 UV。传统的方式是使用 set 保存用户的ID然后统计 set 中元素的数量作为判断标准。但是这种方式保存了大量的用户 IDID 一般比较长占空间还很麻烦。我们的目的是计数不是保存数据所以这样做有弊端。但是如果使用 hyperloglog 就比较合适了。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 PFADD mykey2 i j z x c v b n m # 创建第二组元素(integer) 1
127.0.0.1:6379 PFCOUNT mykey2 # 统计 mykey2 基数(integer) 9
127.0.0.1:6379 PFMERGE mykey3 mykey mykey2 # 合并两组 mykey mykey2 mykey3OK
127.0.0.1:6379 PFCOUNT mykey3
(integer) 15
127.0.0.1:6379
8、bitmap 位图bitmap就是通过最小的单位bit来进行0或者1的设置表示某个元素对应的值或者状态。一个bit的值或者是0或者是1也就是说一个bit能存储的最多信息是2。bitmap 常用于统计用户信息比如活跃粉丝和不活跃粉丝、登录和未登录、是否打卡等。这里使用一周打卡的案例说明其用法127.0.0.1:6379 setbit sign 0 1 # 周一打卡了(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 1
(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
查看某一天是否打卡127.0.0.1:6379 GETBIT sign 3
(integer) 1
127.0.0.1:6379 GETBIT sign 6
(integer) 0
127.0.0.1:6379
统计统计打卡的天数127.0.0.1:6379 BITCOUNT sign
(integer) 4
127.0.0.1:6379往期推荐
《大厂内部资料》Redis 性能优化的 13 条军规全网首发Redis 6.0 正式版终于发布了除了多线程还有什么新功能Redis的自白我为什么在单线程的这条路上越走越远关注我每天陪你进步一点点