Redis(1)——基本命令及数据类型(5+3)

2023-05-16

Redis的基本概念

  • Remote Dictionary Server:远程字典服务
  • Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件
  • 支持多种类型的数据结构,如字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps,hyperloglogs 和地理空间(geospatial) 索引半径查询。
  • Redis 内置了 复制(replication),LUA脚本(Luascripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的磁盘持久化(persistence)-- RDB和AOF , 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。

简单的横向对比

在这里插入图片描述

Redis能干什么?

  1. 内存存储、持久化、内存是断电即失,所以说持久化很重要(RDB和AOF);
  2. 效率高、可用于高速缓冲;
  3. 发布订阅系统;
  4. 地图信息分析;
  5. 计时器,计数器(浏览量);

单线程的Redis

  • 官方表示,Redis是基于内存操作的,CPU不是Redis的性能瓶颈,Redis的瓶颈就是根据机器的内存和网络带宽。既然可以使用单线程来实现,就使用单线程了!
  • Redis是C语言实现的,官方数据:读:110000/s 写: 80000/s,完全不比同样使用key-value的Memcached差

Redis为什么单线程这么快?

  • 误区1: 高性能的服务器一定是多线程的
  • 误区2: 多线程(CPU上下文切换)一定比单线程效率高
  • 核心: Redis是将所有的数据全部放在内存中的,所以说使用单线程去操作效率就是最高的,相比多线程,减少了CPU上下文切换的耗时。对于内存系统来说,没有上下文切换效率就是最高的,多次读写都是在一个CPU上的

Redis的基本操作

注意:Redis对大小写不敏感。

select

Redis默认有16个数据库,默认使用的是第0个数据库,可以通过select 切换数据库

127.0.0.1:6379> select 3
OK
127.0.0.1:6379[3]>

dbsize

查看数据库的大小

127.0.0.1:6379[3]> dbsize
(integer) 0
127.0.0.1:6379[3]> set name mk
OK
127.0.0.1:6379[3]> dbsize
(integer) 1
127.0.0.1:6379[3]> set age 22
OK
127.0.0.1:6379[3]> dbsize
(integer) 2
127.0.0.1:6379[3]>

keys

查看所有的key: 格式 : keys *

127.0.0.1:6379[3]> keys *
1) "name"
2) "age"

flushdb和flushall

清空当前数据库和清空所有数据库

127.0.0.1:6379[3]> flushdb
OK
127.0.0.1:6379[3]> keys *
(empty list or set)
127.0.0.1:6379[3]> flushall
OK

–下面进入正题–

Redis的五种基本类型

Redis-key

#set       设置key
#get       查看key的值
#expire    设置key的过期时间
#ttl       查看key的剩余时间
#exists    判断当前的key是否存在
#keys *    查看当前所有的key
#del key   删除当前的key
#type      查看key存储的value的类型 

1、字符串String

set get

设置值和获取值:格式:

  • set key value
  • get key
127.0.0.1:6379[3]> set k1 v1
OK
127.0.0.1:6379[3]> get k1
"v1"

exists

判断key是否存在:格式:

  • exists key
127.0.0.1:6379[3]> exists k1
(integer) 1

append

追加字符串,如果key不存在,相当于set命令,格式:

  • append key value
127.0.0.1:6379[3]> append k1 hello
(integer) 7
127.0.0.1:6379[3]> get k1
"v1hello"
127.0.0.1:6379[3]> append k2 v2
(integer) 2
127.0.0.1:6379[3]> get k2
"v2"

strlen

获取字符串的长度:格式:

  • strlen key
127.0.0.1:6379[3]> strlen k1
(integer) 7
127.0.0.1:6379[3]> strlen k2
(integer) 2
127.0.0.1:6379[3]> append k2 hi
(integer) 4
127.0.0.1:6379[3]> strlen k2
(integer) 4
127.0.0.1:6379[3]>

incr 和decr

对value进行自增1和自减1操作:格式:

  • incr key
  • decr key
127.0.0.1:6379[3]> set views 0
OK
127.0.0.1:6379[3]> get views
"0"
127.0.0.1:6379[3]> incr views   # i++操作
(integer) 1
127.0.0.1:6379[3]> incr views
(integer) 2
127.0.0.1:6379[3]> get views
"2"
127.0.0.1:6379[3]> decr views   # i--操作
(integer) 1
127.0.0.1:6379[3]> get views
"1"

incrby和decrby

设置加减的步长:格式:

  • incrby key num
  • decrby key num
127.0.0.1:6379[3]> incrby views 10   # 设置自增的步长
(integer) 11
127.0.0.1:6379[3]> get views
"11"
127.0.0.1:6379[3]> decrby views 3    # 设置自减的步长
(integer) 8
127.0.0.1:6379[3]> get views
"8"

getrange

获取给定范围的字符串的值:格式:

  • getrange key start stop
127.0.0.1:6379[3]> set k1 hello,mk
OK
127.0.0.1:6379[3]> get k1
"hello,mk"
127.0.0.1:6379[3]> getrange k1 0 4
"hello"
127.0.0.1:6379[3]> getrange k1 0 -1
"hello,mk"

setrange

从制定位置开始替换字符串的值:格式:

  • sterange key offset value
127.0.0.1:6379[3]> getrange k1 0 -1
"hello,mk"
127.0.0.1:6379[3]> setrange k1 6 bw
(integer) 11
127.0.0.1:6379[3]> getrange k1 0 -1
"hello,bw"

setex和ttl

(set with expire)
设置过期时间,查看剩余时间:格式:

  • setex key seconds value
  • ttl key
127.0.0.1:6379[3]> setex k2 10 aaaa
OK
127.0.0.1:6379[3]> ttl k2
(integer) 7
127.0.0.1:6379[3]> ttl k2
(integer) 2

setnx

(set if not exist)
如果key不存在则设置,否则失败:格式:

  • setnx key value
127.0.0.1:6379[3]> setnx k2 bw
(integer) 1
127.0.0.1:6379[3]> get k2
"bw"
127.0.0.1:6379[3]> setnx k2 xa
(integer) 0
127.0.0.1:6379[3]> get k2
"bw"

mset和mget

同时设置或者获取多个值:格式:

  • mset key1 value1 key2 value2…
  • mget key1 key2…
127.0.0.1:6379[3]> mset k1 mk k2 bw
OK
127.0.0.1:6379[3]> keys *
1) "k2"
2) "k1"
127.0.0.1:6379[3]> mget k1 k2
1) "mk"
2) "bw"

msetnx

msetnx是一个原子操作,要么一起成功,要么一起失败

127.0.0.1:6379> msetnx k1 mk k2 bw k3 ccc
(integer) 0
127.0.0.1:6379> get k3
(nil)

用String存储对象时key值的设计

#对象
127.0.0.1:6379> set user:1 {name:mk,age:22}
OK     #设置一个user:1对象,值为Json字符串

#这里的key是一个巧妙的设计: user:{id}:{filed}
127.0.0.1:6379> mset user:1:name mk user:1:age 22
OK
127.0.0.1:6379> mget user:1:name user:1:age
1) "mk"
2) "22"

getset

先获取值,再设置值,如果不存在,返回nil,如果存在,获取原来的值,并设置新的值:格式:

  • getset key value
127.0.0.1:6379> getset k3 ccc
(nil)
127.0.0.1:6379> get k2
"bw"
127.0.0.1:6379> getset k2 mk
"bw"
127.0.0.1:6379> get k2
"mk"

2、列表List

在Redis中,我们可以用list完成栈、队列、阻塞队列

注意:所有的list命令都是l开头的

lpush rpush lrange

从list左边或者右边插入值

  • lpush key value
  • rpush key value

lrange获取指定范围的值

  • lrange key start stop
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 zero  # 将一个值或者多个值,插入到列表尾部(右)
(integer) 4
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "two"
3) "one"
4) "zero"

lpop和rpop

从列表左边或者右边移除值:格式:

  • lpop key
  • rpop key
127.0.0.1:6379> lrange list 0 -1
1) "three"
2) "two"
3) "one"
4) "zero"
127.0.0.1:6379> lpop list
"three"
127.0.0.1:6379> rpop list
"zero"
127.0.0.1:6379> lrange list 0 -1
1) "two"
2) "one"

lindex

获取指定下标的值:格式:

  • lindex key index
127.0.0.1:6379> lrange list 0 -1
1) "two"
2) "one"
127.0.0.1:6379> lindex list 0
"two"
127.0.0.1:6379> lindex list 1
"one"

llen

获取列表中的元素个数:格式:

  • llen key
127.0.0.1:6379> llen list
(integer) 2

lrem

移除列表中的元素:格式:

  • lrem key count value

移除key中的count个value

127.0.0.1:6379> lrange list 0 -1
1) "two"
2) "one"
127.0.0.1:6379> lrem list 1 two
(integer) 1
127.0.0.1:6379> lrange list 0 -1
1) "one"

ltrim

截取列表的值:格式:

  • ltrim key start stop
127.0.0.1:6379> lpush list mk1 mk2 mk3 mk4
(integer) 4
127.0.0.1:6379> lrange list 0 -1
1) "mk4"
2) "mk3"
3) "mk2"
4) "mk1"
127.0.0.1:6379> ltrim list 1 2   # 通过下标截取指定的长度,这个list已经改变了,截断了只剩下截取的 元素!
OK
127.0.0.1:6379> lrange list 0 -1
1) "mk3"
2) "mk2"

rpoplpush

移除列表中最后一个元素,将它添加到另一个列表中,格式:

  • rpoplpush key1 key2
127.0.0.1:6379> lrange list 0 -1
1) "mk3"
2) "mk2"
127.0.0.1:6379> rpoplpush list list2    # 移除列表的最后一个元素,将它移动到新的列表中
"mk2"
127.0.0.1:6379> lrange list 0 -1        # 查看原来的列表
1) "mk3"
127.0.0.1:6379> lrange list2 0 -1       # 查看目标列表,确实存在该值
1) "mk2"

lset

根据下标替换列表中的值,前提是这个值存在,格式:

  • lset key index value
#LSET 将列表中指定下标的值替换为另外一个值,相当于更新操作
127.0.0.1:6379> lrange list 0 -1
1) "mk3"
127.0.0.1:6379> lset list 0 mk1     # 将0号下标的值替换为mk1
OK
127.0.0.1:6379> lrange list 0 -1
1) "mk1"
127.0.0.1:6379> lset list 1 mk2           # 修改不存在的下标,报错
(error) ERR index out of range

linsert

在列表中插入值,格式:

  • linsert key before | after value new_value
127.0.0.1:6379> linsert list after mk1 "mk2"
(integer) 2
127.0.0.1:6379> lrange list 0 -1
1) "mk1"
2) "mk2"

小结

  • List实际上是一个链表,before or after, left,right都可以插入值
  • 如果key不存在,创建新的链表
  • 如果key存在,新增内容
  • 如果移除了所有的值,空链表,也代表不存在
  • 在两端插入或者改动值,效率最高!中间元素,相对来说效率会低一点
  • 队列——LPOP - RPUSH
  • 栈——LPOP - LPUSH

3、集合set

注意:set中的值是不可以重复的

给set中添加值

格式:

  • sadd key value1 value…
127.0.0.1:6379> sadd myset mk1   #set集合中添加值
(integer) 1
127.0.0.1:6379> sadd myset mk2
(integer) 1
127.0.0.1:6379> sadd myset mk3
(integer) 1
127.0.0.1:6379> sadd myset mk1    #设置重复值时,失败
(integer) 0

smembers

获取set中的所有值:格式:

  • smembers key
127.0.0.1:6379> smembers myset
1) "mk3"
2) "mk2"
3) "mk1"

sismember

判断某个值是否在set中:格式:

  • sismember key value
127.0.0.1:6379> sismember myset mk1
(integer) 1
127.0.0.1:6379> sismember myset mk4
(integer) 0

scard

获取set中元素的个数:格式:

  • scard key
127.0.0.1:6379> scard myset
(integer) 3

srem

删除set中的值:格式:

  • srem key value1 value2…
127.0.0.1:6379> smembers myset
1) "mk3"
2) "mk2"
3) "mk1"
127.0.0.1:6379> srem myset mk1   #删除set集合中的元素
(integer) 1
127.0.0.1:6379> srem myset mk4    #删除set集合中不存在的元素,则失败
(integer) 0
127.0.0.1:6379> smembers myset
1) "mk3"
2) "mk2"

srandmember

从set中获取随机值,格式:

  • srandmember key count
    从key中随机获取count个值
#set是无序不重复的,可以获取随机值
127.0.0.1:6379> smembers myset
1) "mk3"
2) "mk2"
3) "mk1"
4) "mk4"
127.0.0.1:6379> srandmember myset
"mk1"
127.0.0.1:6379> srandmember myset
"mk4"
127.0.0.1:6379> srandmember myset 2
1) "mk3"
2) "mk1"

spop

随机删除指定个数个元素:格式:

  • spop key count
127.0.0.1:6379> smembers myset
1) "mk3"
2) "mk2"
3) "mk1"
4) "mk4"
127.0.0.1:6379> spop myset
"mk1"
127.0.0.1:6379> spop myset
"mk2"

smove

将指定的元素从一个set中移动到另一个set中,格式:

  • smove set1 set2 value
127.0.0.1:6379> sadd myset mk1 mk2 mk3 mk4
(integer) 4
127.0.0.1:6379> smembers myset
1) "mk3"
2) "mk2"
3) "mk1"
4) "mk4"
127.0.0.1:6379> sadd myset2 bw1 bw2 bw3
(integer) 3
127.0.0.1:6379> smembers myset2
1) "bw1"
2) "bw3"
3) "bw2"
127.0.0.1:6379> smove myset myset2 mk1  #从一个集合中移动一个值到另一个集合中
(integer) 1
127.0.0.1:6379> smembers myset
1) "mk3"
2) "mk2"
3) "mk4"
127.0.0.1:6379> smembers myset2
1) "mk1"
2) "bw1"
3) "bw3"
4) "bw2"

数字集合类

  • 差集 —— sdiff set1 set2
  • 交集 —— sinter set1 set2
  • 并集 —— sunion set1 set2

应用: A用户的关注列表放在一个set,将他的粉丝放在一个集合中,可以实现共同关注、共同爱好、推荐好友等:

127.0.0.1:6379> sadd set1 a b c d
(integer) 4
127.0.0.1:6379> sadd set2 c d e f
(integer) 4
127.0.0.1:6379> sdiff set1 set2   #差集
1) "b"
2) "a"
127.0.0.1:6379> sinter set1 set2   #交集 
1) "d"
2) "c"
127.0.0.1:6379> sunion set1 set2   #并集
1) "b"
2) "d"
3) "e"
4) "f"
5) "c"
6) "a"

4、哈希

可以将哈希看成是一个Map集合,key-value中的value是一个map集合

hset和hget

设置或者获取一个hash的值:格式:

  • hset key field1 value1
  • hget key field
127.0.0.1:6379> hset myhash field mk
(integer) 1
127.0.0.1:6379> hget myhash field
"mk"

hmset和hmget

设置或者获取一组hash的值:格式

  • hmset key field1 value1 field2 value2…
  • hmget key field1 field2 …
127.0.0.1:6379> hmset myhash field1 mk field2 bw field3 ccc
OK
127.0.0.1:6379> hmget myhash field1 field2
1) "mk"
2) "bw"

hgetall

获取hash中的值:格式:

127.0.0.1:6379> hgetall myhash
1) "field1"
2) "mk"
3) "field2"
4) "bw"
5) "field3"
6) "ccc"

hdel

删除指定field的hash键值对,格式::

  • hdel key field
127.0.0.1:6379> hdel myhash field3
(integer) 1
127.0.0.1:6379> hgetall myhash
1) "field1"
2) "mk"
3) "field2"
4) "bw"

hlen

获取hash的键值对的个数:格式:

  • hlen key
127.0.0.1:6379> hlen myhash
(integer) 2

hexists

判断hash中的字段是否存在:格式:

  • hexists key
127.0.0.1:6379> hexists myhash field1
(integer) 1
127.0.0.1:6379> hexists myhash field3
(integer) 0

hkeys和hvals

获取hash中所有的字段或者值:格式:

  • hkeys key
  • hvals key
127.0.0.1:6379> hkeys myhash
1) "field1"
2) "field2"
127.0.0.1:6379> hvals myhash
1) "mk"
2) "bw"

hincrby

给hash中指定字段的值加上一个增量

OK
127.0.0.1:6379> hset myhash field1 2
(integer) 1
127.0.0.1:6379> hincrby myhash field1 3
(integer) 5
127.0.0.1:6379>  hincrby myhash field1 -1  #给hash的值一个减量
(integer) 4

hsetnx

如果不存在则添加,如果存在则失败:格式:

  • hsetnx key field value
127.0.0.1:6379> hsetnx myhash field1 3
(integer) 0    #存在,无法添加
127.0.0.1:6379> hsetnx myhash field3 5
(integer) 1     #不存在,添加

hash的应用

  • hash中存储经常变更的值:比如用户信息: user : name-value,age-value,sex-value
  • hash更适合对象的存储,String更加适合字符串存储

5、有序集合zset

zadd

向有序集合中添加值:格式:

  • zadd key scores value
127.0.0.1:6379> zadd myzset 1 mk  #添加一个值
(integer) 1
127.0.0.1:6379> zadd myzset 2 bw 3 cc   #添加多个值
(integer) 2

zrange

获取zset中一个范围的值,格式:

  • zrange key start stop
127.0.0.1:6379> zrange myzset 0 -1
1) "mk"
2) "bw"
3) "cc"

zrangebyscore

将zset中的值按照score从小到大排序输出,格式:

  • zrangebyscore key min max
127.0.0.1:6379> zrangebyscore myzset -inf +inf    #按照从小到大排序 右区间也可指定值
1) "mk"
2) "bw"
3) "cc"
127.0.0.1:6379> zrangebyscore myzset -inf +inf withscores   #按照从小到大排序并显示scores
1) "mk"
2) "1"
3) "bw"
4) "2"
5) "cc"
6) "3"

从大到小输出:zrevrange myset 0 -1

zrem

移除zset中指定的元素,格式:

  • zrem key value
127.0.0.1:6379> zrange myzset 0 -1
1) "mk"
2) "bw"
3) "cc"
127.0.0.1:6379> zrem myzset cc
(integer) 1
127.0.0.1:6379> zrange myzset 0 -1
1) "mk"
2) "bw"

zcard

查看zset中的元素的个数:格式:

  • zcard key
127.0.0.1:6379> zrange myzset 0 -1
1) "mk"
2) "bw"
127.0.0.1:6379> zcard myzset
(integer) 2

zcount

根据score的值统计在给定区间的元素个数,格式:

  • zcount key min max
127.0.0.1:6379> zrange myzset 0 -1
1) "mk"
2) "bw"
127.0.0.1:6379> zcount myzset 1 1
(integer) 1
127.0.0.1:6379> zcount myzset 1 3
(integer) 2

Redis的三种特殊类型

1、geospatial

可以用来实现朋友的定位,附近的人,打车距离计算等

城市的经度纬度查询: http://www.jsons.cn/lngcode/

在这里插入图片描述

geoadd

添加地理位置:格式:

  • geoadd key 纬度 精度 名称
#两极无法直接添加
 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

geopos

返回给定名称的纬度和经度

127.0.0.1:6379> GEOPOS china:city xian 
1) 1) "108.96000176668167114"
   2) "34.25999964418929977" 
127.0.0.1:6379> GEOPOS china:city xian beijing 
1) 1) "108.96000176668167114" 
   2) "34.25999964418929977" 
2) 1) "116.39999896287918091" 
 2) "39.90000009167092543"

geodist

返回两个给定位置之间的距离

单位:

  • m 米
  • km 千米
  • mi 英里
  • ft 英尺
127.0.0.1:6379> GEODIST china:city beijing xian km
"910.0565" 
127.0.0.1:6379> GEODIST china:city hangzhou xian
km "1143.6295"

geohash

返回一个11个字符的geohash字符串

127.0.0.1:6379> GEOHASH china:city xian 
1) "wqj6zky6bn0" #指定元素的纬度和经度的字符串 12

georadius

以给定的纬度经度为中心,找到某一半径内的元素

127.0.0.1:6379> GEORADIUS china:city 110 30 1000 km 
1) "chongqing" 
2) "xian" 
3) "shengzhen" 
4) "hangzhou" 
127.0.0.1:6379> GEORADIUS china:city 110 30 500 km 
1) "chongqing" 
2) "xian" 
127.0.0.1:6379> GEORADIUS china:city 110 30 500 km withcoord 
1) 1) "chongqing" 
   2) 1) "106.49999767541885376" 
      2) "29.52999957900659211" 
2) 1) "xian" 
   2) 1) "108.96000176668167114" 
      2) "34.25999964418929977" 
127.0.0.1:6379>

georadiusbymember

以一个成员为中心,查找指定半径范围内容的元素

127.0.0.1:6379> GEORADIUSBYMEMBER china:city xian 1000 km 
1) "xian" 
2) "chongqing" 
3) "beijing"

geo的底层是一个zset集合

127.0.0.1:6379> zrange china:city 0 -1 
1) "chongqing" 
2) "xian" 
3) "shengzhen" 
4) "hangzhou" 
5) "shanghai" 
6) "beijing" 
127.0.0.1:6379> zrem china:city shanghai 
(integer) 1
127.0.0.1:6379> zrange china:city 0 -1 
1) "chongqing" 
2) "xian" 
3) "shengzhen" 
4) "hangzhou" 
5) "beijing"

2、hyperloglog

什么是基数?

比如数据集 {1, 3, 5, 7, 5, 7, 8},
那么这个数据集的基数集为 {1, 3, 5 ,7, 8},
基数(不重复元素)为5。 基数估计就是在误差可接受的范围内,快速计算基数。

简介

Redis hyperloglog是基数统计的算法,其在输入元素的数量或者体积很大的时候,计算基数的空间总是固定的,并且很小。(错误率:0.81%)

  • 264不同的元素基数,只需要12KB的内容空间

pfadd、pfcount、pfmerge

  • pfadd key value1 value2…添加指定元素到hyperloglog中
  • pfcount key key…返回给定hyperloglog的基数估算值
  • pfmerge destkey soucrekey sourcekey合并多个hyperloglog
127.0.0.1:6379> pfadd myset a b c d e f f
(integer) 1
127.0.0.1:6379> pfcount myset
(integer) 6
127.0.0.1:6379> pfadd myset2 c d e f g h h
(integer) 1
127.0.0.1:6379> pfcount myset2   #存在误差
(integer) 6
127.0.0.1:6379> pfmerge myset3 myset1 myset2
OK
127.0.0.1:6379> pfcount myset3
(integer) 6

3、bitmaps

bitmaps是位存储的,都是二进制位来进行记录, 所以只要是只有两种状态值的场景,都可以使用bitmaps来存储。比如:登录、未登录;打卡,未打卡;活跃,不活跃等。
操作二进制位进行记录,5

setbit

在bitmaps中添加数据:格式:

  • setbit key offset value
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 1
(integer) 0
127.0.0.1:6379> setbit sign 4 0
(integer) 0

getbit

查看位图中某个位置的值:格式:

  • getbit key offset
127.0.0.1:6379> getbit sign 3
(integer) 1
127.0.0.1:6379> getbit sign 1
(integer) 1
127.0.0.1:6379> getbit sign 4
(integer) 0

bitcount

统计位图中value等于1的个数,格式:

  • bitcount key start end
127.0.0.1:6379> bitcount sign 0 -1
(integer) 4
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Redis(1)——基本命令及数据类型(5+3) 的相关文章

  • BigDecimal和Double的区别

    Double span class token number 0 3 span span class token number 0 2 span span class token operator 61 span span class to
  • 对科里奥利力的理解

    首先创造一个情景 xff0c 方便理解 假设你站在一个这样的封闭靶场 xff08 全封闭 xff09 上 xff0c 这个靶场在以大小为 的角速度做匀速圆周运动 xff08 速度不大不小 xff0c 你感觉不到 xff0c 而且靶场没风 x
  • typora使用技巧

    1 Typora vue theme的介绍与下载 typora vue theme是参考了Vue文档风格而开发的一个 Typora 自定义主题 点击此处下载 2 如何安装 a 下载本主题中的vue css vue dark css文档和包含
  • 序列化什么意思

    序列化就是一种用来处理对象流的机制 xff0c 将对象转化成字节序列后可以保存在磁盘上 xff0c 或通过网络传输 xff0c 以达到以后恢复成原来的对象
  • mybatis plus 事务回滚总结

    https www cnblogs com c2g5201314 p 13163097 html
  • throw 和 try catch 的区别

    try catch是直接处理 xff0c 处理完成之后程序继续往下执行 xff0c throw则是将异常抛给它的上一级处理 xff0c 程序便不往下执行了
  • throw的异常日志会打印吗

    throw 就是要把异常继续抛出 xff0c 要么由上层方法解决 xff0c 要么会终止程序运行
  • java assert什么意思

    assert 意为断言的意思 xff0c 这个关键字可以判断布尔值的结果是否和预期的一样 xff0c 如果一样就正常执行 xff0c 否则会抛出AssertionError assert 的使用 xff1a span class token
  • throw和throws的区别

    throws xff1a 用来声明一个方法可能产生的所有异常 xff0c 不做任何处理而是将异常往上传 xff0c 谁调用我我就抛给谁 用在方法声明后面 xff0c 跟的是异常类名 可以跟多个异常类名 xff0c 用逗号隔开 表示抛出异常
  • 1024有感

    2022 10 24 1024节日快乐 xff01 好好学习 xff0c 天天向上 x1f600
  • 互联网项目一般几轮测试

    第一轮测试 xff1a 要覆盖所有测试用例 所有功能都要跑一遍 第二轮测试 xff1a 重点功能的测试 还要把第一轮测试发现的问题 xff0c 根据开发修改完成的结果 xff0c 进行验证 最后一轮是回归测试 xff1a 验证所有bug是否
  • IDEA pom文件 ctrl alt l无法格式化

    File gt Manage IDE settings gt Restore Default settings 恢复IDEA默认设置后 xff0c 即可格式化pom文件
  • 科里奥利力简单清晰的推导

    看到一个比较好的科里奥利力推导方法 xff1a 如果你不太理解科里奥利力 xff0c 可以看一下我的这篇文章 xff1a 对科里奥利力的理解 本文参考 xff1a 1 黄永义 科里奥利力简单而清晰的导出 J 广西物理 2015 36 04
  • java实体类命名

    Entity xff1a 与数据库表结构一一对应 xff0c 通过Dao层向上传输数据源对象 Dto xff08 Data Transfer Object xff09 xff1a 数据传输对象 xff0c Service或Manager向外
  • 字节的高低位互换

    蝶式交换法 unsigned char Reverse byte unsigned char data data 61 data lt lt 4 data gt gt 4 data 61 data lt lt 2 amp 0xcc data
  • 没有Build文件夹的情况下(最新的vue-cli3没有)怎么关闭掉ESlink

    这里写目录标题 一般的注释掉Build中的方法最新的vue cli3没有build文件夹怎么办 一般的注释掉Build中的方法 在build文件夹 gt webpack base conf js中注释以下代码 和在IntelliJ IDEA
  • 使用zed摄像头跑ORB_SLAM2

    zed ros wrapper安装 首先对zed ros wrapper安装 xff1a 具体操作步骤及代码的参考链接 xff1a https github com stereolabs zed ros wrapper git mkdir
  • 【linux网络编程学习笔记】第二节:创建TCP通信(双向)(socket、bind、listen、accept、connect、recv、send、shutdown、server\client)

    Work won 39 t kill but worry will 劳动无害 xff0c 忧愁伤身 上一篇章中创建了TCP的客户端的服务器 xff0c 但是只能单向发送 xff0c 本章节主要讲解如何进行双向互发消息 xff0c 实现的过程
  • 航模电池及稳压降压模块—毕设简记

    航模电池及稳压降压模块简介 简述 准备给设计的控制系统选一块航模电池 xff0c 需要关注什么参数 xff1f 控制系统的传感器需要5V供电 直流减速电机需要12V供电 单片机需要7 12V供电 xff0c 这么多供电该怎么处理 xff1f
  • Laplance算子(二阶导数)

    理论 xff1a 在二阶导数的时候 xff0c 最大变化处的值为0 即边缘是零 xff0c 通过二阶导数计算 xff0c 依据此理论我们可以计算图像的二阶导数 xff0c 提取边缘 Laplance算子 二阶导数我不会 xff0c 别担心

随机推荐

  • yolo3_pytorch 训练voc数据集和训练自己的数据集并进行预测(github代码调试)

    训练voc数据集的步骤 xff1a xff1a 首先下载voc数据集 xff0c 将数据集放在从github中下载的项目中VOCdevkit目录中 xff08 直接将数据集拉入到项目中 xff0c 替代目标文件即可 xff09 源码下载 x
  • ros的通信机构

    ros的通信是在os层之上 xff0c 基于TCP IP协议实现 os层 xff08 操作系统层 xff09 对于开发者来讲 xff0c 是不需要关系的 中间层 xff1a TCPROS UDPROS 这是基于TCP IP协议进行重新封装的
  • 视频追踪(meanshift和camshift算法)

    import numpy as np import cv2 as cv opencv实现meanshift的api cv meanShift probImage window criteria 参数一 xff1a roi区域 xff0c 目
  • 国产的Arduino Mega 2560 R3改进版串口1丝印标注错误

    Mega 2560有四个串口 xff1a 分别是串口0 xff0c 串口1 xff0c 串口2 xff0c 串口3 而串口1的丝印标注反了 在板子中烧录如下代码 xff0c 则串口1的TX应该不断的有输出 xff0c RX没有 void s
  • Visual Studio实现光流法(opencv and Eigen)

    环境问题 xff1a 首先是在vs中安装opencv和eigen两个库 安装eigen库所推荐的链接 xff1a VS2019正确的安装Eigen库 xff0c 解决所有报错 xff08 全网最详细 xff01 xff01 xff09 Ma
  • Deformable DETR环境配置和应用

    准备工作 xff1a Deformable DETR代码路径如下 xff1a GitHub fundamentalvision Deformable DETR Deformable DETR Deformable Transformers
  • A review of visual SLAM methods for autonomous driving vehicles

    自主驾驶车辆的视觉SLAM方法回顾 原论文在文章末尾 摘要 xff1a 自主驾驶车辆在不同的驾驶环境中都需要精确的定位和测绘解决方案 在这种情况下 xff0c 同步定位和测绘 xff08 SLAM xff09 技术是一个很好的研究解决方案
  • slam原理介绍和经典算法

    1 传统slam局限性 slam算法假设的环境中的物体都是处于静态或者低运动状态的 xff0c 然而 xff0c 现实世界是复杂多变的 xff0c 因此这种假设对于应用 环境有着严格的限制 xff0c 同时影响视觉slam系统在实际场景中的
  • Git教程(李立超git和GitHub使用)

    Git教程 配置 配置name和email git config global user name 34 xxxx 34 git config global user email 34 xxx 64 xxx xxx 34 git statu
  • 需求:节目上传至MINIO后,使用mqtt进行上报

    需求 xff1a 节目上传至MINIO后 xff0c 使用mqtt进行上报 环境准备 文件管理平台 xff1a 首先需要使用minio搭建属于自己的对象存储 xff08 此步骤跳过 xff09 通信方式 xff1a MQTT方式 xff0c
  • Vue.js自定义事件的使用(实现父子之间的通信)

    vue v model修饰符 xff1a lazy number trim attrs数据的透传 xff0c 在组件 xff08 这个是写在App vue中 xff09 数据就透传到student组件中 xff0c 在template中可以
  • 简单算法——二分搜索的递归版本和非递归版本

    二分搜索 这是大家比较熟悉的算法了 xff0c 我们今天来复习一下 xff1a 前提 xff1a 二分查找要求所查找的顺序表必须是有序的 算法思路 定义left为顺序表最左端元素位置 xff0c right为顺序表右端元素位置 定义mid
  • Mysql(14)——事务

    概念 一个事务是由一条或者多条对数据库操作的SQL语句所组成的一个不可分割的单元 只有当事务中的所有操作都正常执行完了 xff0c 整个事务才会被提交给数据库 xff1b 如果有部分事务处理失败 xff0c 那么事务就要回退到最初的状态 x
  • Mysql(15)——锁机制 + MVCC(全)

    前言 事务的隔离级别在之前我们已经学习过 xff0c 那么事务隔离级别的实现原理是什么呢 xff1f 锁 43 MVCC 下面我们就来分开讲解 xff1a 表级锁 amp 行级锁 注意 xff1a 表锁和行锁说的是锁的粒度 xff0c 不要
  • DIY无人机组装与飞控参数调试记录(DJI NAZA-LITE)

    早就想玩一玩无人机 xff0c 奈何各种原因一直没有机会 xff0c 工作之后资金富足 xff0c 加上本身工作和这个相关性比较大 xff0c 于是就自己DIY了一台无人机 一 材料准备 xff1a F450机架 GPS支架 好盈乐天 20
  • Mysql(16)——日志

    前言 我们之前了解过redo log和undo log xff0c 他们是作用在InnoDb存储引擎层的 xff0c 今天我们来讲讲服务层的其他日志类型 一 错误日志 错误日志是 MySQL 中最重要的日志之一 xff0c 它记录了当 my
  • Mysql(17)——优化

    前言 一 SQL和索引优化 二 应用优化 除了优化SQL和索引 xff0c 很多时候 xff0c 在实际生产环境中 xff0c 由于数据库服务器本身的性能局限 xff0c 就必须要对上层的应用来进行一些优化 xff0c 使得上层应用访问数据
  • 项目——C++实现数据库连接池

    前言 在学习Mysql的时候 xff0c 我们都有这个常识 xff1a 对于DB的操作 xff0c 其实本质上是对于磁盘的操作 xff0c 如果对于DB的访问次数过多 xff0c 其实就是涉及了大量的磁盘IO xff0c 这就会导致MYsq
  • Redis入门——发展历程及NoSQL

    前言 随着社会的发展 xff0c 数据存储经历了诸多的过程 xff0c 这篇文章就是介绍Redis的发展由来 xff1a 1 单机Mysql时代 这种模式存在以下的瓶颈 xff1a 数据量太大 xff0c 一个机器存放不下数据的索引太大 x
  • Redis(1)——基本命令及数据类型(5+3)

    Redis的基本概念 Remote Dictionary Server xff1a 远程字典服务Redis 是一个开源 xff08 BSD许可 xff09 的 xff0c 内存中的数据结构存储系统 xff0c 它可以用作数据库 缓存和消息中