redis八种基本数据类型及其应用 您所在的位置:网站首页 茶叶总共有多少种类型 redis八种基本数据类型及其应用

redis八种基本数据类型及其应用

2024-06-06 08:40| 来源: 网络整理| 查看: 265

redis八种基本数据类型及其应用

文章目录 redis八种基本数据类型及其应用1.简介2.安装redis3.基本命令3.1SET命令 4.基本数据类型4.1 String 字符串存储原理String的三种编码redis SDSembstr和raw应用场景 4.2 Hash 哈希ziplist 压缩列表ht(hashtable) 哈希表应用场景 4.3 List 列表List 存储原理(quicklist)应用场景 4.4 Set 集合存储结构应用场景 4.5 ZSet 有序集合存储结构应用场景 4.6 BitMaps4.7 Hyperloglogs4.8 Streams 5.总结数据结构编码转换 6.参考

1.简介

Redis是一个开源的,内存中的数据结构存储系统,它可以用做数据库,缓存和消息中间件。

支持多种类型的数据结构

字符串 strings散列 hashes列表 lists集合 sets有序集合 sorted setsbitmapshyperloglogs地理空间 geospatial 索引半径查询

支持每秒10w次查询请求

2.安装redis

Linux CentOS7安装和启动redis

设置alias方便操作

ls |grep redis #找到redis的安装路径 alias rcli='/usr/bin/redis-cli' #设置别名 #使用别名登录 rcli 3.基本命令

推荐网站 http://redisdoc.com/ [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h82HM4Tu-1579594343657)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200120110919117.png)]

3.1SET命令

网站上已经介绍的很清楚了,本文就不赘述了,我们直接看效果。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dRrAAhTJ-1579594343659)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200120111238082.png)] 这有个小问题 (error) NOAUTH Authentication required. 提示没有认证。我们需要输入密码即可

AUTH password。

set qingshan 666 设置key=qingshan value=666get qingshan 获取key=qingshan的value值

那么我们一般 set 的数据在redis中是什么类型?

type qingshan - > string [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o1vKR6yZ-1579594343659)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200120111949262.png)]

4.基本数据类型

官网数据类型介绍地址 https://redis.io/topics/data-types-intro

官网有 8 种,前面 5 种为常用数据结构

string 二进制安全的字符串Lists: 按插入顺序排序的字符串元素的集合。他们基本上就是链表(linked lists)。Sets: 不重复且无序的字符串元素的集合。Sorted sets,类似Sets,但是每个字符串元素都关联到一个叫score浮动数值(floating number value)。里面的元素总是通过score进行着排序,所以不同的是,它是可以检索的一系列元素。(例如你可能会问:给我前面10个或者后面10个元素)。Hashes,由field和关联的value组成的map。field和value都是字符串的。这和Ruby、Python的hashes很像。Bit arrays (或者说 simply bitmaps): 通过特殊的命令,你可以将 String 值当作一系列 bits 处理:可以设置和清除单独的 bits,数出所有设为 1 的 bits 的数量,找到最前的被设为 1 或 0 的 bit,等等。HyperLogLogs: 这是被用于估计一个 set 中元素数量的概率性的数据结构。Streams:5.0版本新增, append-only collections of map-like entries that provide an abstract log data type. 可以用来做持久化的消息队列 4.1 String 字符串 存储原理

假设存储 key = hello vlaue = word

set hello word [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vkaWlhrs-1579594343660)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200120115354305.png)]

String的三种编码 int,存储8个字节的长整型(long,2^63-1)embstr,embstr格式的SDS(Simple Dynamic String)raw,SDS,存储大于44个字节的字符串

redis 为什么要自己写一个SDS的数据类型

主要是为了解决C语言 char[] 的四个问题

字符数组必须先给目标变量分配足够的空间,否则可能会溢出查询字符数组长度 时间复杂度O(n)长度变化,需要重新分配内存通过从字符串开始到结尾碰到的第一个\0来标记字符串的结束,因此不能保存图片、音频、视频、压缩文件等二进制(bytes)保存的内容,二进制不安全 redis SDS 不用担心内存溢出问题,如果需要会对 SDS 进行扩容因为定义了 len 属性,查询数组长度时间复杂度O(1) 固定长度空间预分配,惰性空间释放根据长度 len来判断是结束,而不是 \0 embstr和raw

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-98KQgtzI-1579594343660)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200120144602150.png)]

当 value 的值为整型时,编码为 int当 value 值为字符时,存储的编码为 embstr,连续的内存空间,只需要分配一次当 value 值字符长度超过 44 时,存储的编码为 raw,不是连续的内存空间,需要分配两次如果 value 的值为 int 或者 embstr ,然后通过 append 添加字符的时候,也会转化为 raw 类型(因为 embstr 设计的是只读的,如果发生变化只能再开辟一块空间),而且这个过程是不可逆的。 应用场景 缓存,热点数据分布式sessionset key value NX EX 分布式锁INCR计数器 文章的阅读量,微博点赞数,允许一定的延迟,先写入 Redis 再定时同步到数据库 全局ID INT 类型,INCRBY,利用原子性 INCR 限流 以访问者的 IP 和其他信息作为 key,访问一次增加一次计数,超过次数则返回 false。 setbit 位操作 4.2 Hash 哈希

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-P08IOaaL-1579594343661)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200120162911742.png)]

对于这种类似于数据库表的结构,redis中可以使用hash进行存储

批量设置

hmset coder:xwf age 30 addr wuhan tag java

批量获取

hmget coder:xwf age addr tag

执行效果: [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HV3H4be0-1579594343661)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200120163552719.png)]

**同样是存储字符串,Hash 与 String 的主要区别? **

1、把所有相关的值聚集到一个 key 中,节省内存空间

2、只使用一个 key,减少 key 冲突

3、当需要批量获取值的时候,只需要使用一个命令,减少内存/IO/CPU 的消耗

Hash 不适合的场景:

1、Field 不能单独设置过期时间

2、没有 bit 操作

3、需要考虑数据量分布的问题(value 值非常大的时候,无法分布到多个节点)

hash表有两种存储的数据编码

如果Field的个数超过 512 个 或者 Field 中任意一个 键或者值 的长度大于 64个字节,hash表会用ht来存储

redis配置文件

hash-max-ziplist-entries 512 hash-max-ziplist-value 64 ziplist 压缩列表

ziplist 是一个经过特殊编码的双向链表,它不存储指向上一个链表节点和指向下一 个链表节点的指针,而是存储上一个节点长度和当前节点长度,通过牺牲部分读写性能, 来换取高效的内存空间利用率,是一种时间换空间的思想。只用在字段个数少,字段值小的场景里面 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3mS2sFKm-1579594343661)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200120165318390.png)]

ht(hashtable) 哈希表

在 Redis 中,hashtable 被称为字典(dictionary),它是一个数组+链表的结构。

为什么有 ht[0] 和 ht[1] 两个hash表,是为了扩容。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DFDCxy29-1579594343662)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200120192718161.png)]

应用场景

购物车 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l3qoFn7w-1579594343662)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200120184047773.png)]

存储命令用户idkey商品idfield1商品数量value1商品价格field2商品价格值value2 操作命令商品+1hincr商品-1hdecr删除hdel全选hgetall商品数量hlen 4.3 List 列表

有序,左边是列表头,从左到右

存储有序的字符串(从左到右),元素可以重复。可以充当队列和栈的角色。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O5aYoeT2-1579594343663)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200120190102111.png)] [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v9JoHrOm-1579594343663)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200121160924862.png)]

127.0.0.1:6379> lpush queue a (integer) 1 127.0.0.1:6379> lpush queue b c (integer) 3 127.0.0.1:6379> lrange queue 0 -1 1) "c" 2) "b" 3) "a" 127.0.0.1:6379> rpush queue d e (integer) 5 127.0.0.1:6379> lrange queue 0 -1 1) "c" 2) "b" 3) "a" 4) "d" 5) "e" 127.0.0.1:6379> lpop queue "c" 127.0.0.1:6379> lrange queue 0 -1 1) "b" 2) "a" 3) "d" 4) "e" 127.0.0.1:6379> rpop queue "e" 127.0.0.1:6379> lrange queue 0 -1 1) "b" 2) "a" 3) "d" List 存储原理(quicklist)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KaH2a3M6-1579594343664)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200120185909116.png)] 内部是一个双向链表,*zl 指针指向的是 ziplist 压缩列表,数据真正还是存储在 ziplist 中。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TChTwnro-1579594343664)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200120191151179.png)]

应用场景 时间线队列栈 4.4 Set 集合

一个 set 集合可以存储 2^63-1 个元素

127.0.0.1:6379> sadd xwfset 123 a b c d e f g 456 (integer) 9 127.0.0.1:6379> smembers xwfset 1) "e" 2) "f" 3) "b" 4) "d" 5) "g" 6) "123" 7) "a" 8) "c" 9) "456" 存储结构 intsethashtable 127.0.0.1:6379> object encoding xwfset "hashtable" 127.0.0.1:6379> sadd intsets 1 2 3 (integer) 3 127.0.0.1:6379> object encoding intsets "intset" 应用场景

1.知乎点赞数 在这里插入图片描述 2.京东的商品筛选 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7UWFCFsm-1579594343665)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200120194833288.png)]

127.0.0.1:6379> sadd brand:apple iPhone11 (integer) 1 127.0.0.1:6379> sadd brand:ios iPhone11 (integer) 1 127.0.0.1:6379> sadd screensize:6.0-6.24 iPhone11 (integer) 1 127.0.0.1:6379> sadd memorysize:256GB iPhone11 (integer) 1 127.0.0.1:6379> sinter brand:apple brand:ios screensize:6.0-6.24 memorysize:256GB 1) "iPhone11"

筛选商品,苹果,IOS,屏幕6.0-6.24,内存大小256G

sinter brand:apple brand:ios screensize:6.0-6.24 memorysize:256GB

3.微博关注

用户(编号user001)关注

sadd focus:user001 user003

sadd focus:user002 user003 user004

相互关注

sadd focus:user001 user002

sadd focus:user002 user001

#判断用户2是否关注了用户1 127.0.0.1:6379> SISMEMBER focus:user002 user001 (integer) 1

我关注得到人也关注了他(共同关注)

#获取关注的交集 127.0.0.1:6379> sinter focus:user001 focus:user002 1) "user003"

可能认识的人

#将所有的人存放到allusers集合 127.0.0.1:6379> SUNIONSTORE alluser:user001 focus:user001 focus:user002 (integer) 4 127.0.0.1:6379> SDIFF alluser:user001 focus:user001 1) "user004" 2) "user001" #剔除掉自己 127.0.0.1:6379> SREM alluser:user001 user001 (integer) 1 127.0.0.1:6379> SDIFF alluser:user001 focus:user001 1) "user004" 4.5 ZSet 有序集合

每个元素有一个对应的分数,基于分数进行排序;如果分数相等,以key值的 ascii 值进行排序。

数据结构对比

数据结构是否允许重复元素是否有序有序实现方式list是是索引下标set否否无zset否是分值score 存储结构

ziplist

skiplist+dict 跳表+字典

redis配置文件

如果元素的个数超过 128 个 或者 元素中任意一个 value 的大小超过 64个字节,存储会采用 skiplist 跳表

zset-max-ziplist-entries 128 zset-max-ziplist-value 64

什么是 skiplist ?

上面的是普通的链表,下面的是跳表,level 是随机的

普通链表查找一个元素的时间复杂度为O(n)

跳表的时间复杂度为O(m*log2n) [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dPDRBP4F-1579594343666)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200121103942711.png)] 假设我们找元素19

1.先从起始的 level3 指针中查找 26 大于 19

2.退回到起始的 level2 的指针,大于7 继续往后,找到19

3.通过三次就找到了19

简书的一篇文章:redis用到的非常高效的数据结构–跳表

应用场景

1.商品的评价标签,可以记录商品的标签,统计标签次数,增加标签次数,按标签的分值进行排序 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-97TPeJgR-1579594343666)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200120195514557.png)]

#添加商品(编号i5001)的标签tag和对应标签的评价次数 127.0.0.1:6379> zadd good_tag:i5001 442 tag1 265 tag2 264 tag3 (integer) 3 #不带分数 127.0.0.1:6379> zrange good_tag:i5001 0 -1 1) "tag3" 2) "tag2" 3) "tag1" #带分数 127.0.0.1:6379> zrange good_tag:i5001 0 -1 withscores 1) "tag3" 2) "264" 3) "tag2" 4) "265" 5) "tag1" 6) "442"

2.百度搜索热点 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pJv8D7rq-1579594343667)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200120202817364.png)]

#维护2020年1月21号的热点新闻 127.0.0.1:6379> zadd hotspot:20200121 520 pot1 263 pot2 244 pot3 (integer) 3 127.0.0.1:6379> zrange hotspot:20200121 0 -1 withscores 1) "pot3" 2) "244" 3) "pot2" 4) "263" 5) "pot1" 6) "520" #增加点击次数 127.0.0.1:6379> ZINCRBY hotspot 1 pot1 "521" 4.6 BitMaps

Bitmaps 是在字符串类型上面定义的位操作。一个字节由 8 个二进制位组成。

应用场景:

用户访问统计

在线用户统计

4.7 Hyperloglogs

Hyperloglogs:提供了一种不太准确的基数统计方法,比如统计网站的 UV,存在一定的误差。

4.8 Streams

5.0 推出的数据类型。支持多播的可持久化的消息队列,用于实现发布订阅功能,借鉴了 kafka 的设计。

5.总结 数据结构 对象对象type属性值type命令输出object encoding字符串OBJ_STRING“string”int/embstr/raw列表OBJ_LIST“list”quicklist哈希OBJ_HASH“hash”ziplist/hashtable集合OBJ_SET“set”intset/hashtable有序集合OBJ_ZSET“zset”ziplist/skiplist 编码转换 对象元素编码升级编码再次升级字符串INT 整数并且小于 log 2^63-1embstr 超过44字节被修改raw哈希ziplist 键和值的长度小于64字节,键值对个数不超过521个hashtable列表quicklist集合intset 元素都是整数,元素个数小于512hashtable有序集合ziplist 任何一个member长度小于64字节,元素个数不超过128个skiplist 6.参考

咕泡学院 青山老师 redis-基础篇(原版更加具体,对照redis的源码进行讲解)



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有