首页 > 数据库 >Redis中的数据结构

Redis中的数据结构

时间:2023-04-17 16:59:05浏览次数:51  
标签:存储 对象 Redis 列表 字符串 集合 数据结构

Redis中的数据结构

前言

Redis是一个高性能的分布式内存数据库,在国内外个大互联网公司中都有着广泛的使用,即使是一些非互联网公司也有着非常重要的使用场景。

Redis提供了五种主要的数据类型,它提供了强大且实用的功能,然而实际开发中,有大多数的开发者仅仅只会使用简单的 Redis String的 Get和Set,下面将回顾Redis五大对象,以便能够在实战中游刃有余。

  • String(终究是我扛下来所有)
  • Hash(存储对象我也行)
  • List(栈和队列我都行)
  • Set(标签系统我在行)
  • Sort Set(排起名来我最棒)

字符串

字符串类型是Redis最基础的数据结构,其他几种数据结构都是在字符串类型基础上构建的。字符串类型的值是字符串(简单的字符串、复杂的字符串(例如JSON、XML))、数字(整数、浮点数),甚至是二进制(图片、音频、视频)等。

image-20200626095844113

字符串对象的内部编码有3种 :intrawembstr,Redis会根据当前值的类型和长度来决定使用哪种编码来实现

  • int:如果一个字符串对象保存的是整数值,并且这个整数值可以用long类型来表示
  • raw:如果字符串对象保存的是一个字符串值,并且这个字符串值的长度大于32字节
  • embstr:如果字符串对象保存的是一个字符串值,并且这个字符申值的长度小于等于32字节

Reids字符串的使用场景是最为广泛的,甚至有些对redis其它几种对象不太熟悉的人,基本所有场景都会使用字符串(序列化一下直接扔进去),这让本身很单纯的字符串承受了它这个年纪本不该承受的重量。其实Redis的主要使用场景主要有以下几种:

  • 作为缓存层,缓存热点数据
  • Redis字符串可以自增自减的特性可以用来做计数器、限速器、自增ID生成等
  • 分布式系统的Session共享
  • 二进制数据的存储

关于更加详细的关于字符串结构的介绍,参考这篇博客

哈希

哈希对象用来存储一组数据对。每个数据对又包含键值两部分

image-20200626101327742

Hash对象也有两种实现方式:ziplist(压缩列表)hashtable(哈希表)

同样,只有当存储的数据量比较小的情况下,Redis才使用压缩列表来实现哈希对象,具体需要满足两个条件

  • 字典中保存的键和值的大小都要小于64字节
  • 字典中键值对的个数要小于512个

当不能同时满足上面的两个条件时,Redis就使用哈希表来实现Hash对象

当存储的内容是对象的时候,Redis字符串对象很多功能使用Redis 哈希对象也可以实现,如缓存用户信息的时候,使用Redis哈希对象存储,简单直观,如果使用合理可以减少内存空间的使用。

但是也有其缺点,就是要控制哈希在ziplist和hashtable两种内部编码的转换,hashtable将会消耗更多的内存。

此外,Hash对象还可以实现购物车和计数器等功能,更详细的介绍,参考这篇博客

列表

列表这种对象支持存储一组有序的,不重复的数据。因为其有序性,它可以获取指定范围的元素列表,可以在O(1)的时间复杂度获取指定索引的下标的元素等。

image-20200626105857594

在Redis3.2版本以前列表类型的内部编码有两种。当满足下面两个条件的时候,Redis 列表对象使用ziplist(压缩列表)来实现。

  • 当列表的元素个数小于list-max-ziplist-entries配置(默认512个)
  • 当列表中每个元素的值都小于list-max-ziplist-value配置时(默认64字节)

当列表类型无法满足ziplist条件时,Redis会使用linkedList作为列表的内部实现。

而在Redis3.2版本开始怼列表数据结构进行改造,使用quickList代替了zipList和linkedList。

由于列表对象的有序且不可重复的特性,它比较适合用来做文章、商品等列表的存储。

列表类型可以lpush(左侧push),同时又可以使用rpop(右侧弹出)第一个元素,所以列表类型具有先进先出的特性,可以用来实现消息队列,也可以lpush(左侧push)和lpop(左侧弹出),具有后进先出的特性,因此开发中需要使用栈的时候,我们可以使用列表对象来实现。

关于List更详细的介绍,参考这篇博客

集合

集合对象是一个无序且唯一的键值集合。它的存储顺序不会按照插入的先后顺序进行存储,与列表不同的是它存储的数据是无序且不重复的。

image-20200626122033221

集合对象的内部编码也有两种,intest(整数集合)与hashtable(哈希表),当满足下面两个条件的时候,集合对象使用intset来实现

  • 集合中的元素都是整数
  • 集合中元素的个数小于 set-maxintset-entries配置(默认512个)

不满足上面两个条件时,集合对象使用hashtable来实现

集合对象的主要两个特性就是:无序不可重复支持并交差,因此可以用来做标签系统

而集合中的 SPOP(随机移除并返回集合中一个或多个元素)SRANDMEMBER(随机返回集合中一个或多个元素) 命令可以帮助我们实现一个抽奖系统

有关Set更详细的介绍,参考这篇博客

有序集合

有序集合类型 (Sorted Set或ZSet) 相比于集合类型多了一个排序属性 score(分值),对于有序集合 ZSet 来说,每个存储元素相当于有两个值组成的,一个是有序结合的元素值,一个是排序值。有序集合保留了集合不能有重复成员的特性(分值可以重复),但不同的是,有序集合中的元素可以排序。

image-20200626123309037

有序集合是由 ziplist (压缩列表)skiplist (跳跃表) 组成的。

当数据比较少时,有序集合使用的是 ziplist 存储的,有序集合使用 ziplist 格式存储必须满足以下两个条件:

  • 有序集合保存的元素个数要小于 128 个;
  • 有序集合保存的所有元素成员的长度都必须小于 64 字节。

如果不能满足以上两个条件中的任意一个,有序集合将会使用 skiplist 结构进行存储。

有序集合比较典型的使用场景就是排行榜系统例如学生成绩的排名。某视频(博客等)网站的用户点赞、播放排名、电商系统中商品的销量排名等。

有关Redis有序集合对象的更详细的介绍,参考这篇博客

小结

Redis提供了五种最基础也是最常用的对象(数据类型):String、Hash、List、Set、ZSet。了解这五种对象的有助于我们更好的在日常开发中对Redis进行使用。而通过这篇文章我们可以看到每种对象都是通过多种数据结构来实现的,大家可以思考一下为什么。

标签:存储,对象,Redis,列表,字符串,集合,数据结构
From: https://www.cnblogs.com/salixleaf/p/17133941.html

相关文章

  • Redis_大白话谈IO模型
    通俗理解多种IO模型前言我们以故事来讲我们经常遇到的多种IO模型,首先故事的情节是老李去买火车票,三天后买到一张退票,其中往返车站耗时1小时。里面主要包含的人员有:老李,黄牛,售票员,快递员多种IO模型阻塞IO模型老李去火车站买票,排了三天队买到一张退票耗费:在火车站等了三......
  • Dockerfile详细使用、docker私有仓库、dockercompose介绍、dockerpose部署flask+redis
    昨日内容#1容器其他操作1dockerstart容器id2dockerstop容器id3dockerrm容器id4dockerrm`dockerps-aq`#正在运行的容器不能删除5dockerexec容器id命令6dockercp宿主机目录容器id:容器目录#目录要存在7docker......
  • redis在linux的操作
    redisredis特性速度快,10wops(秒读写)数据都是内存操作,c语言实现。单线程模型,所有的读写是同步的,不会出现脏读脏写持久化:rdb和aof策略多种数据结构:5大数据结构支持多种编程语言:基于tcp通信协议,各大编程语言都支持通信功能丰富:发布订阅(消息)Lua脚本,事务(pipeline)操作简单:不依......
  • 爬取的数据存mysql中、加代理,cookie,header,加入selenium、布隆过滤器、scrapy-redis实
    上节回顾#1scrapy架构 -爬虫:写的一个个类-引擎: -调度器:排队,去重-下载器-pipline-下载中间件-爬虫中间件#2命令 -scrapystartproject项目名-scrapygensipder爬虫名网址-scrapycrawl爬虫名字-run.py#......
  • 1 redis介绍 、2 redis linux下安装 、3 redis启动方式、4 redis典型场景 、5 redis通
    目录1redis介绍2redislinux下安装3redis启动方式3.1最简启动3.2动态参数启动3.3配置文件启动3.4客户端连接命令4redis典型场景5redis通用命令6数据结构和内部编码7redis字符串类型1redis介绍#特性Redis特性(8个)#速度快:10wops(每秒10w读写),数据存在内存中,c语言实现......
  • mysql和redis测试
    Go单测从零到溜系列2—MySQL和Redis测试发布于2021/09/14,更新于2021/09/1422:31:17|Golang|总阅读量:480次这是Go语言单元测试从零到溜系列教程的第2篇,介绍了如何使用go-sqlmock和miniredis工具进行MySQL和Redis的mock测试。在上一篇《Go单测从零到溜系列1—网络测试》中,......
  • 手动实现数据结构-栈结构
    1.栈结构是一种受限的线性结构。特点:先进后出2.使用TS实现1//封装一个栈使用泛型类2classArrayStack<T=any>{//给一个默认值为any类型3//定义一个数组,用于存储元素4privatedata:T[]=[]5//push:将元素压入栈中6push(e:T):void{7this.data.pus......
  • 聊聊Redis sentinel 机制
    Redis的哨兵机制自动完成了以下三大功能,从而实现了主从库的自动切换,可以降低Redis集群的运维开销:监控主库运行状态,并判断主库是否客观下线;在主库客观下线后,选取新主库;选出新主库后,通知从库和客户端。 一、为什么需要哨兵主从模式下,如果主库发生故障了,那就直接会影响到......
  • thinkphp: 用redis存储短信验证码(thinkphp v6.0.12LTS)
    一,配置redis1,编辑.env[REDIS0]TYPE=redisHOST=127.0.0.1PORT=6379PASSWORD=2,config/cache.php<?php//+----------------------------------------------------------------------//|缓存设置//+----------------------------------------------------......
  • 扎实打牢数据结构算法根基,从此不怕算法面试系列之004 week01 02-04 使用泛型实现线性
    1、算法描述在数组中逐个查找元素,即遍历。2、上一篇文的实现结果在扎实打牢数据结构算法根基,从此不怕算法面试系列之003week0102-03代码实现线性查找法中,我们实现了如下代码:packagecom.mosesmin.datastructure.week01.chap02;/***@Misson&Goal代码以交朋友、传福音......