登录之后
输入 help @generic
(@之后会自动补全)常用的:
del ,exists,expire,keys ,move,object,persist,pexpire,type
eg:
查库里有哪些key: keys *
清空库里所有key(谨慎操作):flushdb / flushall
给字符串赋值:set k1 hello
取值:get k1
查询set命令用法:help set
根据用法可以知道下图
nx 作用:只能新建
k1没有值的时候才能赋值成功,如果k1已经有值,则不能对k1进行赋值。【适用场景:分布式锁,许多人,谁能赋值成功,则谁抢占了锁】
xx的作用:只能更新
k1有值的时候,才能更新成功
发送一次get再发送一次set,使用该命令,相当于只发一个包,减少io请求:getset k1 mm
127.0.0.1:6379> flushall
OK
127.0.0.1:6379> keys *
(empty list or set)
给k1, k2赋值
127.0.0.1:6379> msetnx k1 a k2 b
(integer) 1
127.0.0.1:6379> mget k1 k2
1) "a"
2) "b"
更新k2的值,给k3赋值 ,nx只能给没有值的元素赋值成功,下面操作失败,msetnx是原子操作,所以k3赋值失败
127.0.0.1:6379> msetnx k2 c k3 d
(integer) 0
127.0.0.1:6379> mget k1 k2 k3
1) "a"
2) "b"
3) (nil)
127.0.0.1:6379> APPEND k1 123
(integer) 8
127.0.0.1:6379> get k1
"hello123"
127.0.0.1:6379> GETRANGE k1 5 7
"123"
获取字符串部分值,也可以用正反向索引下标 来取值:
127.0.0.1:6379> GETRANGE k1 5 -1
"123"
127.0.0.1:6379> GETRANGE k1 0 -1
"hello123"
127.0.0.1:6379> GETRANGE k1 -3 -1
"123"
正反向索引下标 :
修改字符串某一部分的值
127.0.0.1:6379> get k1
"hello ke"
127.0.0.1:6379> SETRANGE k1 5 " A"
(integer) 8
127.0.0.1:6379> get k1
"hello Ae"
k1值+1
127.0.0.1:6379> INCR k1
(integer) 100指定k1增加88
127.0.0.1:6379> INCRBY k1 88
(integer) 188k1值-1
127.0.0.1:6379> DECR k1
(integer) 187指定k1值-80
127.0.0.1:6379> DECRBY k1 80
(integer) 107指定k1增加 0.3
127.0.0.1:6379> INCRBYFLOAT k1 0.3
"107.3"
STRLEN
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> set k1 hello
OK
127.0.0.1:6379> STRLEN k1
(integer) 5
127.0.0.1:6379> set k2 128
OK
127.0.0.1:6379> STRLEN k2
(integer) 3
127.0.0.1:6379> set k3 9
OK
127.0.0.1:6379> STRLEN k3
(integer) 1
可以看出,offset只是二进制位的索引下标
127.0.0.1:6379> help setbitSETBIT key offset valuesummary: Sets or clears the bit at offset in the string value stored at keysince: 2.2.0group: string
下面是bit相关命令
变量 | 值 | 0号字节 | 1号字节 |
---|---|---|---|
k1 | A | 0100 0001 | 0000 0000 |
k2 | C | 0100 0011 | 0000 0000 |
给k1赋值为A
给k1索引下标第7个位置 赋值1
127.0.0.1:6379> setbit k1 7 1
(integer) 0
给k1索引下标第1个位置 赋值1
127.0.0.1:6379> setbit k1 1 1
(integer) 0
得到k1的值为A ,对应ascii码值41 ,如下:
127.0.0.1:6379> get k1
"A"
给k2赋值为C
127.0.0.1:6379> setbit k2 6 1
(integer) 0
127.0.0.1:6379> setbit k2 7 1
(integer) 0
127.0.0.1:6379> setbit k2 1 1
(integer) 0
127.0.0.1:6379> get k2
"C"
k1 和k2做运算
k1 k2做与运算
127.0.0.1:6379> bitop and andkey k1 k2
(integer) 1
127.0.0.1:6379> get andkey
"A"k1 k2做或运算
127.0.0.1:6379> bitop or orkey k1 k2
(integer) 1
127.0.0.1:6379> get orkey
"C"
值 | 0号字节 | 1号字节 |
---|---|---|
A | 0100 0001 | 0000 0000 |
127.0.0.1:6379> get k1
"A"
127.0.0.1:6379> bitcount k1 1 1
(integer) 0
127.0.0.1:6379> bitcount k1 0 0
(integer) 2
127.0.0.1:6379> bitcount k1 0 1
(integer) 2
K1值 | 0号字节 | 1号字节 | 2号字节 |
---|---|---|---|
“A \x80” | 0100 0001 | 0010 0000 | 1000 0000 |
给k1赋值:A \x80
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> setbit k1 1 1
(integer) 0
127.0.0.1:6379> setbit k1 7 1
(integer) 0
127.0.0.1:6379> get k1
"A"
127.0.0.1:6379> setbit k1 10 1
(integer) 0
127.0.0.1:6379> get k1
"A "
127.0.0.1:6379> setbit k1 16 1
(integer) 0
127.0.0.1:6379> get k1
"A \x80"
查找k1在0号,1号,2号字节里面,指定字节区间后,第一个1出现二进制下标的位置:
127.0.0.1:6379> bitpos k1 1 0 0
(integer) 1
127.0.0.1:6379> bitpos k1 1 1 1
(integer) 10
127.0.0.1:6379> bitpos k1 1 2 2
(integer) 16
1 统计tom一年中有多少天购买了商品
变量 | 二进制表示 | 每个二进制位含义{字节里面二进制位索引下标 跟日期映射 } |
---|---|---|
tom | 0100 1000 | tom在第2天和第5天购买过商品 |
json | 0100 0010 | json 在第2天和第7天购买过商品 |
上面示例类推,举例如下:
每个用户一年最多占用46 B ,eg:某电商企业用户数200w(2000 000 )用户,则统计一年所有用户占内存中仅用 92M 。
第二天,第299天和第365天均购买了商品,
127.0.0.1:6379> setbit tom 1 1
(integer) 0
127.0.0.1:6379> setbit tom 300 1
(integer) 0
127.0.0.1:6379> setbit tom 364 1
(integer) 0
127.0.0.1:6379> STRLEN tom
(integer) 46查最后一天是否下单:
127.0.0.1:6379> bitcount tom -2 -1
(integer) 1查一年中下单天数
127.0.0.1:6379> bitcount tom 0 -1
(integer) 3
2 查询3.17-3.18号两天的活跃用户数量
看这两天下单的用户,做去重
变量 | 二进制表示 | 每个二进制位含义{字节里面二进制位索引下标 跟用户id映射 } |
---|---|---|
20230317 | 0100 0000 | 1号用户3.17号下单 |
20230318 | 0100 0010 | 1号和6号用户3.18号各下单一次 |
setbit ,bitop
和bitcount
结合应用场景
127.0.0.1:6379> setbit 20230317 1 1
(integer) 0
127.0.0.1:6379> setbit 20230318 1 1
(integer) 0
127.0.0.1:6379> setbit 20230318 6 1
(integer) 0
【查询这两天有哪些用户下了单】
127.0.0.1:6379> bitop or tarkey 20230317 20230318
(integer) 1统计这两天下单用户数量
127.0.0.1:6379> BITCOUNT tarkey 0 1 【查0-1字节区间有多少个1】
(integer) 2
127.0.0.1:6379> BITCOUNT tarkey 0 0 【查0-0字节区间有多少个1】
(integer) 2
127.0.0.1:6379> BITCOUNT tarkey 1 1 【由此结果0可知,查的是1-1字节区间有多少个1】
(integer) 0
list用处:
list结构下标反向检索:双向链表
给list存值和取值【查全部,查单个元素值】
127.0.0.1:6379> flushdb
OK-- 给list类型的k1赋值
127.0.0.1:6379> lpush k1 a b c d e f
(integer) 6-- 给list类型的k2赋值
127.0.0.1:6379> rpush k2 a b c d e f
(integer) 6-- 获取k1的值
127.0.0.1:6379> LRANGE k1 0 -1
1) "f"
2) "e"
3) "d"
4) "c"
5) "b"
6) "a"-- 获取k1的值
127.0.0.1:6379> LRANGE k2 0 -1
1) "a"
2) "b"
3) "c"
4) "d"
5) "e"
6) "f"-- 获取 k1单个元素的值:同向(lpush,lpop ): 后进先出 ;反向(lpush ,rpop):先进先出
127.0.0.1:6379> lpop k1
"f"
127.0.0.1:6379> lpop k1
"e"
127.0.0.1:6379> rpop k1
"a"-- 获取 k2单个元素的值:同向(rpush,rpop ): 后进先出 ;反向(rpush ,lpop):先进先出
127.0.0.1:6379> rpop k2
"f"
127.0.0.1:6379> rpop k2
"e"
127.0.0.1:6379> lpop k2
"a"
lindex 查找元素位置 ,lrem 删除指定元素,linsert 插入元素
lindex 查询list指定位置的元素值
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> lpush k1 a b c d e f
(integer) 6查询k1 第0个位置的元素
127.0.0.1:6379> lindex k1 0
"f"最后一个位置的元素
127.0.0.1:6379> lindex k1 -1
"a"还有倒数第二个元素
127.0.0.1:6379> lindex k1 -2
"b"
redis里的list是可以重复的,可以用 lrem 移除元素,也可以用linsert插入元素
初始化k2集合
127.0.0.1:6379> lpush k2 a b c d 2 3 a d f g a 3 2 d 6 3 a
(integer) 17遍历k2的值
127.0.0.1:6379> LRANGE k2 0 -11) "a"2) "3"3) "6"4) "d"5) "2"6) "3"7) "a"8) "g"9) "f"
10) "d"
11) "a"
12) "3"
13) "2"
14) "d"
15) "c"
16) "b"
17) "a"-- 移除 k2 中 2个 a元素
127.0.0.1:6379> lrem k2 2 a
(integer) 2-- 再次遍历k2的值,1和7号位置的a已经被删除
127.0.0.1:6379> LRANGE k2 0 -11) "3"2) "6"3) "d"4) "2"5) "3"6) "g"7) "f"8) "d"9) "a"
10) "3"
11) "2"
12) "d"
13) "c"
14) "b"
15) "a"在k2中值为3的元素前面插入a
127.0.0.1:6379> LINSERT k2 before 3 a
(integer) 16
在k2中值为3的元素前面插入a
127.0.0.1:6379> LINSERT k2 before 3 a
(integer) 17
在k2中值为6的元素前面插入a
127.0.0.1:6379> LINSERT k2 before 6 a
(integer) 18
在k2中值为c的元素前面插入a
127.0.0.1:6379> linsert k2 after c a
(integer) 19
127.0.0.1:6379> lrange k2 0 -11) "a"2) "a"3) "3"4) "a"5) "6"6) "d"7) "2"8) "3"9) "g"
10) "f"
11) "d"
12) "a"
13) "3"
14) "2"
15) "d"
16) "c"
17) "a"
18) "b"
19) "a"
lrem:删除list集合里靠后的4个a
127.0.0.1:6379> lrem k2 -4 a
(integer) 4
127.0.0.1:6379> lrange k2 0 -11) "a"2) "a"3) "3"4) "6"5) "d"6) "2"7) "3"8) "g"9) "f"
10) "d"
11) "3"
12) "2"
13) "d"
14) "c"
15) "b"
127.0.0.1:6379> llen k2
(integer) 15
blpop 阻塞弹出元素
---会话1127.0.0.1:6379> blpop k1 5 【5代表超时时间】
(nil)
(5.09s)
127.0.0.1:6379> blpop k1 60
阻塞住了---会话2127.0.0.1:6379> rpush k1 2 3
(integer) 2--- 会话1
127.0.0.1:6379> blpop k1 60 【刚才阻塞的命令,有了下面的响应结果】
1) "k1"
2) "2"
(12.62s)
127.0.0.1:6379> lpush k4 a b c d n d f
(integer) 7
127.0.0.1:6379> lrange k4 0 -1
1) "f"
2) "d"
3) "n"
4) "d"
5) "c"
6) "b"
7) "a"
127.0.0.1:6379> ltrim k4 1 -2
OK
127.0.0.1:6379> lrange k4 0 -1
1) "d"
2) "n"
3) "d"
4) "c"
5) "b"
可以用stirng类型实现,然后通过 keys tom*
获取全部的值
127.0.0.1:6379> set tom::name abc
OK
127.0.0.1:6379> get tom::name
"abc"
127.0.0.1:6379> set tom::age 25
OK
127.0.0.1:6379> get tom::age
"25"
127.0.0.1:6379> keys tom*
1) "tom::age"
2) "tom::name"
给哈希数组赋值:hset ,hmset
127.0.0.1:6379> hset tom name ss
(integer) 1
127.0.0.1:6379> hmset tom age 20 address jlin
OK
从hash里取值,以及取多个值 hget ,hmget
127.0.0.1:6379> hget tom age
"20"
127.0.0.1:6379> hmget tom name address
1) "ss"
2) "jlin"
获取hash全部的key值 ,获取hash全部value值
127.0.0.1:6379> hkeys tom
1) "name"
2) "age"
3) "address"
127.0.0.1:6379> HVALS tom
1) "ss"
2) "20"
3) "jlin"
获取hash全部的值(key和value)
127.0.0.1:6379> hgetall tom
1) "name"
2) "ss"
3) "age"
4) "20"
5) "address"
6) "jlin"
127.0.0.1:6379> HINCRBY tom age 3
(integer) 23
127.0.0.1:6379> HINCRBY tom age -1
(integer) 22
127.0.0.1:6379> HINCRBYFLOAT tom age -2.5
"19.5"
127.0.0.1:6379> hget tom age
"19.5"
适用场景:关注,收藏,点赞,都可以存储在map里,还能进行计算 ,效率比较快。
redis是去重的集合,也不维护排序。
sadd :给集合增加元素
smembers :获取全部元素
srem: 移除元素
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> sadd k1 tom json seam lily ab ba
(integer) 6
127.0.0.1:6379> SMEMBERS k1
1) "tom"
2) "lily"
3) "json"
4) "ab"
5) "ba"
6) "seam"
127.0.0.1:6379> srem k1 ab ba
(integer) 2
127.0.0.1:6379> SMEMBERS k1
1) "tom"
2) "seam"
3) "json"
4) "lily"
SINTERSTORE :取完交集直接存储在一个目标集合里,相比于sinter ,
SINTER :直接把集合的交集取出来;如果实际取出集合交集后续还会用到,那么会把交集结果存储重新存储到缓存里,记录了io。效率是比较低的,想较SINTERSTORE ,数据取交集放集合里,所有操作都是在服务端完成的,效率比较高。
127.0.0.1:6379> sadd k2 1 2 3 4 5
(integer) 5
127.0.0.1:6379> sadd k3 5 4 6 8 9
(integer) 5
127.0.0.1:6379> SMEMBERS k2
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
127.0.0.1:6379> SMEMBERS k3
1) "4"
2) "5"
3) "6"
4) "8"
5) "9"
127.0.0.1:6379> SINTERSTORE kn k2 k3
(integer) 2
127.0.0.1:6379> SMEMBERS kn
1) "4"
2) "5"
127.0.0.1:6379> SINTER k2 k3
1) "4"
2) "5"
SUNIONSTORE
同理,交集结果放在指定集合里,在服务端完成的操作,效率较高。而SUNION
要把并集结果存储到缓存, 多了一次io交互,相比 SUNIONSTORE
效率会低一些。
127.0.0.1:6379> SUNION k2 k3
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"
7) "8"
8) "9"
127.0.0.1:6379> SUNIONSTORE destBing k2 k3
(integer) 8
127.0.0.1:6379> SMEMBERS destBing
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"
7) "8"
8) "9"
k2 里减去和k3重合的部分
127.0.0.1:6379> SDIFF k2 k3
1) "1"
2) "2"
3) "3"k3 里减去和k2重合的部分
127.0.0.1:6379> SDIFF k3 k2
1) "6"
2) "8"
3) "9"
SRANDMEMBER KEY count
count :可以是正数,表示从集合随机取出指定元素个数
也可以是负数,表示从集合随机取出指定元素个数,可以有重复元素。
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379> sadd k1 tom json seam lily tom seam lily aa bb cc bb aa
(integer) 7取出3个随机值,但是如果k1有2个元素,则取出来得是2个
127.0.0.1:6379> SRANDMEMBER k1 3
1) "lily"
2) "json"
3) "bb"
127.0.0.1:6379> SRANDMEMBER k1 8
1) "aa"
2) "cc"
3) "tom"
4) "seam"
5) "lily"
6) "json"
7) "bb"取出3个随机值可以有重复的元素
127.0.0.1:6379> SRANDMEMBER k1 -3
1) "tom"
2) "cc"
3) "cc"
127.0.0.1:6379> SRANDMEMBER k1 -8
1) "tom"
2) "aa"
3) "seam"
4) "cc"
5) "cc"
6) "tom"
7) "cc"
8) "tom"随机取出单个元素
127.0.0.1:6379> spop k1
"bb"
127.0.0.1:6379> spop k1
"lily"
127.0.0.1:6379> spop k1
"cc"
127.0.0.1:6379> spop k1
"tom"
127.0.0.1:6379> spop k1
"json"
127.0.0.1:6379> spop k1
"seam"
127.0.0.1:6379> spop k1
"aa"
127.0.0.1:6379> spop k1
(nil)
127.0.0.1:6379> spop k1
(nil)
给集合赋值,查询范围,按照分数排序查询范围 ,下面是示例:
127.0.0.1:6379> flushdb
OK给集合初始化
127.0.0.1:6379> zadd k1 8 apple 2 banana 3 orange
(integer) 3
127.0.0.1:6379> zrange k1 0 -1
1) "banana"
2) "orange"
3) "apple"按照价格排序,查全部水果 【由此可见,内存中元素左小右大】
127.0.0.1:6379> zrange k1 0 -1 withscores
1) "banana"
2) "2"
3) "orange"
4) "3"
5) "apple"
6) "8"价格在 [3,8] 区间的水果
127.0.0.1:6379> ZRANGEBYSCORE k1 3 8
1) "orange"
2) "apple"查询价格最低的前两种水果
127.0.0.1:6379> ZRANGE k1 0 1
1) "banana"
2) "orange"
下面两组数据虽然一样,但是顺序不一样,由此可见,SortedSet的物理内存左小右大不随机命令发生变化
按增序,取分数最高的2个
127.0.0.1:6379> ZRANGE k1 -2 -1
1) "orange"
2) "apple"
按照分值降序取前两个
127.0.0.1:6379> ZREVRANGE k1 0 1
1) "apple"
2) "orange"
查询元素(按分数的)排名
127.0.0.1:6379> ZRANK k1 apple
(integer) 2
127.0.0.1:6379> ZRANK k1 orange
(integer) 1
127.0.0.1:6379> ZRANK k1 banana
(integer) 0
查指定元素分数
127.0.0.1:6379> ZSCORE k1 apple
"8"
初始时候,水果的顺序是这样的
127.0.0.1:6379> zrange k1 0 -1
1) "banana"
2) "orange"
3) "apple"
127.0.0.1:6379> zrange k1 0 -1 withscores
1) "banana"
2) "2"
3) "orange"
4) "3"
5) "apple"
6) "8"
做了运算之后,再次查看水果的分数排序,有了变化:
给橘子和香蕉分别增加1.5和4.5
127.0.0.1:6379> ZINCRBY k1 1.5 orange
"4.5"
127.0.0.1:6379> ZINCRBY k1 4.5 banana
"6.5"
再次看水果的排序,是实时变化的
127.0.0.1:6379> zrange k1 0 -1 withscores
1) "orange"
2) "4.5"
3) "banana"
4) "6.5"
5) "apple"
6) "8"
由上面可知,sortedset 会实时根据元素的值去维护这个分数的排序
给k1 ,k2集合初始化
127.0.0.1:6379> zadd k1 80 tom 60 seam 70 lily
(integer) 3
127.0.0.1:6379> zadd k2 60 tom 100 seam 40 liming
(integer) 3
127.0.0.1:6379> ZUNIONSTORE tarKey 2 k1 k2
(integer) 4
127.0.0.1:6379> ZRANGE tarKey 0 -1 withscores
1) "liming"
2) "40"
3) "lily"
4) "70"
5) "tom"
6) "140"
7) "seam"
8) "160"
127.0.0.1:6379> ZUNIONSTORE tarkey1 2 k1 k2 weights 1 0.5
(integer) 4
127.0.0.1:6379> ZRANGE tarkey1 0 -1 withscores
1) "liming"
2) "20"
3) "lily"
4) "70"
5) "seam"
6) "110"
7) "tom"
8) "110"
k1 k2 交叉元素只取 值大的元素 参与两个集合的并集运算
127.0.0.1:6379> ZUNIONSTORE tarkey2 2 k1 k2 aggregate max
(integer) 4
127.0.0.1:6379> ZRANGE tarkey2 0 -1 withscores
1) "liming"
2) "40"
3) "lily"
4) "70"
5) "tom"
6) "80"
7) "seam"
8) "100"
抽奖:中奖用户:是否重复
①n个奖品,人小于礼物数【 公司年会抽奖,奖品数比人数多】:用户
②人大于礼物数:用户 >n
eg: SRANDMEMBER key(3个人) count(大于3并且为正数)
③ 上面两种是取出全部 比较贴合实际的是一个一个抽奖
spop key ,取出一个
help @list
,help @string
等会出现很多关于list的api方法 ,
help ltrim
127.0.0.1:6379> set k1 99
OK
127.0.0.1:6379> type k1
string
127.0.0.1:6379> set k2 hello
OK
127.0.0.1:6379> type k2
string
看OBJECT 的用法
127.0.0.1:6379> OBJECT help
1) OBJECT arg arg ... arg. Subcommands are:
2) ENCODING -- Return the kind of internal representation used in order to store the value associated with a key.
3) FREQ -- Return the access frequency index of the key. The returned integer is proportional to the logarithm of the recent access frequency of the key.
4) IDLETIME -- Return the idle time of the key, that is the approximated number of seconds elapsed since the last access to the key.
5) REFCOUNT -- Return the number of references of the value associated with the specified key.eg:
127.0.0.1:6379> get k1
"99"
127.0.0.1:6379> get k2
"hello"
127.0.0.1:6379> OBJECT encoding k1
"int"
127.0.0.1:6379> OBJECT encoding k2
"embstr"127.0.0.1:6379> set k3 qqqqq
OK
127.0.0.1:6379> OBJECT encoding k3
"embstr"
127.0.0.1:6379> APPEND k3 kkkk
(integer) 9
127.0.0.1:6379> OBJECT encoding k3
"raw"