Redis string类型hash类型
string类型
类型介绍
在Redis中的所有的key都是string类型,而value的类型有多种。
Redis中的字符串是直接按照二进制的方式进行存储的,也就是不会做任何的编码转换,存的是什么,取出来的就是什么。这样一般来说,Redis遇见乱码的可能性会变小。因为这里会出现乱码就只跟存入端和读取端有关,而像mysql这样自己会做编码转换的,那么出现的乱码的原因还可能跟mysql自身的编码转换有关。
另外因为Redis存储字符串是按二进制存储的,所以不仅仅只可以存文本数据,
甚至还可以存图片,音频。
set/get
再看一下set的语法:
SET key value [expiration EX seconds|PX milliseconds] [NX|XX]
对于后面的选项语法格式:
[expiration EX seconds|PX milliseconds] 也就是在设置key的时候,同时设置超时时间,EX就是以秒级单位的,PX就是毫秒。
[NX|XX] NX:表示 如果key存在,那么就不设置 ,返回nil;如果不存在,那么才设置。
XX:表示 key存在,才设置(相当于更新key);如果key不存在,那么就不设置。
这样的额外选项可以减少网络轮次,在客户端-服务器这样的程序下还是很有用的。 并且对于一条命令来说,它的执行效果是原子的,而分开的话就不好说了。
用命令
flushall
可以进行删库操作,将所有的数据全部删除。这个操作非常危险,几乎不会用到。
mset/mget
mset:⼀次性设置多个 key 的值。
MSET key value [key value ...]
mget:⼀次性获取多个 key 的值。如果对应的 key 不存在或者对应的数据类型不是 string,返回 nil。
MGET key [key ...]
这里的时间复杂度官方给的是:O(N),不过这里的N跟我们之前说的一样,指的是key的数目。
这两个命令同样是为了减少请求的网络轮次的。
setnx/setex/psetex
这三个命令其实就是对set的一些常见用法进行了缩写。
incr/incrby/decr/decrby/incrbyfloat
incr只能针对一个整数使用,返回这个数加一后的值。相当于 ++i,其他的命令同理。
incrby可以针对value进行 + n的操作。并且这里的n可以是负数,如果是负数就相当于减法操作。
另外在Redis中的int是64位的。
为什么Redis明明可以使用一套命令就可以实现加减法,为什么要设计两套呢?这一点跟刚刚的setnx那些命令是一样的,是为了让Redis的使用更加符合人的直觉,从而降低用户的使用门槛。
另外,如果我们 incr/incrby的key不存在时,它会帮我们插入一个value为0的值,然后进行对应的加减操作。
剩下三个命令的使用原理跟incr和incrby差不多。这些命令的时间复杂度都是O(1)。
另外这个 incrbyfloat 中的float其实是按double的标准来的。
append
APPEND KEY VALUE
注意:append这里的返回值 的单位是字节。
如果我们想让Redis客户端能够自动的把二进制数据尝试翻译,那么在启动客户端的时候要加上一个 --raw的选项
可以看到,当我们启动时没有带 --raw时,我们查出来的汉字是十六进制显示的,其中每个十六进制前的 \x 是转义字符,表示这是一个十六进制。
getrange
GETRANGE key start end
在C++和Java中,谈到一个区间大多都是左闭右开的 [x,y) 。而Redis这里都是闭区间 [x,y]
注意:当我们存的值是汉字时,因为一个汉字占3个字节,所以使用这个切分的时候还需要考虑到这一点,不然切出来的可能是乱码
setrange
覆盖字符串的⼀部分,从指定的偏移开始。 如果从指定偏移位置覆盖的字符串超出了原本能覆盖的大小,那么多余的字符串会以追加的形式覆盖。
SETRANGE key offset value
注意:当value是一个中文字符串的时候,进行setrange是有可能出问题的。
另外,setrange对于不存在的key也是可以操作的, 不过会把 offset(偏移位置)之前的内容填充成:0x00。
strlen
获取 key 对应的 string 的⻓度。当 key 存放的类似不是 string 时,报错。
STRLEN key
string编码方式
不过不建议记住这样的数字,记住数字是没有意义的。
根据业务场景的不同,最佳的长度不一定是39字节,此时就需要自行修改这个数字的大小
关于修改:
另外,我们发现Redis存储整形会用int类型(8字节大小),但是存储小数其实是用embstr的,也就是说存储小数本质还是当作字符串来存储的。
这样的差别其实是很大的,因为对于整形 进行算术运算的时候是比较方便的,但是如果是字符串存储,那么进行算术运算的时候,要先将字符串转化为小数,然后再进行算术运算,最后还要再转回字符串,开销就大多了。
string的应用场景
作为缓存
作为缓存的思路:应用服务器访问数据时,先查询Redis,如果Redis上有这个数据,那么就直接返回给应用服务器,如果没有,那么就去MySQL中去查找,在MySQL中找到后再返回给应用服务器,同时会把这个数据写入到Redis中,这个写入到Redis中的值,作为key往往被设置了过期时间
Redis这样的缓存经常存储热点数据,也就是高频被访问的数据。这样能够加速查询和缓解MySQL服务器的压力。
伪代码模拟业务数据访问过程:
1.根据用户uid获取用户信息:
UserInfo getUserInfo(long uid) {...
}
2.⾸先从 Redis 获取⽤⼾信息,我们假设⽤⼾信息保存在 "user:info:<uid>" 对应的键中:
// 根据 uid 得到 Redis 的键
String key = "user:info:" + uid;
// 尝试从 Redis 中获取对应的值String value = Redis 执⾏命令:get key;
// 如果缓存命中(hit)
if (value != null) {// 假设我们的⽤⼾信息按照 JSON 格式存储UserInfo userInfo = JSON 反序列化(value);return userInfo;
}
3.
// 如果缓存未命中(miss)
if (value == null) {// 从数据库中,根据 uid 获取⽤⼾信息UserInfo userInfo = MySQL 执⾏ SQL:select * from user_info where uid =
<uid>// 如果表中没有 uid 对应的⽤⼾信息if (userInfo == null) {响应 404return null;}// 将⽤⼾信息序列化成 JSON 格式String value = JSON 序列化(userInfo);// 写⼊缓存,为了防⽌数据腐烂(rot),设置过期时间为 1 ⼩时(3600 秒)Redis 执⾏命令:set key value ex 3600// 返回⽤⼾信息return userInfo;
}
注意:
使⽤,可以省略业务名 "vs:"。如果键名过程,则可以使⽤团队内部都认同的缩写替代,例如
计数功能
Redis将播放量同步到其他数据源的方式是异步的。
不过Redis用作计数功能是挺不错的,但是让Redis统计数据就不行了,比如让Redis统计播放量前百的视频就很麻烦,如果让MySQL来的话一行sql就搞定了 (排序加limit 100)
共享会话
手机验证码
String 发送验证码(phoneNumber) {key = "shortMsg:limit:" + phoneNumber;// 设置过期时间为 1 分钟(60 秒)// 使⽤ NX,只在不存在 key 时才能设置成功bool r = Redis 执⾏命令:set key 1 ex 60 nxif (r == false) {// 说明之前设置过该⼿机的验证码了long c = Redis 执⾏命令:incr keyif (c > 5) {// 说明超过了⼀分钟 5 次的限制了// 限制发送return null;}}// 说明要么之前没有设置过⼿机的验证码;要么次数没有超过 5 次String validationCode = ⽣成随机的 6 位数的验证码();validationKey = "validation:" + phoneNumber;// 验证码 5 分钟(300 秒)内有效Redis 执⾏命令:set validationKey validationCode ex 300;// 返回验证码,随后通过⼿机短信发送给⽤⼾return validationCode ;
}// 验证⽤⼾输⼊的验证码是否正确bool 验证验证码(phoneNumber, validationCode) {validationKey = "validation:" + phoneNumber;String value = Redis 执⾏命令:get validationKey;if (value == null) {// 说明没有这个⼿机的验证码记录,验证失败return false;}if (value == validationCode) {return true;} else {return false;}
}

hash类型
类型介绍
基础命令 1:hset/hget/hexists/hdel
hset
设置 hash 中指定的字段(field)的值(value)。
HSET key field value [field value ...]
hget
获取 hash 中指定字段的值。
HGET key field
hexists
判断 hash 中是否有指定的字段。
HEXISTS key field
hdel
删除 hash 中指定的字段。
HDEL key field [field ...]
如果要删除所有字段,那么就是
del key
基础命令2:hkeys / hvals / hgetall
hkeys
获取 hash 中的所有字段。
HKEYS key
HVALS key
hgetall
获取 hash 中的所有字段以及对应的值。
HGETALL key
可以看到,查询出来的结果 是一对 field和value 的形式规律显示的。
上述的操作都是风险比较大的,数据量多大时就可能会导致Redis阻塞。
基础命令3:hmget / hlen / hsetnx / hincrby
hmget
⼀次获取 hash 中多个字段的值
HMGET key field [field ...]
对于hmget命令,同样也还有一个hmset命令,可以同时设置多个 filed value,但是没必要,因为hset本身就已经有这个功能了。
hlen
HLEN key
hsetnx
在字段不存在的情况下,设置 hash 中的字段和值。
HSETNX key field value
hincrby
将 hash 中字段对应的数值添加指定的值。
HINCRBY key field increment
hincrbyfloat
HINCRBYFLOAT key field increment
使用示例:
hash的编码方式
压缩的本质就是对数据进行重新编码,不同的数据有不同的特点,结合这些特点,进行精妙的设计,重新编码之后,就可以缩小体积。
示例:
哈希类型的应用场景
作为缓存
之前说过,string类型也可以作为缓存,哈希类型也可以作为缓存。
当存储结构化的数据时,使用hash作为缓存就更合适一些。
比如:
如果用string来存储这样的具有表结构的数据的话,那么就得把数据转化为json的格式。
但是如果我们只想要操作某一对filed value,那么就需要将整个key (json)读取出来,然后解析成对象,然后对其进行修改,修改完之后,又需要将字符串重新转为json,再写回去。
但是如果此时是用hash存储的数据,那么就可以很方便的取出和修改数据了。
总结:使用hash的方式确实可以高效的对filed进行读写,但是hash也付出了更大的空间上的代价
其实还有一种缓存方式,那就是用原生字符串类型。每一个属性用一个键(key)
但是这种方式是不推荐的,因为它把同一个数据的各个属性给分散开了,也就是低内聚。这里不要把内聚和耦合混淆了。
一般写代码追求的是:高内聚,低耦合。
还有一个问题就是:
缓存方式对比
string类型缓存
序列化字符串类型,例如JSON格式
哈希类型缓存
原生字符串类型
使⽤字符串类型,每个属性⼀个键。
相关文章:

Redis string类型hash类型
string类型 类型介绍 在Redis中的所有的key都是string类型,而value的类型有多种。 Redis中的字符串是直接按照二进制的方式进行存储的,也就是不会做任何的编码转换,存的是什么,取出来的就是什么。这样一般来说,Redi…...

Solidity智能合约中的异常处理(error、require 和 assert)
Solidity 中的三种抛出异常方法:error、require 和 assert 在 Solidity 开发中,异常处理是确保智能合约安全性和正确性的关键步骤。Solidity 提供了三种主要方法来抛出异常:error、require 和 assert。本文将详细介绍这三种方法的用途、实现方…...

True NAS禁用ipv6
在 TrueNAS Scale 中,禁用 IPv6 的方法如下:12 进入 System->Advanced->Sysctl,设置一个 sysctl 可调整变量 net.ipv6.conf.all.disable_ipv6,值为 1,以完全禁用 IPv6。\...

笔记整理—linux进程部分(2)使用fork创建进程
为什么要创建进程,首先每个程序的运行都需要一个进程;多进程实现宏观上的并行。 fork的原理,是进程的分裂生长模式。如果操作系统需要一个新的进程,那么就会以cp的方法得到一个新的进程,此时老的进程是父进程ÿ…...
在Python中实现多目标优化问题(6)
在Python中实现多目标优化问题 在Python中实现多目标优化,除了传统的进化算法(如NSGA-II、MOEA/D)和一些基于机器学习的方法外,还有一些新的方法和技术。这些新方法通常结合了最新的研究成果,提供了更高效的解决方案。…...

Java EE中的编码问题及解决方案
Java EE中的编码问题及解决方案 在Java EE开发中,处理字符编码是确保数据正确传输和显示的重要环节。不同的编码不一致会导致乱码,影响用户体验。本文将总结在Java EE中可能遇到的编码问题及其解决方案。 1. 输入数据编码问题 在表单提交时,…...
9月27日,每日信息差
第一、中国科学家团队在干细胞治疗领域取得重要突破,通过化学重编程技术成功制备出胰岛细胞,并用于移植治疗一名 1 型糖尿病患者,实现了临床功能性治愈。相关研究成果已发表在国际权威期刊《细胞》上。 第二、交通运输部公路局局长周荣峰在国…...
什么是 Angular 开发中的 Dumb components
Dumb components,在 Angular 开发中也被称为 Presentational components,它们的主要职责是通过展示数据和触发事件,把业务逻辑和 UI 表现分离开来。Dumb components 只通过 Input() 接收数据,Output() 向外发送事件,不…...
Docker 进入容器运行命令的详细指南
Docker 进入容器运行命令的详细指南 Docker 是一个开源的容器化平台,广泛应用于开发和生产环境中。它允许开发者打包应用程序及其依赖项到容器中,并能够在不同的平台上快速部署和运行。容器通常是独立且隔离的,但在开发、调试或维护过程中&a…...
如何禁止非真实用户的ip访问网站服务器
为了禁止非真实用户的IP访问网站服务器,可以采用多种技术手段和策略。以下是一些常用的方法: 1. 使用IP黑名单和白名单 黑名单:定期更新和维护一个IP黑名单,阻止已知的恶意IP地址或数据中心IP访问网站。白名单:对于特…...

探索SpringBoot:学科竞赛管理项目开发
2 相关技术简介 2.1Java技术 Java是一种非常常用的编程语言,在全球编程语言排行版上总是前三。在方兴未艾的计算机技术发展历程中,Java的身影无处不在,并且拥有旺盛的生命力。Java的跨平台能力十分强大,只需一次编译,任…...

ultralytics yolo v8 示例:加载官方模型进行推理
Ultralytics YOLO 是计算机视觉和 ML 领域专业人士的高效工具。 安装 ultralytics 库: pip install ultralytics 实现代码如下: import cv2 from ultralytics import YOLO# 加载预训练的 YOLOv8n 模型 ckpt_dir "./ckpt/" # 模型缓存地址…...

【中间件学习】Nginx快速入门(为了配置一个项目)
-----------------------------本文章借鉴遇见狂神说--------------------------- 一、一个产品出现瓶颈?? 在一个产品刚刚上线的时候,并发量小,用户使用的少,所以在低并发的情况下,一个jar包启动应该就够…...

鸿蒙harmonyos next flutter通信之MethodChannel获取设备信息
本文将通过MethodChannel获取设备信息,以此来演练MethodChannel用法。 建立channel flutter代码: MethodChannel methodChannel MethodChannel("com.xmg.test"); ohos代码: private channel: MethodChannel | null nullthis.c…...

【笔记】原子结构的近代理论
近代原子结构理论的建立是从氢原子光谱得到启示的。 一、氢原子光谱与波尔理论 1.氢原子光谱 在装有两个电极的真空玻璃管内通入极少量高纯氢气,通高压电使之放电,管中发出的光束通过分光棱镜,得到分立的谱线,称为线状光谱。 发…...
【python】循环中断:break 和 continue
目录: while 循环的基础语法while 循环的基础案例while 循环的嵌套应用while 循环的嵌套案例for 循环的基础语法for 循环的嵌套应用循环中断:break 和 continue综合案例 学习目标: 掌握使用 continue 和 break 关键字控制循环 思考&#…...

WIFI密码默认显示
文章目录 需求分析遇到问题问题原因解决方案 需求 在进入设置,点击某一个wifi,连接wifi 界面,显示密码默认选中状态,效果如下 分析 在 WiFi密码被输入法挡住 中我们已经分析了整个流程,布局文件和控制中心。 结局系统设置WIFI连…...

Emiya 家今天的饭C++
题目: 样例解释: 【样例 1 解释】 由于在这个样例中,对于每组 i,j,Emiya 都最多只会做一道菜,因此我们直接通过给出烹饪方法、主要食材的编号来描述一道菜。 符合要求的方案包括: 做一道用烹饪方法 1、主要…...

Mybatis缓存机制(图文并茂!)
目录 一级缓存 需求我们在一个测试中通过ID两次查询Monster表中的信息。 二级缓存 案例分许(和上述一样的需求) EhCache第三方缓存 在了解缓存机制之前,我们要先了解什么是缓存: 缓存是一种高速存储器,用于暂时存储访问频繁的数据&…...
Git 工作区、暂存区和版本库
Git 工作区、暂存区和版本库 Git 是一个强大的版本控制系统,它帮助开发者管理代码历史,协作开发,以及跟踪和合并更改。为了更好地理解 Git 的工作流程,我们需要了解 Git 中的三个核心概念:工作区(Workspac…...

python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...
基于matlab策略迭代和值迭代法的动态规划
经典的基于策略迭代和值迭代法的动态规划matlab代码,实现机器人的最优运输 Dynamic-Programming-master/Environment.pdf , 104724 Dynamic-Programming-master/README.md , 506 Dynamic-Programming-master/generalizedPolicyIteration.m , 1970 Dynamic-Programm…...

从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践
作者:吴岐诗,杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言:融合数据湖与数仓的创新之路 在数字金融时代,数据已成为金融机构的核心竞争力。杭银消费金…...

Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统
💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「storms…...
Python 训练营打卡 Day 47
注意力热力图可视化 在day 46代码的基础上,对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...
raid存储技术
1. 存储技术概念 数据存储架构是对数据存储方式、存储设备及相关组件的组织和规划,涵盖存储系统的布局、数据存储策略等,它明确数据如何存储、管理与访问,为数据的安全、高效使用提供支撑。 由计算机中一组存储设备、控制部件和管理信息调度的…...