6. redis 数据类型
Redis 是一个key-value的数据库,所以Key一般都是String类型。
下面会记录常见常用的几种类型;更多的我们可以查看redis官方的类型: https://redis.io/docs/latest/develop/data-types/
String数据类型
String类型可以是说Redis最基本也是最常用的数据类型了,一个key对应一个value
String类型基本上可以包含任何数据,比如图片或者序列化的对象等。
一个Redis中的字符串value最多可以是512M
String的常见命令:
- SET:添加或者修改已经存在的一个String类型的键值对(如果key不存在则是新增,如果存在则是修改)
 - GET:根据key获取String类型的value
 - GETSET:先获取在设置,如果get时值不存在返回空,然后在进行设置,如果get时值存在,返回对应的值,在进行修改
 - APPEND:Append 命令用于为指定的key 追加值,如果 key 已经存在并且是一个字符串,APPEND 命令将 value 追加到 key原来的值的末尾。如果 key 不存在,APPEND 就简单地将给定 key 设为 value,就像执行 SET key value 一样。
 - MSET:批量添加多个String类型的键值对
 
                MSET k1 value1 k2 value2 
        MSET user:1:name zhangsan user:2:age 18 小技巧:设置一个用户的信息
- MGET:根据多个key获取多个String类型的value
 
                MGET k1 k2
- MSETNX: 命令用于所有给定 key 都不存在时,同时设置一个或多个 key-value 对。(原子性操作);如果有一个存在,就都不会保存成功
 - INCR:命令将 key 中储存的数字值增一。如果key 不存在,那么key 的值会先被初始化为0,然后再执行INCR 操作。如果值包含错误的类型,或字符串类型的值不能表示为数字,那么返回一个错误。本操作的值限制在64位(bit)有符号数字表示之内。
 - INCRBY;让一个整型的值自增并指定步长(例如:num 5 让num值自增5,其余与上方一致)
 - DECR:命令将 key 中储存的数字值减一(与INCR命令相反,其余一致)。
 - DECRBY: 命令将 key 所储存的值減去指定的减量值(与INCRBY相反,其余一致)。
 - SETNX:添加一个String类型的键值对,前提是这个key不存在,如果否则不执行(与MSETNX区别在于,此命令只能设置一组key value)
 - SETEX:命令为指定的key设置值及其过期时间。如果 key 已经存在,SETEX 命令将会替换旧的值
 
- 注意:set与setnx区别
 
在Redis中,SET和SETNX命令用于设置字符串类型的键值,但它们在处理键已经存在的情况下的行为是不同的。当然MSET与MSETNX与之同理,只是添加MSET与MSETNX可以批量添加数据
SET命令:如果键已经存在,SET会直接覆盖旧的值,无论键是否存在,都将设置新值。例如:SET mykey "He11o"
SETNX 命令:SETNX 表示"SET if Not exists”,也就是只有在键不存在的情况下,才会设置新的值。如果键已经存在,SETNX将不做任何操作。例如:SETNX mykey "He11o"
SETNX 命令常常被用于实现锁和其他需要保证原子性的操作。例如,你可以使用SETNX 来实现一个分布式锁,只有第一个请求的客户端可以获得锁(设置成功),后来的客户端因为键已经存在,所以设置失败,从而实现锁的功能。
总的来说,SET和SETNX的主要区别在于它们如何处理键已经存在的情况。
List 数据类型
List类型是一种有序集合,也是Redis的基础数据结构之一。List类型内部实现为一个双向链表,即每个节点都有两个指针,一个指向前一个节点,一个指向后一个节点。
List功能非常强大,我们既可以把它当成栈(先进后出)、队列(先进先出),阻塞队列(超时时间)并且可以存放重复的值。
List甚至可以使用负数下标,以-1表示列表的最后一个元素,-2表示列表的倒数第二个元素,以此类推。
常用命令
- LPUSH key value1 value2 将一个或多个值插入到列表头部(左侧)
 - LRANGE key start stop 获取列表指定范围内的元素,根据下标
 - RPUSH key value1 value2 在列表中(右侧)添加一个或多个值
 - LPOP key 移除并获取列表的第一个元素
 - RPOP key 移除并获取列表最后一个元素
 - LINDEX key index 通过索引获取列表中的元素
 - LLEN key 获取列表长度
 - LREM key count value 移除列表元素(可以移除多个重复的值)
 - LTRIM key start stop 对一个列表进行修剪(trim),就是说,通过下标让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。
 - RPOPLPUSH source destination 移除列表的最后一个元素,并将该元素添加到另一个列表并返回
 - EXISTS 也可以判断列表中是否有值 (exists list)
 - LSET key index value 通过索引设置列表元素的值(需要保证现有列表和下标存在,一般作为更新操作)
 - LINSERT key BEFORE|AFTER pivot value 在列表的元素前或者后插入元素
 - BLPOP key1 key2 timeout 移出并获取列表的第一个元素,如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
 - BRPOP key1 key2 timeout 移出并获取列表的最后一个元素,如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。
 
- List小节
 - 我们可以把list看成一个链表,前后中间都可以插入数据
 - 如果key不存在,则创建新的list(链表)
 - 如果key存在,新增或者修改内容
 - 如果某—个list中没有任何数据,表示不存在(空链表)
 - 既然类似于链表,两边数据的插入和改动效率高,中间效率稍低
 - 常用功能:消息队列、消息排队(Ipush rpop)栈 (Ipush Ipop)
 
Set 数据类型
Redis的Set是string类型的无序集合。集合成员是唯一的,这就意味着集合中不能出现重复的数据(无序不重复)
常见命令
- SADD key member1 [member2] 向集合添加一个或多个成员
 - SMEMBERS key 返回集合中的所有成员
 - SISMEMBER key member 判断 member 元素是否是集合 key 的成员
 - SCARD key 获取集合的成员数
 - SREM key member1 [member2] 移除集合中一个或多个成员
 - SRANDMEMBER key [count] 返回集合中一个或多个随机数
 - SPOP key 移除并返回集合中的一个随机元素(原子操作,多个客户端并发访问时,每个返回的元素都是唯一的)
 - SMOVE source destination member 将 member 元素/ source 集合移动到 destination 集合
 - SDIFF key1 key2 返回给定所有集合的差集(两个set中不同的值)
 - SINTER key1 key2 返回给定所有集合的交集(两个set中相同的值)
 - SUNION key1 key2 返回所有给定集合的并集(两个set中所有的值,重复的只有一个)
 - SDIFF、SINTER、SUNION 这些命令就可以完成 共同好友、共同爱好等类似的功能,比如将用户的关注的人关注放入到set中,即可完成“共同关注"功能
 - SDIFFSTORE destination key1 key2 返回给定所有集合的差集并存储在 destination 中
 - SINTERSTORE destination key1 key2 返回给定所有集合的交集并存储在 destination 中
 - SUNIONSTORE destination key1 key2 所有给定集合的并集存储在 destination 集合中由于Set类型的特性,它经常被用来实现标签系统,好友关系,粉丝关系等功能。
 
Hash 数据类型
Redis hash 是一个String类型的field和value的映射表,hash特别适合用于存储对象。
我们可以把它想象成Map集合 key:<key-value>
Redis的Hash数据类型是用来表示键值对映射的一种数据类型,通常用于表示对象,如用户信息,商品信息等。哈希可以存储人量的字段-值对,并且设计得十分节省空间,使其成为表示数据对象的理想选择。你可以用哈希来表示基本对象,也可以用来存储一组计数器等多种数据。
常见命令
- HSET key field1 value1 field2 value2 同时将多个 field-value(域-值)对设置到哈希表 key 中
 - 注意:Redis 4.0.0版本以后,HMSET被视为已弃用。请在新代码中使用HSET
 - HGET key field 获取存储在哈希表中指定字段的值
 - HMGET key field1 field2 获取所有给定字段的值
 - HGETALL key 获取在哈希表中指定 key 的所有字段和值
 - HDEL key field2 field2删除一个或多个哈希表字段
 - HLEN key 获取哈希表中字段的数量
 - HKEYS key 获取所有哈希表中的字段
 - HVALS key 获取哈希表中所有值
 - HEXISTS key field 查看哈希表key 中,指定的字段是否存在。
 - HINCRBY key field increment 为哈希表 key 中的指定字段的整数值加上增量increment(如果是负数,就是減量)。
 - HSETNX key field value 只有在字段 field 不存在时,设置哈希表字段的值(原子性操作)。
 
Zset 数据类型(Sorted Set)
在Redis中,ZSET(有序集合)是一种复合类型的数据结构,它将Set和Hash两种数据结构进行了结合,类似于Java的TreeMap(实际上是SkipList实现)。
在ZSET中,每个元素都是唯一的(就像set),但每个元素关联了一个socre(就像Hash中的Value)。
这个socre(分数)用于对元素进行从小到大的排序。
可以简单理解为在set的基础上,增加了一个值,例如:zset k1 score v1
特点:可排序、元素不重复、查询速度快
由于这个特点所以Zset经常被用于排行榜类型的功能
注意:所有的排序默认都是升序排序,如果需要降序需要在Z后面加上REV
常用命令
- ZADD key score member [score member ⋯.]向有序集合添加一个或多个成员,或者更新已存在成员的分数。
 - ZRANGE key start stop [WITHSCORES]通过索引区间返回有序集合指定区间内的成员。成员按分数值递增(从小到大)来排列。
 - ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count] 通过分数返回有序集合指定区间内的成员(分数可以采用正负无穷大-inf +inf)。
 - ZREM key member 从有序集合中删除一个成员。
 - ZCARD key 返回有序集合的成员数量
 - ZCOUNT key min max返回有序集合中分数在给定范围内的成员数量。
 - ZSCORE key member 返回有序集合中指定成员的分数。
 
Redis特殊数据类型-Hyperloglog基数统计
HyperLogLog 是一种概率数据结构,用于估计集合的基数。
HLL(简称)其实代替了通过Set保存用户ID,统计set中元素数量来计算用户访问量的传统方式,因为我们的目的是为了统计独立用户访问量,而并非记录用户id或者用户表示等数据
计算唯一项目通常需要与要计算的项目数量成比例的内存量,因为需要记住过去已经见过的元素,以避免多次计算它们。所以这就会导致计算基数内存量会占用较多。
但是HyperLogLog实现最多使用12KB内存,就可以计算进阶2^64个不同元素的基数。
每个HyperLogLog只会根据输入元素来计算基数,而本身不会储存元素,所以HLL不能像其他集合那样返回各个元素本身。
什么是基数?
基数:用于统计一个集合中不重复的元素个数,其本身就是对集合去重后,统计剩余元素的个数
        A:{1,2,4,6,3,2,1}
        去掉重复的元素
        B:{1,2,4,6,3} = 5(基数)注意:HLL官方说明中提出了,会有标准0.81%的误差,但是在大数据统计的时候可以忽略不计
常见使用场景
统计网站的访问uv(网站独立用户访问量)
• 当前页面独立访问次数统计
• 一首歌曲的独立用户播放人数
• 一个视频的独立用户观看人数
相关命令
- PFADD key element [element..] 添加指定元素到HyperLogLog中
 - PFCOUNT 返回给定HyperLogLog的基数估算值
 - PFMERGE将多个HyperLogLog合并为一个HLL
 
Redis特殊数据类型-BitMaps
Redis的Bitmaps是一种紧凑的数据结构工用于存储二进制逻辑和状态。然而,需要注意的是,Bitmaps并不是实际的数据类型,而是定义在String类型上的一组位操作。
简单理解Bitmaps其实就是通过 位来保存二进制数据,通过01的方式来表示两种状态。
适合的场景
- 钉钉打卡 0表示未打卡1表示打卡
 - 登录状态
 
一个byte(字节)为8位
例子
统计某个员工一周的打卡情况
0表示未打卡
1表示打卡
        
相关命令
- SETBIT key offset val 命令在提供的偏移处 (offset)将位设置为0或1
 - GETBIT key offset 此命令返回给定偏移处的位的值
 - BITOP operation destkey key Ikey ..]命令可以在一个或多个字符串上执行位运算,包括AND、OR、XOR和NOT操作
 - AND:这是按位与操作。在每一位上,如果两个数字都为1,结果就是1,否则是0。例如,0101 AND 0011结果为0001。
 - OR:这是按位或操作。在每一位上,如果任何一个数字为1,结果就是1,否则是0。例如,0101 OR 0011结果为0111。
 - XOR:这是按位异或操作。在每一位上,如果两个数字不相同,结果就是1,否则是0。例如,0101 XOR 0011结果为0110。
 - NOT:这是按位非操作。这个操作将输入键的每个位反转(0变为1,1变为0)。例如,NOT 0101结果为1010。
 - BITCOUNT key start end 这个命令用于报告设置为1的位的数量
 - 注意:start和end参数定义了要检查的字节范围(不是位的范围)
 - 这两个参数都是基于字节的,而不是基于位的。也就是说,如果你有一个包含8位的字符串,start=0和 end=0将只检查第一个字节(即前8位)
 - STRLEN key 用于统计占用的字节数