Redis5种基本数据类型 详细介绍及底层如何存储 与 3种特殊数据类型

Key

redis作为K-V键值对类型的数据库,其中的key都是String类型
所以数据类型讨论的是value的结构

key的常用操作
在这里插入图片描述

db-redis-ds-1.jpg

5中基本数据类型

String(字符串)

  1. string 是redis中最基本的数据类型
  2. string是二进制安全的,意思是redis中的string类型可以存储任何数据,例如jpg图片或序列化后的对象。
  3. string的大小最多为512M

0f3b97bb-9f5f-4151-87a2-c2105518133c.png

string常用命令

在这里插入图片描述

实战场景

  • 缓存: 经典使用场景,把常用信息,字符串,图片或者视频等信息放到redis中,redis作为缓存层,mysql做持久化层,降低mysql的读写压力。
  • 计数器:redis是单线程模型,一个命令执行完才会执行下一个,同时数据可以一步落地到其他的数据源。
  • session:常见方案spring session + redis实现session共享

与底层对应关系

(联系redis数据结构看)
string 支持三种编码方式RAW, INT, EMBSTR,三种编码方式内存结构如下
db-redis-ds-x-21.png

注意事项
  1. raw和embstr的区别

embstr 编码是专门用来保存短字符串的一种优化编码
区别:
embstr的使用只分配一次内存空间(因此redisObject和sds是连续的),而raw需要分配两次内存空间(分别为redisObject和sds分配空间)。因此与raw相比,embstr的好处在于创建时少分配一次空间,删除时少释放一次空间,以及对象的所有数据连在一起,寻找方便。而embstr的坏处也很明显,如果字符串的长度增加需要重新分配内存时,整个redisObject和sds都需要重新分配空间,因此redis中的embstr实现为只读。

2. 编码转换:当 int 编码保存的值不再是整数,或大小超过了long的范围时,自动转化为raw。

Hash(哈希)

  1. Redis中的hash 是一个键值对的集合
  2. hash是一个field(string类型)和value的映射表,适合用来存储对象 类似java中的Map<string,Obiect>db-redis-ds-4.png

Hash常用命令

在这里插入图片描述

实战场景

  • 缓存: 能直观,相比string更节省空间,的维护缓存信息,如用户信息,视频信息等。

与底层对应关系

(联系redis数据结构看)

哈希对象的编码可以是 ziplist 或者 hashtable;对应的底层实现有两种, 一种是ziplist, 一种是dict。
db-redis-ds-x-23.png
上图ptr指针应该指向红色dict实例

List(列表)

  1. Redis列表是一个简单的字符串列表,按照插入顺序排序,插入时可以选择头插或尾插
  2. 底层是一个链表,左右都可插入
  3. 如果值全部移除,键也会消失
  4. 头尾操作效率极高,但中间操作效率很低

db-redis-ds-5.png

List常用命令

实战场景

  • 微博TimeLine: 有人发布微博,用lpush加入时间轴,展示新的列表信息。
  • 消息队列

与底层对应关系

(联系redis数据结构看)
目前redis只有quicklist一种编码(之前版本中有linked和ziplist这两种编码)
db-redis-ds-x-22.png

Set(集合)

  1. Redis的set是string类型的无序,无重复集合,通过HashTable实现,所以添加,删除,查找的复杂度都是 O(1)。

db-redis-ds-7.png

Set常用命令

在这里插入图片描述在这里插入图片描述

实战场景

  • 标签(tag),给用户添加标签,或者用户给消息添加标签,这样有同一标签或者类似标签的可以给推荐关注的事或者关注的人。
  • 点赞,或点踩,收藏等,可以放到set中实现

与底层对应关系

(联系redis数据结构看)

集合对象的编码可以是 intset 或者 hashtable; 底层实现有两种, 分别是intset和dict。 显然当使用intset作为底层实现的数据结构时, 集合中存储的只能是数值数据, 且必须是整数; 而当使用dict作为集合对象的底层实现时, 是将数据全部存储于dict的键中, 值字段闲置不用.
db-redis-ds-x-24.png

Zset(有序集合)

  1. Redis中的Zset 和set一样为String类型的不允许重复的集合
  2. 不同的是它是有序的,每个元素都会关联一个double类型的score
  3. redis通过score类对集合中的成员进行排序。
  4. Zset的成员唯一,但score可以重复

db-redis-ds-8.png

Zset常用命令

在这里插入图片描述

实战场景

  • 排行榜:有序集合经典使用场景。例如小说视频等网站需要对用户上传的小说视频做排行榜,榜单可以按照用户关注数,更新时间,字数等打分,做排行。

与底层对应关系

(联系redis数据结构看)

有序集合的底层实现依然有两种, 一种是使用ziplist作为底层实现, 另外一种比较特殊, 底层使用了两种数据结构: dict与skiplist. 前者对应的编码值宏为ZIPLIST, 后者对应的编码值宏为SKIPLIST
ZipList
db-redis-ds-x-25.png
SKIPLIST(跳表)db-redis-ds-x-26.png

三种特殊数据类型

HyperLogLogs(基数统计)

什么是基数?

举个例子,A = {1, 2, 3, 4, 5}, B = {3, 5, 6, 7, 9};那么基数(不重复的元素)= 1, 2, 4, 6, 7, 9;
(允许容错,即可以接受一定误差)

HyperLogLogs 基数统计用来解决什么问题?

这个结构可以非常省内存的去统计各种计数,比如注册 IP 数、每日访问 IP 数、页面实时UV、在线用户数,共同好友数等。

127.0.0.1:6379> pfadd key1 a b c d e f g h i	# 创建第一组元素
(integer) 1
127.0.0.1:6379> pfcount key1					# 统计元素的基数数量
(integer) 9
127.0.0.1:6379> pfadd key2 c j k l m e g a		# 创建第二组元素
(integer) 1
127.0.0.1:6379> pfcount key2
(integer) 8
127.0.0.1:6379> pfmerge key3 key1 key2			# 合并两组:key1 key2 -> key3 并集
OK
127.0.0.1:6379> pfcount key3
(integer) 13

Bitmap (位存储)

Bitmap 即位图数据结构,都是操作二进制位来进行记录,只有0 和 1 两个状态。

用来解决什么问题?

比如:统计用户信息,活跃,不活跃! 登录,未登录! 打卡,不打卡! 两个状态的,都可以使用 Bitmaps
如果存储一年的打卡状态需要多少内存呢? 365 天 = 365 bit 1字节 = 8bit 46 个字节左右!

相关命令使用

使用bitmap 来记录 周一到周日的打卡!


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 0
(integer) 0
127.0.0.1:6379> setbit sign 3 1
(integer) 0
127.0.0.1:6379> setbit sign 4 0
(integer) 0
127.0.0.1:6379> setbit sign 5 0
(integer) 0
127.0.0.1:6379> setbit sign 6 1
(integer) 0

查看某一天是否有打卡!

127.0.0.1:6379> getbit sign 3
(integer) 1
127.0.0.1:6379> getbit sign 5
(integer) 0
127.0.0.1:6379> bitcount sign # 统计这周的打卡记录,就可以看到是否有全勤!
(integer) 3

geospatial (地理位置)

地理位置信息相关使用,可以推算入两点之间距离,方圆几里范围查找之类的操作

相关操作

//添加位置 geoadd
127.0.0.1:6379> geoadd china:city 118.76 32.04 manjing 112.55 37.86 taiyuan 123.43 41.80 shenyang
(integer) 3
127.0.0.1:6379> geoadd china:city 144.05 22.52 shengzhen 120.16 30.24 hangzhou 108.96 34.26 xian
(integer) 3

# 当坐标位置超出指定范围时,该命令将会返回一个错误。
127.0.0.1:6379> geoadd china:city 39.90 116.40 beijin
(error) ERR invalid longitude,latitude pair 39.900000,116.400000
    
    
    
    
//获取位置geopos 返回一个坐标值

127.0.0.1:6379> geopos china:city taiyuan manjing
1) 1) "112.54999905824661255"
   1) "37.86000073876942196"
2) 1) "118.75999957323074341"
   1) "32.03999960287850968"
    
  
//georadius 获得所有附近的人的地址, 定位, 通过半径来查询

127.0.0.1:6379> georadius china:city 110 30 1000 km			以 100,30 这个坐标为中心, 寻找半径为1000km的城市
1) "xian"
2) "hangzhou"
3) "manjing"
4) "taiyuan"
127.0.0.1:6379> georadius china:city 110 30 500 km
1) "xian"
127.0.0.1:6379> georadius china:city 110 30 500 km withdist
1) 1) "xian"
   2) "483.8340"
127.0.0.1:6379> georadius china:city 110 30 1000 km withcoord withdist count 2
1) 1) "xian"
   2) "483.8340"
   3) 1) "108.96000176668167114"
      2) "34.25999964418929977"
2) 1) "manjing"
   2) "864.9816"
   3) 1) "118.75999957323074341"
      2) "32.03999960287850968"
  
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值