Redis的一些数据类型(一)
(一)数据类型
我们说redis是key value键值对的方式存储数据,key是字符串,而value是一些数据结构,那今天就来说一下value存储的数据。
我们数据结构包含,String,hash,list,set和zest但是在redis内部真的就是按这些数据结构存储的嘛?
很明显上面的图告诉我们不是,我们在内部是由不同的内存编码来保存数据的,但是时间复杂度是跟我们的数据结构一样的,那我们先来看一下第一个
1.String
String数据结构内部编码由raw,int,embstr
raw:存储一些比较短的字符串
int:我们redis里没有存储整形数据的方法,所以我们一般会用字符串来保存整型数据,所以我们String里有一个内存编码int,如果我们存入整型数据的话,内存编码就是int类型来保存数据。
embstr:存储一些比较长的字符串
2.hash
hashtable:内部就是一个哈希表
ziplist:是一个压缩列表
3.list
内部包含
linkedlist:链表(不是很节省空间)但是效率比较高
ziplist:压缩列表,比较节省空间,但是效率不高
我们redis3.2开始引入了新的实现方式quicklist,同时兼顾了linkedlist和ziplist,其实quicklist就是个链表,每个元素又是一个ziplist,同时节省了空间和效率
4.set
hashtable:就是一个哈希表
intset:集合中存的元素都是整数
5.zset
skiplist:跳表,也是链表,每个节点上有多个指针域,使用这些指针域的指向可以做到从跳表上查询的时间复杂度是o(logn)
查询内部编码方式
使用object encoding key,用来查看key对应的value的实际编码方式(redis会自动根据实际情况,自动适应的)
redis单线程模式
我们之前说redis只使用一个线程来处理所有的命令请求,但是redis又很快,这看起来是相互矛盾的,因为多个线程一起执行怎么会比单线程还慢呢?
实际上redis确实只有多个线程,但是是用来处理网络IO
当我们两个客户端同时发起上述的请求,此时我们会产生疑问是否会产生线程安全问题
答案是不会,因为我们多个请求同时到达redis服务器,需要在队列中排队,再等待redis服务器一个一个取出里面的命令再执行,类似于实现了一个阻塞队列,微观上讲,redis服务器是串行执行这个多个命令的
而他快的原因就是因为他的业务逻辑都是些很简单的操作,不是很消耗cpu资源,但是redis由于是单线程模型就必须要小心,某一些操作占用时间太长了阻塞其他命令的执行,而且redis是访问内存数据库访问硬盘,并且正因为他是单线程模型,所以省去了一些线程竞争的开销
处理网络IO的时候是使用了类似epoll这样的IO多路复用机制
这里我们说一下什么是IO多路复用,这里我们在网络原理那几篇博客中说过,简单来说就是一个线程管理多个socket
我们来回顾一下,TCP客户端需要有一个sever socket,然后会给我们客户端分配一个socket,如果我们多个客户端同时访问,同时就有多个socket,但这些socket大多数情况下并不是一直都在传输数据,很多情况下socket都是静默的,因为没有数据要进行传输(可能在等待用户的输入),但也有一些socket是活跃的,我们之前实现的时候因为每个客户端都要分配一个线程,客户端多了,线程就多了,系统开销就会变大,所以我们当时有两个方案,一个就是引入协程(更小的线程),一个就是使用IO多路复用
那我们说IO多路复用就是一个线程管理多个socket,那对于这些socket也是有要求的,我们需要这几个socket交互不频繁,大部分时间都在等待,如果这几个socket的交互都特别频繁,那我们还是要使用多个线程的
(二)String类型
我们redis中的string是直接按照二进制数据的方式存储的不做任何的编码转换,存什么取什么(mysql中的默认字符集是拉丁文,所以我们插入中文会失败),因为是二进制方式存储的,所以我们也可以存一些音频和图片等(但不可以存太大的)
1.set和get
我们看后面的nx和xx,nx标识如果key不存在才设置value存在就不设置(返回nil),xx标识如果key存在那就设置不存在就不设置(返回nil),ex和px是设置过期时间单位是秒和毫秒。
redis文档给出的语法格式说明【】是独立的单元,可以同时存在多个【】,但是|是表示或,一个单元只能出现一个
我们现在库上有很多操作,我们可以有一个操作可以删除所有数据,就是flushall(我们一般不使用)
get的使用就很简单,但是get只是支持字符串类型的value,如果value是其他的类型,get就会出错
2.MSET和MGET
这两条命令一次可以操作多组键值对,我们之前也说过一次在exists查询多个key时说,我们redis是通过网络传输数据的,那如果一次传一个数据传多次就会导致我们大部分时间浪费在网络通信中,就会导致我们效率变低,但是如果我们一次传多个数据,就可以很好的节省我们的网络开销
但是还是我们说的那个问题,redis是单线程模型,如果我们一次性传太多的数据,就会导致我们的redis会花很长的时间进行处理,就会导致其他的请求等待,可能会引发一系列的问题
我们这里的时间复杂度都是O(1)
3.incr和incrby
incr就是针对value的值+1,我们这里的value必须要是整数,如果是小数,需要我们是以哦那个incrfloat可以针对小数进行加减操作,我们这里的incr操作的key如果不存在,我们就会把这个key的value当作0来使用
incrby就是把+1操作换成任意的一个整数,当然也可以是小数,但是这种减法我们会更适用于下一条指令
我们的返回值就是修改后的值
4.decr和decrby
与上条指令类似,就是把+变成了-,我们要注意value中的值必须要是整数,在64位范围内,如果这个key对应value不存在就会当0处理
decrby就是-n的操作
上述的操作时间复杂度都是o(1)
5.append字符串拼接
append是用来拼接字符串的,返回值是拼接后的长度,单位是字节,在redis中也是按照utf8进行编码所以一个汉字通常是三个字节
6.setrange设置一定范围的字符
默认从1开始设置,但是我们可以设置偏移量
但是如果是一个中文字符串就可能会出问题,如果我们凭空生成了一个字节,那么就会自动生成一个0x00
返回值是修改后的长度
7.strlen计算value中字符串长度
返回值就是value的长度单位是字节
8.getrange
我们可以设置获取的头和尾通过设置start和end(都是闭区间)
这里的start和end就类似于下标,但是redis下标可以支持负数,-1就表示倒数第一个元素,如果我们保存的是汉字,就会对字符串进行切分,到时候就不一定是一个完整的汉字了
9.String的编码方式
我们之前说String内部有三种编码方式,并且可以通过object encoding+key来查询内部编码方式,那么我们现在就来通过指令来看一下
1)int
首先内部编码为int:8个字节的长整型
如果我们存的使一个整数,那么内部就会变为int,但是我们强调必须是整数,如果是小数会怎么样?
可以看到,如果我们的存一个小数内部编码会变为emstr(用来存较短的字符串),所以整数用int存是方便我们进行算术运算的,小数用字符串来存,那么我们想要进行运算,就需要讲字符串转为小数,运算后再保存
2)embstr
如果字符串的长度小于某个数,内部就会自动编码为emstr,具体的数字默认为39
3)raw
如果字符串长度比较大,内部就会自动编码为raw
10.String的一些应用场景
1)缓存功能
这是我们redis作为缓存的模型,因为mysql从硬盘读取数据会比较慢,但是如果同时有很多请求,就会导致mysql出错,所以我们引入了redis,之前的博客也有详细说到过
那我们String具体在这里有什么用呢?我们说key中存的一定是String类型的数据,我们先来看一段伪代码
我们让用户传一个id,然后我们在内部拼接一个类似报头一样的字符串,这样我们就能清楚的知道,在redis中,这是什么数据,如果我们不加,我们很可能存在redis中存储了用户的id(key)商品的id(key)如果统一传来一个id,我们也无法知道具体是什么类,当然我们也不建议这个名称过长,会影响我们redis的一个效率
2)计数
我们上面说到内部编码的时候说String可以存整型数据,所以我们就可以把redis当作一个计数的基础工具,因为redis比较快,所以可以用来实现快速计数,查询缓存等功能,就比如我们播放一个视频,那我们视频的播放量就需要立刻+1
但是也有一些问题,就是redis不擅长统计数据,如果我们要通过value里存的整数来统计一些数据,就会比较麻烦,就比如我们统计播放量前10的数据,如果我们使用mysql,直接一个orderby,一个limite就可以直接查询到
所以我们需要一个统计数据的仓库,可以是mysql也可以是别的,来将播放量同步到其他数据源,由这个仓库来统计数据,这里我们写入统计数据的仓库的方式是异步的,也就是说,我们不需要获取数据就立刻给这个统计数据的仓库,等双方都不是很忙的时候,再进行同步就可以
3)session
我们在之前的博客里也说到了好几次session,他通常跟cookie一起出现
session用来存储服务器数据,cookie用来存储客户端数据(都是通过键值对的方式存储)
我们客户端向服务器发起了请求之后服务器要存储我们的数据,就存到了session中,然后给我们返回一个token(内部可能是sessionid也可以是别的,但是一定能通过这个找到对应的session),我们客户端通常就会把这个token中的数据存储到cookie中,然后我们下次请求服务器的时候,就会携带着cookie,服务器拿到cookie拿到sessionid,然后再获取对应的数据,那这个作为标识放到token中的数据,就是一个字符串
那这种通过负载均衡分配到不同服务器上的模型,如果只是我们上述说的过程,就不是很够用了,因为我们无法保证每一次访问的都是那一个服务器,所以我们需要再引入一个redis
我们通过引入个redis服务器来存储所有session,这样我们每个web服务器的session都会放到redis中,客户端拿着cookie来查询时,我们就会再访问redis寻找对应的session
4)手机验证码
我们现在每次登录一个东西,会让用户输入手机号并且发送一个验证码,通过验证码进行验证,确定是不是用户本人,但是验证码每多久才可以获取一次,并且有过期时间,这时我们就可以很好的利用我们的setex key +时间+value的指令
我们也可以验证短信,把收到的验证码提交,系统来进行验证
这是伪代码的实现
相关文章:

Redis的一些数据类型(一)
(一)数据类型 我们说redis是key value键值对的方式存储数据,key是字符串,而value是一些数据结构,那今天就来说一下value存储的数据。 我们数据结构包含,String,hash,list,set和zest但…...

论文复现:考虑电网交互的风电、光伏与电池互补调度运行(MATLAB-Yalmip-Cplex全代码)
论文复现:考虑电网交互的风电、光伏与电池储能互补调度运行(MATLAB-Yalmip-Cplex全代码) 针对风电、光伏与电化学储能电站互补运行的问题,已有大量通过启发式算法寻优的案例,但工程上更注重实用性和普适性。Yalmip工具箱则是一种基于MATLAB平台的优化软件工具箱,被广泛应用…...
HTTP 协议介绍
基本介绍: HTTP(Hyper Text Transfer Protocol): 全称超文本传输协议,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本地浏览器的传送协议。 HTTP 是一种应用层协议,是基…...

解决windows上VMware的ubuntu虚拟机不能拷贝和共享
困扰多时的VMware虚拟机不能复制拷贝和不能看到共享文件夹的问题,终于解决了~ 首先确定你已经开启了复制拷贝和共享文件夹,并且发现不好用。。。 按照下面方式解决这个问题。 1,删除当前的vmware tools。 sudo apt-get remove --purge ope…...
Python+rust会是一个强大的组合吗?
今天想和大家讨论一个在技术圈子里越来越火的话题——Python和Rust的组合。 不少程序员都开始探索这两个语言的结合,希望能借助Python的简洁和Rust的高性能,来打造出既易用又强大的软件。 那么,这对CP(编程组合)真的…...
引用和指针的区别
引用(reference)和指针(pointer)都是 C 中用来间接访问内存中对象的机制,但它们有一些重要的区别。以下是它们在语法、用法和特性上的详细区别。 下面从7个方面来详细说明引用和指针的区别 1. 定义与语法区别 引用&…...

内容生态短缺,Rokid AR眼镜面临市场淘汰赛
AR是未来,但在技术路径难突破、生态系统难建设,且巨头纷纷下场的背景下,Rokid能坚持到黎明吗? 转载:科技新知 原创 作者丨王思原 编辑丨蕨影 苹果Vision Pro的成功量产和发售,以及热门游戏《黑神话》等在A…...

【论文阅读】StoryMaker | 更全面的人物一致性开源工作
文章目录 1 Motivation2 背景 相关工作 Related work3 Method 方法4 效果 1 Motivation 背景是 Tuning-free personalized image generation methods无微调的个性化图像生成方式在维持脸部一致性上取得了显著性的成功。这里我不是很了解 然而,在多个场景中缺乏整…...

读构建可扩展分布式系统:方法与实践14流处理系统
1. 流处理系统 1.1. 时间就是金钱 1.1.1. 从数据中提取有价值的知识和获得洞见的速度越快,就能越快地响应系统所观察的世界的变化 1.1.2. 信用卡欺诈检测 1.1.3. 网络安全中异常网络流量的捕获 1.1.4. 在支持GPS的驾驶应用程序中进行的实时路线规划 1.1.5. 社交…...
C++第2课——取余运算符的应用、浮点型和字符型(含视频讲解)
文章目录 1、课程笔记2、课程视频 1、课程笔记 /* #include<iostream> using namespace std; int main(){//cout<<"hello,world!";//运算符的优先级 () * / % -// 3/2 1...1 3%21 5%32 3%53 -3%2-1 3%-21//cout<<6/4%2;//int 向下取整6…...
SQL常用技巧总结
查询优化基本准则 1、ORACLE 的解析器按照从右到左的顺序处理 FROM 子句中的表名,因此 FROM 子句中写在最后的表(基础表 driving table)将被最先处理。 在FROM 子句中包含多个表的情况下,你必须选择记录条数最少的表作为基础表。 例如: 表 T…...
AJAX(简介以及一些用法)
AJAX 1. 简介 什么是 Ajax Ajax 的全称是 Asynchronous JavaScript And XML (异步 JavaScript 和 XML )我们可以理解为:在网页中 利用 XMLHttpRequest 对象和服务器进行数据交互的方式就是 Ajax ,它可以帮助我们轻松实现网页…...

美畅物联丨GB/T 28181系列之TCP/UDP被动模式和TCP主动模式
GB/T 28181《安全防范视频监控联网系统信息传输、交换、控制技术要求》作为我国安防领域的重要标准,为视频监控系统的建设提供了全面的技术指导和规范。该标准详细规定了视频监控系统的信息传输、交换和控制技术要求,在视频流传输方面,GB/T 2…...

机器学习之实战篇——图像压缩(K-means聚类算法)
机器学习之实战篇——图像压缩(K-means聚类算法) 0. 文章传送1.实验任务2.实验思想3.实验过程 0. 文章传送 机器学习之监督学习(一)线性回归、多项式回归、算法优化[巨详细笔记] 机器学习之监督学习(二)二元逻辑回归 …...

轴承介绍以及使用
轴承(Bearing)是在机械传动过程中起固定、旋转和减小载荷摩擦系数的部件。也可以说,当其它机件在轴上彼此产生相对运动时,用来降低运动力传递过程中的摩擦系数和保持转轴中心位置固定的机件。 轴承是当代机械设备中一种举足轻重的…...
【JAVA】算法笔记
一、ArrayList ArrayList类是一个可以动态变化的数组,与普通数组的区别就是它没有固定的长度。 ArrayList<String> arrList new ArrayList<String>(); arrList.add("吐泡泡"); System.out.println(arrList.get(0)); arrList.set(0,"J…...

Gnu Radio抓取WiFi信号,流程图中模块功能
模块流程如图所示: GNURadio中抓取WiFi信号的流程图中各个模块的功能: UHD: USRP Source: 使用此模块配置USRP硬件进行信号采集。设置频率、增益、采样率等参数。Complex to Mag^2: 将复数IQ数据转换为幅度的平方。Delay…...
GO语言中make与new的区别
区别 1 make不仅分配内存,还会初始化。 new只会分配零值填充的值2make只适用slice,map,channel的数据,new 没有限制3make返回原始类型(T),new返回类型的指针(*T) 源码中定义的区别 func make(t Type,size …IntegerType) Type func new(Type) *Type f…...
安全运维类面试题
1、你熟悉哪些品牌的安全设备 答:天融信的ngfw防火墙,老牌防火墙厂商,功能比较齐全,像流量检测,web应用防护和僵木蠕等模块都有,界面是红白配色,设计稍微有点老 2、IPS用的是哪个牌子的 答&…...

STM32外设之LTDC/DMA2D—液晶显示(野火)
文章目录 显示屏有几种?基本参数控制?显存 LTDC 液晶控制器LTDC 结构框图LTDC 初始化结构体 LTDC_InitTypeDefLTDC 层级初始化结构体 DMA2D 图形加速器DMA2D 初始化结构体 要了解什么 屏幕是什么,有几种屏,有什么组成。 怎么控制,不同屏幕控…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

简易版抽奖活动的设计技术方案
1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...

《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互
引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据
微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列,以便知晓哪些列包含有价值的数据,…...