Redis数据类型以及复杂度。

一、String

  • 应用:String结构使用非常广泛、最常见的就是缓存用户信息。将用户信息结构体使用JSON序列化成字符串、存入redis中、获取时再将value反序列化成目标对象。
    string 类型是二进制安全的。意思是 redis 的 string 可以包含任何数据。比如jpg图片或者序列化的对象。
  • 常用操作
  • 储存 set key value 时间复杂度 O(1)
Max_:1>set username Max
  • 获取 get key 时间复杂度 O(1)
Max_:1>get username    "Max"
  • 删除 del key 时间复杂度 O(k) k是键的个数
Max_:1>del username
  • 先取值后塞值 getset key value 时间复杂度 O(1)
Max_:1>set name tom

"OK"

Max_:1>getset name jack

"tom"
  • 追加值 append key value ;如果 key 已经存在,则直接在对应的 value 后追加值否则就创建新的键值对 时间复杂度 O(1)
Max_:1>append name lalal
"9"

Max_:1>get name
"jacklalal"
  • 是否存在key exists key 存在返回1,否返回0 时间复杂度 O(1)
Max_:1>exists name

"1"

二、List

  • 应用:Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。
  • 常用操作
  • 将元素添加到列表的左边:lpush key value 时间复杂度 O(k) k是field的个数
Max_:3>lpush mylist a

"1"

Max_:3>lpush mylist b

"2"
  • 将元素添加到列表的右边:rpush key value 时间复杂度 O(k) k是field的个数
Max_:3>rpush mylist c

"3"

Max_:3>rpush mylist d

"4"
  • 范围获取:lrange key start end 时间复杂度O(s+n),s是start的偏移量,n是start到end的范围
Max_:3>lrange mylist 0 3
 1)  "b"
 2)  "a"
 3)  "c"
 4)  "d"
  • 删除并返回列表左边的元素: 时间复杂度 O(1)
Max_:3>lpop mylist

"b"
  • 删除并返回列表右边的元素: 时间复杂度 O(1)
Max_:3>rpop mylist 

"d"
  • 根据参数 count 的值,移除列表中与参数 value 相等的元素。 LREM key count value 时间复杂度 O(1)
  • 将列表 key 下标为 index 的元素的值设置为 value 。 LSET key index value 时间复杂度 O(n) n是索引的偏移量
  • 返回列表 key 的长度。 LLEN key 时间复杂度 O(1)
  • 对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。 LTRIM key start stop 时间复杂度O(n) n是索引的偏移量==
  • 返回列表 key 中,下标为 index 的元素。 LINDEX key index 时间复杂度O(n) n是索引的偏移量

三、Hash

  • 应用:hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。
  • 常用操作
  • 存储 hset key field value 时间复杂度 O(1)
Max_:2>hset myhash username lisi

"0"
  • 获取指定field对应的value:hget key field 时间复杂度 O(1)
Max_:2>hget myhash username

"lisi"
  • 获取所有的field和value:hgetall key 时间复杂度 0(k),k是field的个数
Max_:2>hgetall myhash

 1)  "username"

 2)  "lisi"
  • 删除 hdel key field 时间复杂度 0(k),k是field的个数
Max_:2>hdel myhash username

"1"
  • 获取key里面的键值对数量 hlen hash的key 时间复杂度 O(1)
  • hexists:判断键值是否存在。hexists hash的key 项的key 时间复杂度 O(1)
  • hkeys:获取所有的item的key,hkeys hash的key 时间复杂度 0(k),k是field的个数
  • hincrby : 增减整数数字,:hincrby Hash的key 项的key 正负整数 时间复杂度 O(1)

四、Set

  • 应用:Redis 的 Set 是 string 类型的无序集合。
    集合是通过哈希表实现的。
  • 常用操作
  • 添加:sadd key value,可以写多个value 时间复杂度O(k),k为元素个数
Max_:4>sadd myset a b c d
"4"

Max_:4>sadd myset b c 
"0"
  • 获取set集合中所有元素:smembers key、 时间复杂度O(n),n为元素总数
Max_:4>smembers myset
 1)  "c"
 2)  "b"
 3)  "d"
 4)  "a"
  • 删除某个元素:srem key value 时间复杂度O(k),k为元素个数
Max_:4>srem myset a

"1"
  • 获取集合的成员数 scard key 时间复杂度 O(1)
  • 移除并返回集合中的一个随机元素 spop key 时间复杂度 O(1)
  • 移除集合中一个或多个成员 srem key member1 [member2] 时间复杂度O(k),k为元素个数
  • 返回给定所有集合的交集 sinter key1 [key2] 时间复杂度O(m*k),k为多个集合中元素较少的个数,m是键个数
  • 返回所有给定集合的并集 sunion key1 [key2] 时间复杂度O(k),k为多个集合元素个数和

五、Zset

  • 应用:Redis zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。
    不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。
    zset的成员是唯一的,但分数(score)却可以重复。
  • 常用操作
  • 存储:zadd key score value 时间复杂度O(k*log(n)),k为添加 成员个数,n为当前成员个数
Max_:5>zadd mysort 1 Max

"1"

Max_:5>zadd mysort 2 Sex

"1"

Max_:5>zadd mysort 3 Tax

"1"
  • 获取:zrange key start end [withscores] | zrange mysort 0 -1 withscores 时间复杂度O(log(n)),n为当前成员个数
Max_:5>zrange mysort 0 -1

 1)  "Max"

 2)  "Sex"

 3)  "Tax"

Max_:5>zrange mysort 0 -1 withscores

 1)  "Max"

 2)  "1"

 3)  "Sex"

 4)  "2"

 5)  "Tax"

 6)  "3"
  • 删除:zrem key value 时间复杂度O(k*log(n)),k为删除成员个数,n为当前成员个数
Max_:5>zrem mysort Tax

"1"
  • 对有序集合中指定成员的分数加上增量 increment 时间复杂度O(log(n)),n为当前成员个数
    ZINCRBY key increment member
  • 获取有序集 key 的元素成员的个数 时间复杂度 O(1)
    zcard key
  • 获取有序集 key 中,所有 score 值介于 min 和 max 之间(包括 min 和 max)的成员,有序 成员是按递增(从小到大)排序。 时间复杂度O(log(n)+k),k为要获取成员个数,n为当前成员个数
    zrangebyscore key min max [WITHSCORES ] [LIMIT offset count]

六、bitmap

  • 应用场景与简介:就是通过一个bit位来表示某个元素对应的值或者状态,其中的key就是对应元素本身。我们知道8个bit可以组成一个Byte,所以bitmap本身会极大的节省储存空间。 使用场景 <用户周活跃> <统计活跃用户> <用户在线状态> <用户签到>等
  • 常用操作:
  • 设置或者清空key的value(字符串)在offset处的bit值(只能只0或者1)。
Max_:6>setbit mytest1 8987129 0

"0"

Max_:6>setbit mytest1 8987129 1

"0"
  • 对key1 key2做opecation并将结果保存在rs上 bitop operation rs key1 [key2…]
Max_:6>bitop OR result Monday Tuesday Wednesday Thursday Friday Saturday Sunday

"1123392"
  • 对一个或多个保存二进制位的字符串 key 进行位元操作,并将结果保存到 destkey 上。
    BITOP operation destkey key [key …]
  • 参考

七、geohash

  • 应用场景与简介: Redis 在 3.2 版本以后增加了地理位置 GEO 模块,意味着我们可以使用 Redis 来实现摩拜单车「附近的 Mobike」、美团和饿了么「附近的餐馆」这样的功能了。 业界比较通用的地理位置距离排序算法是 GeoHash 算法.GeoHash 算法将二维的经纬度数据映射到一维的整数,这样所有的元素都将在挂载到一条线上,距离靠近的二维坐标映射到一维后的点之间距离也会很接近。当我们想要计算「附近的人时」,首先将目标位置映射到这条线上,然后在这个一维的线上获取附近的点就行了。
    底层zset
  • 常用操作:
  • geoadd 指令携带集合名称以及多个经纬度名称三元组,注意这里可以加入多个三元组
127.0.0.1:6379> geoadd company 116.48105 39.996794 juejin
(integer) 1
127.0.0.1:6379> geoadd company 116.514203 39.905409 ireader
(integer) 1
127.0.0.1:6379> geoadd company 116.489033 40.007669 meituan
(integer) 1
127.0.0.1:6379> geoadd company 116.562108 39.787602 jd 116.334255 40.027400 xiaomi
(integer) 2
  • geodist 指令可以用来计算两个元素之间的距离,携带集合名称、2 个名称和距离单位。
127.0.0.1:6379> geodist company juejin ireader km
"10.5501"
127.0.0.1:6379> geodist company juejin meituan km
"1.3878"
127.0.0.1:6379> geodist company juejin jd km
"24.2739"
127.0.0.1:6379> geodist company juejin xiaomi km
"12.9606"
127.0.0.1:6379> geodist company juejin juejin km
"0.0000"
  • geopos 指令可以获取集合中任意元素的经纬度坐标,可以一次获取多个。
127.0.0.1:6379> geopos company juejin
	 "116.48104995489120483"
 2) "39.99679348858259686"
127.0.0.1:6379> geopos company ireader
	 "116.5142020583152771"
 2) "39.90540918662494363"
127.0.0.1:6379> geopos company juejin ireader
	 "116.48104995489120483"
 2) "39.99679348858259686"
	 "116.5142020583152771"
 2) "39.90540918662494363"

补充:我们观察到获取的经纬度坐标和 geoadd 进去的坐标有轻微的误差,原因是 geohash 对二维坐标进行的一维映射是有损的,通过映射再还原回来的值会出现较小的差别。对于「附近的人」这种功能来说,这点误差根本不是事。

  • geohash 可以获取元素的经纬度编码字符串,上面已经提到,它是 base32 编码。 你可以使用这个编码值去 http://geohash.org/${hash}中进行直接定位,它是 geohash 的标准编码值。
127.0.0.1:6379> geohash company ireader
1) "wx4g52e1ce0"
127.0.0.1:6379> geohash company juejin
1) "wx4gd94yjn0"
  • 参考文章

八、hyperloglog

  • 应用场景与简介:
    Redis 在 2.8.9 版本添加了 HyperLogLog 结构。Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。
    在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。
    基数不大,数据量不大就用不上,会有点大材小用浪费空间
    有局限性,就是只能统计基数数量,而没办法去知道具体的内容是什么
    和bitmap相比,属于两种特定统计情况,简单来说,HyperLogLog 去重比 bitmap 方便很多
    一般可以bitmap和hyperloglog配合使用,bitmap标识哪些用户活跃,hyperloglog计数
    适用于一下场景:
  • 统计注册 IP 数
  • 统计每日访问 IP 数
  • 统计页面实时 UV 数
  • 统计在线用户数
  • 统计用户每天搜索不同词条的个数
  • 理解:HyperLogLog是一种算法,并非redis独有。目的是做基数统计,故不是集合,不会保存元数据,只记录数量而不是数值。
    耗空间极小,支持输入非常体积的数据量、核心是基数估算算法,主要表现为计算时内存的使用和数据合并的处理。最终数值存在一定误差。
  • 常用操作:
  • pfadd添加 影响基数估值则返回1否则返回0.若key不存在则创建 时间复杂度O(1)
127.0.0.1:6379> pfadd m1 1 2 3 4 1 2 3 2 2 2 2
(integer) 1
  • pfcount 获取基数值 也就是去重值 (1,1,2,2,3)的插入pfcount得到的是3、可以一次统计多个key 时间复杂度为O(N) n为key的个数,返回值是一个带有0.81%标准错误。
127.0.0.1:6379> pfadd m1 1 2 3 4 1 2 3 2 2 2 2
(integer) 1
127.0.0.1:6379> pfcount m1
(integer) 4
  • pfmerger合并多个key
    取多个key的并集
    命令只会返回OK
    时间复杂度 O(N)
127.0.0.1:6379> pfadd m1 1 2 3 4 1 2 3 2 2 2 2
(integer) 1
127.0.0.1:6379> pfcount m1
(integer) 4
127.0.0.1:6379> pfadd m2 3 3 3 4 4 4 5 5 5 6 6 6 1
(integer) 1
127.0.0.1:6379> pfcount m2
(integer) 5
127.0.0.1:6379> pfmerge mergeDes m1 m2
OK
127.0.0.1:6379> pfcount mergeDes
(integer) 6
  • 参考

九、streams

  • 应用场景及简介:
    Redis Stream 是 Redis 5.0 版本新增加的数据结构。Redis Stream 主要用于**消息队列**(MQ,Message Queue),Redis 本身是有一个 Redis 发布订阅 (pub/sub) 来实现消息队列的功能,但它有个缺点就是消息无法持久化,如果出现网络断开、Redis 宕机等,消息就会被丢弃。而 Redis Stream 提供了消息的持久化和主备复制功能,可以让任何客户端访问任何时刻的数据,并且能记住每一个客户端的访问位置,还能保证消息不丢失。
  • 内容较多。深入理解。 见几篇参考文章

补充:什么是二进制安全

二进制安全 是指,在传输数据时,保证二进制数据的信息安全,也就是不被篡改、破译等,如果被攻击,能够及时检测出来。