Redis基础数据结构及操作命令解析

Redis基础数据结构及操作命令解析


  Redis有五种基础数据结构,分别为string、list、hash、set、zset。

字符串类型(string)

  字符串类型是Redis中最基本的数据类型,它能存储任何形式的字符串,包括二进制数据、JSON化的对象甚至是一张图片。一个字符串类型键允许存储的数据的最大容量是512 MB,String数据结构是简单的key-value类型,value其实不仅是String,也可以是数字。

基础结构

  Redis的字符串是动态字符串,内部结构的实现类似于Java的ArrayList,采用预分配冗余空间的方式来减少内存的频繁分配。string在redis内部结构是一个带长度信息的字节数组,叫做“Simple Dynamic String”。

struct SDS<T>{T capacity; // 数组容量T len;  // 数组长度byte flags; // 特殊标志位,不用理睬它byte[] content; // 数组内容
}

  如上代码所示,capacity表示所分配数组的长度;len表示字符串的实际长度;content表示字符串的内容。
  上面SDS结构使用了泛型T,之所以使用泛型,是因为redis为了对内存做极致的优化,不同长度的字符串使用不同的结构体来表示,当字符串比较短的时候,len和capacity就使用byte和short来表示。
  字符串的扩容,字符串长度小于1MB之前,扩容空间采用加倍策略;字符串长度超过1MB之后,为了避免加倍扩容带来的冗余空间的浪费,就每次扩容1MB。

embstr VS raw

  字符串有两种存储方式,在长度特别短时,使用embstr形式存储,长度超过44字节时,使用raw形式存储。
  embstr是将RedisObject对象头结构和SDS对象连续存在一起,一次内存分配即可。
  raw是将RedisObject对象头结构和SDS对象分开存储,内存地址不连续。

struct RedisObject{int4 type;int4 encoding;int24 lru;int32 refcount;void *ptr;
}

  如上代码所示,RedisObject对象头占16字节的内存空间,是每种数据结构共有的结构,且ptr指针指向具体对象内容的内存地址,这里就是SDS的内存地址。

为什么长度超过44字节就会使用raw形式存储呢?

  内存分配器每次分配内存大小分别是2/4/8/16/32/64等字节,一个完整的embstr对象至少需要32个字节的空间(RedisObject对象头16字节+SDS头3字节),字符串总体超过64字节Redis会认为是一个大字符串,选择raw形式存储。
  RedisObject对象头16字节;SDS头3字节;字符串是以null结尾占1字节。总共20字节,所以留给存储数据的空间就只有44字节。

常用命令

  get、set、incr、decr、mget

1. SET(赋值)

  SET key value,对指定key赋值value。

SET user:1 zhangsan

2. GET(取值)

  GET key,取得指定key的value值。

GET user:1

3. INCR(递增数字)

  INCR key,将key指定为递增数字,每次调用都会自增1。INCR是保证原子性的,即多个线程同时操作不会发生线程不安全的情况。
  注:如果key不为整数时,会报错。

INCR num
redis> 1

4. INCRBY(增加指定的整数)

  INCRBY key value,INCRBY与INCR命令类型,只是INCRBY可以对某个key增加指定的整数,而INCR每次都固定增加1。

INCRBY num 3
redis> 4

5. DECR(递减数字)

  DECR key,每次调用都会自减1。

DECR num
redis> 3

6. DECRBY(减少指定的整数)

  DECRBY key value,每次调用对某个key减少指定的整数。

DECRBY num 2
redis> 1

7. INCRBYFLOAT(增加指定浮点数)

  INCRBYFLOAT key value,每次调用对某个key增加指定浮点数。

INCRBYFLOAT folat_num 5E+4
redis> 50006.30000000000000071

8. APPEND(尾部追加值)

  APPEND key value,每次调用对某个key增加指定浮点数。如果key不存在,则相当于SET key value,返回追加值的总长度。

APPEND user:1 feng
GET user:1
redis> "zhangsanfeng"

9. STRLEN(获取字符串的长度)

  STRLEN key,返回key对应value长度,如果不存在就返回0。

STRLEN user:1
redis> (integer) 12

10. MGET(取得多个键值)

  MGET …key,返回指定的多个key的value值。

MGET key1 key2 key3

11. MSET(设置多个键值)

  MSET key value [key value],对多个key设置value。

MSET key1 k1 key2 k2 key3 k3

列表类型(list)

  Redis的列表相当于Java中的LinkedList(双向链表),亦意味着插入和删除只需O(1),读取需要O(n)。可以巧妙运用列表提供的操作命令来完成队列和栈的数据结构操作。
  列表类型(list)可以用来存储一个有序的字符串列表,常用操作是向列表两端添加元素,或者取得某个片段。列表类型内部是使用双向链表实现的,即向列表两端添加元素的时间复杂度都为O(1),获取越接近两端的元素越快。

常用命令

1. LPUSH(列表左边添加元素)

  LPUSH key value […value],从列表左边添加指定元素,可以添加多个,返回添加元素后列表的长度。

LPUSH numbers 1
redis> 1

2. RPUSH(列表右边添加元素)

  RPUSH key value […value],从列表右边添加指定元素,可以添加多个,同样返回添加元素之后,当前列表的长度。

RPUSH numbers 2
redis> 2

3. LPOP(从列表左边弹出一个元素)

  LPOP key,从列表左边弹出一个元素,该操作分为两步,第一步将元素从列表中移除,第二部将元素返回。

LPOP numbers
redis> 1

4. RPOP(从列表右边弹出一个元素)

  RPOP key,从列表右边弹出一个元素,该操作分为两步,第一步将元素从列表中移除,第二部将元素返回。

RPOP numbers
redis> 2

5. LLEN(获取列表中元素个数)

  LLEN key,获取列表中元素个数,返回个数。

LLEN numbers
redis> 2

6. LRANGE(获取列表片段)

  LRANGE key start stop,获取列表片段,索引从0开始,LRANGE与POP命令不同,LRANGE只取出片段不会将其从列表中删除。

LRANGE numbers 0 3
redis>

7. LREM(删除列表中指定值)

  LREM key count value,删除列表中指定值。

  1. 当count > 0时LREM命令会从列表左边开始删除前count个值为value的元素。
  2. 当count < 0时LREM命令会从列表右边开始删除前count个值为value的元素。
  3. 当count = 0时LREM命令会删除所有值为value的元素。
LREM numbers 0 2

6. LINDEX(获取指定索引位置的元素)

  LINDEX key index,获取指定索引位置的元素,索引从0开始,获取索引为0位置的元素。

LINDEX numbers 0

7. LSET(设置指定索引位置的元素)

  LSET key index value,设置指定索引位置的元素,索引从0开始,设置索引为0位置的元素为7。

LSET numbers 0 7

8. LTRIM(删除指定范围外的所有元素)

  LTRIM key start end,删除指定范围外的所有元素,删除除0-3位置之外的所有元素。

LTRIM numbers 0 3

9. LINSERT(向列表中插入元素)

  LINSERT key AFTER|BEFORE pivot value,向列表中插入元素,在选择在指定元素前面插入还是后面插入。

LINSERT numbers AFTER 3 2

  在元素3后插入2。

LINSERT numbers BEFORE 3 2

  在元素3前插入2。

集合类型(set)

  Redis的集合相当于Java中的HashSet,内部的键值对是无序且唯一的。内部相当所有元素的value都为null的一个特殊的字典。set可用于需要去重的地方。
  集合类型和列表类型及其相似。但集合类型主要用于求得交集、并集和差集。

常用命令

1. SADD(添加元素)

  SADD key member […member],添加元素,可以添加多个,当所添加元素已经存在,不再添加。

SADD letters a b c d
2. SREM(删除元素)

  SREM key member […member],删除元素,可以删除多个,返回成功删除个数。

SREM letters d

3. SISMEMBER(判断元素是否在集合中)

  SISMEMBER key member,判断元素是否在集合中,有返回1,否则返回0。

SISMEMBER letters a

4. SDIFF(差集运算)

  SDIFF key […key],差集运算。

SADD A 1 2 3 4 5
SADD B 2 4 6 8 9
SDIFF A B
1) "1"
2) "3"
3) "5"

  SDIFF A B = A - B,返回即集合A排除掉A与B交集之后的元素。

5. SINTER(交集运算)

  SINTER key […key],交集运算,返回即集合A与B共有元素。

SADD A 1 2 3 4 5
SADD B 2 4 6 8 9
SINTER A B
1) "2"
2) "4"

6. SUNION(并集运算)

  SUNION key […key],交集运算,返回A + B,所有元素。

SADD A 1 2 3 4 5
SADD B 2 4 6 8 9
SUNION A B
1) "1"
2) "2"
3) "3"
4) "4"
5) "5"
6) "6"
7) "8"
8) "9"

7. SCARD(获得集合中元素个数)

  SCARD key,获得集合中元素个数。

SCARD A

8. SPOP(从集合中弹出一个元素)

  SPOP key,从集合中随机弹出一个元素,因为集合是无序的。

SPOP A

散列类型(hash)

  Redis的字典相当于Java语言里面的HashMap,它是无序字典,内部存储了很多键值对。其内部实现结构也和Java的HashMap一样,“数组+链表”形式,如遇hash冲突则用链表串起来。
  大字典的扩容比较耗时,首先需要重新申请新的数组,然后再将旧字典中的所有元素搬移到新数组中。这是一个O(n)级别的操作,单线程的Redis显然承担不起,所以Redis采用渐进式rehash的方式进行扩容。小步搬移,等待所有都搬移完毕之后再释放旧字典的内存。
  一般情况下,当hash元素个数等于数组长度时就会扩容两倍。但是如果当前redis正在bgsave(将数据保存到磁盘),为了减少内存页的过多分离,redis会选择尽量不去扩容,但是如果元素个数已经是数组长度的5倍,那么此时会强制扩容。
  如果hash表中元素个数低于数组长度的10%,redis就会进行缩容,且不考虑bgsave。

hash攻击

  如果hash函数存在偏向性,这种偏向性就会被利用来攻击服务器。因为偏向性强的hash函数会将过多的元素分配到同一个链表中,从而就会使查找从O(1)退化为O(n)。

常用命令

1. HSET(赋值)

  HSET key field value,对key中的field字段设置value。

HSET car price 500
HSET car name changan

  以上是分别对car下price字段和name进行赋值,price+name类似于一个对象或一个hashmap。

2. HGET(取值)

  HGET key field,取得指定key下指定的field字段。

HGET car price
redis> 500

3. HMSET(批量赋值)

  HMSET key field value [field value …],对指定key下字段批量赋值。

HMSET car price 600 name changan

  对car下price字段和name同时进行赋值。

4. HMGET(取值)

  HMGET key field [field …],取得指定key下指定的field字段对应值。

HMGET car price name
redis> "600"
redis> "changan"

5. HGETALL(取的所有值)

  HGETALL key,取得指定key下所有字段对应值,返回格式为field-value形式。

HGETALL car
redis> "price"
redis> "600"
redis> "name"
redis> "changan"

6. HEXISTS(判断字段是否存在)

  HEXISTS key field,判断指定key下的field字段是否存在,存在返回1,否则返回0。

HEXISTS car price
redis> 1

7. HSETNX(当字段不存在时赋值)

  HSETNX key field value,对某个key下field进行赋值,但如果该field存在则不做任何操作,不存在才赋值。

HSETNX car price 500
redis> 0
HSETNX car brand changan
redis> 1

8. HINCRBY(增加指定数字)

  HINCRBY key field increment,对指定key的field增加指定数字,类似于字符串类型的INCRBY。

HINCRBY car price 400
redis> 1000
HGET car price
redis> "1000"

9. HDEL(删除字段)

  HDEL key field [field …],删除key下field字段,这里可以为多个。

HDEL car brand
redis> 1

10. HKEYS(获取所有field字段)

  HKEYS key,获取当前key下所有field字段。

HKEYS car
redis> "price"
redis> "name"

11. HVALS(获取所有field字段对应值)

  HVALS key,获取当前key下所有field字段对应值。

HVALS car
redis> "1000"
redis> "changan"

12. HLEN(获取field字段数量)

  HLEN key,获取field字段数量。

HLEN car
redis> 2

有序集合类型(zset)

  Redis的有序列表首先保证内部value的唯一性,且还可以给每一个value设置一个score代表其排序的权重,zset内部是用跳跃列表来实现的。
  因为zset提供有score进行排序,所有在读取数据时可以指定某一区间的score进行读取数据,从而可以实现一个有序、不重复且可灵活读取的列表。
  有序集合类型和集合类型,一个是无序,一个有序的。有序集合类型与列表类型:

  1. 列表类型是通过链表实现,即两端元素获取速度快,更多用于“日志”或“新鲜事”的应用场景。
  2. 有序集合类型是通过散列表和跳跃表实现,即读取中间数据相比列表类型要快。
  3. 列表类型不能简答的调整某个元素的位置,但有序集合类型可以(通过更改元素的分数)。
  4. 有序集合类型比列表类型更耗费内存。

常用命令

1. ZADD(添加元素)

  ZADD key [NX|XX] [CH] [INCR] score member [score member …],添加元素,可以添加多个,这里的score可以是应用场景中任何用于排序的元素。

ZADD scoreboard 90 Tom 60 Ann 87 Jason

2. ZSCORE(获取分数)

  ZSCORE key member,获取指定key分数。

ZSCORE scoreboard Tom

3. ZRANGE(获取某个范围排名的元素:从小到大)

  ZRANGE key start stop [WITHSCORES],获取排名在某个范围的元素,WITHSCORES-加上之后会将分数一同返回。

ZRANGE scoreboard 0 2
1) "Ann"
2) "Jason"
3) "Tom"

4. ZREVRANGE(获取某个范围排名的元素:从大到小)

  ZREVRANGE key start stop [WITHSCORES],获取排名在某个范围的元素,WITHSCORES-加上之后会将分数一同返回。

ZREVRANGE scoreboard 0 2
1) "Tom"
2) "Jason"
3) "Ann"

5. ZRANGEBYSCORE(获取指定分数范围的元素)

  ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count],获取指定分数范围的元素,WITHSCORES-加上之后会将分数一同返回。

ZRANGEBYSCORE scoreboard 70 100
1) "Jason"
2) "Tom"

6. ZINCRBY(增加指定分数)

  ZINCRBY key score member,对指定key下的元素增加指定分数,如为-10——则表示为减少10分。

ZINCRBY scoreboard 20 Ann

7. ZCARD(获取元素个数)

  ZCARD key,获取集合中元素的个数并返回。

ZCARD scoreboard
(integer) 3

8. ZCOUNT(统计指定范围的元素个数)

  ZCARD key min max,统计指定范围的元素个数。

ZCOUNT scoreboard 60 100
(integer) 3

9. ZREM(删除元素)

  ZREM key member […member],删除元素。

ZREM scoreboard Tom

10. ZRANK(获取元素中排名:从小到大)

  ZREM key member,获取元素在有序集合中排名。

ZRANK scoreboard Tom
(integer) 2

11. ZREVRANK(获取元素中排名:从大到小)

  ZREVRANK key member,获取元素在有序集合中排名。

ZREVRANK scoreboard Tom
(integer) 0

一键三连,让我的信心像气球一样膨胀!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/780467.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【前端面试3+1】05v-if和v-show的区别、v-if和v-for能同时使用吗、Vuex是什么?【合并两个有序链表】

一、v-if和v-show的区别 v-if 和 v-show 是 Vue.js 中用来控制元素显示与隐藏的指令。 1.v-if&#xff1a; v-if 是根据表达式的真假值来决定是否渲染元素。当表达式为真时&#xff0c;元素会被渲染到 DOM 中&#xff1b;当表达式为假时&#xff0c;元素不会被渲染到 DOM 中。每…

关于未来自我的发展和一些学习方法(嵌入式方向)

我是一名大二的学生&#xff0c;考研还是就业&#xff0c;到底是重视专业课还是重视数学英语&#xff0c;这些问题一直困扰了我很久&#xff0c;但如今已经有了一些浅显的认识&#xff0c;所以才会想写这样一篇文章来记录一下自己的状态和未来的规划 下面的看法都是个人的看法&…

报错:torch.distributed.elastic.multiprocessing.errors.ChildFailedError:

错误&#xff1a; torch.distributed.elastic.multiprocessing.errors.ChildFailedError: 这个主要是torch的gpu版本和cuda不适配 我的nvcc -V是11.8 torch使用的&#xff1a; pip install torch2.0.1 torchvision0.15.2 torchaudio2.0.2 --index-url https://download.pyt…

最长有效括号(C语言)

题目链接&#xff1a;. - 力扣&#xff08;LeetCode&#xff09; 这道题&#xff0c;我看了一种解法&#xff0c;觉得很好&#xff0c;来分享一下 这道题主要是 思考 当前 ) 与之匹配 ( 在哪里 &#xff0c;记录下来&#xff0c;最后比较最大值 例子&#xff1a; 第…

听了中国电信关闭Wi-Fi双频合一功能之后,到底该连接2.4GHz还是5GHz频段?

前言 前段时间沸沸扬扬的关闭双频合一建议&#xff0c;小白也尝试关闭了一下&#xff0c;网络确实是好了不少。 有小伙伴还是有点疑虑&#xff0c;中国电信说的关闭Wi-Fi双频合一功能真的有用吗&#xff1f;点击下方蓝字一探究竟&#xff01; 中国电信建议关闭路由器的双频合一…

万字详解PHP+Sphinx中文亿级数据全文检索实战(实测亿级数据0.1秒搜索耗时)

Sphinx查询性能非常厉害&#xff0c;亿级数据下输入关键字&#xff0c;大部分能在0.01~0.1秒&#xff0c;少部分再5秒之内查出数据。 Sphinx 官方文档&#xff1a;http://sphinxsearch.com/docs/sphinx3.html极简概括&#xff1a; 由C编写的高性能全文搜索引擎的开源组件&…

Python-基础部署

机器没法直接读懂我们写的代码&#xff0c;需要解释解释器作为中间的翻译&#xff0c;把代码转换成字节码在执行 安装python解释器 Download Python | Python.org 安装代码编辑器 pycharm Thank you for downloading PyCharm! 创建一个项目&#xff0c;每个项目里的文件夹…

Cisco ISR 1000 Series IOS XE Release IOSXE-17.13.1a ED

Cisco ISR 1000 Series IOS XE Release IOSXE-17.13.1a ED 思科 1000 系列集成多业务路由器系统软件 请访问原文链接&#xff1a;https://sysin.org/blog/cisco-isr-1000/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org 思科…

如何解决EventSource 删除单词的前置空格问题

如下代码,EventSource会把单词的前置空格吃掉&#xff0c;比如“ blank” 会变成"blank",这会导致输出的英语单词连在一起 const eventSource new EventSource(api_question); eventSource.onmessage streamEvent > {const data streamEvent.data;handleTest(…

ubuntu18.04 pycharm

一、下载pycharm &#xff08;1&#xff09;进入官网下载Download PyCharm: The Python IDE for data science and web development by JetBrains 选择专业版&#xff08;professional&#xff09;直接点击下载&#xff08;download&#xff09;&#xff0c;我下载的是2023.3…

数字孪生|初识山海鲸可视化

哈喽&#xff0c;你好啊&#xff0c;我是雷工&#xff01; 最近开始学习了解数字孪生的软件&#xff0c;看山海鲸可视化介绍的不错&#xff0c;便准备下载了试一下。 01 、概述 该软件是一套技术自主可控的、国产自研的、零代码数字孪生可视化工具集&#xff0c; 02、产品定…

从0到1利用express搭建后端服务

目录 1 架构的选择2 环境搭建3 安装express4 创建启动文件5 express的核心功能6 加入日志记录功能7 日志记录的好处本节代码总结 不知不觉学习低代码已经进入第四个年头了&#xff0c;既然低代码很好&#xff0c;为什么突然又自己架构起后端了呢&#xff1f;我有一句话叫低代码…

EasyRecovery2024中文版数据恢复软件功能全面介绍

EasyRecovery2024是世界著名数据恢复公司 Ontrack 的技术杰作&#xff0c;它是一个威力非常强大的硬盘数据恢复工具。能够帮你恢复丢失的数据以及重建文件系统。 EasyRecovery不会向你的原始驱动器写入任何东东&#xff0c;它主要是在内存中重建文件分区表使数据能够安全地传输…

C语言如何进⾏函数的⼀般调⽤?

一、问题 函数调⽤的⼀般样式都是⼀样的&#xff0c;简称为函数的⼀般调⽤&#xff0c;那么函数的⼀般调⽤的形式是什么呢&#xff1f; 二、解答 在C语⾔中&#xff0c;函数调⽤的⼀般形式如下。 函数名(实际参数表) 对⽆参函数调⽤时&#xff0c;则⽆实际参数表。实际参数表…

nodejs下载安装以及npm、yarn安装及配置教程

1、nodejs下载安装 ​ 1.1、使用nodejs版本管理工具下载安装&#xff0c;可一键安装、切换不同nodejs版本&#xff0c; nvm-setup.zip&#xff1a;安装版&#xff0c;推荐使用 本次演示的是安装版。 1、双击安装文件 nvm-setup.exe 选择nvm安装路径 例如&#xff1a;E:\Soft…

ssm 科研奖励申报管理系统开发mysql数据库web结构java编程计算机网页源码eclipse项目

一、源码特点 ssm 科研奖励申报管理系统是一套完善的信息系统&#xff0c;结合springMVC框架完成本系统&#xff0c;对理解JSP java编程开发语言有帮助系统采用SSM框架&#xff08;MVC模式开发&#xff09;&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用…

[CSS]使用flex实现二联三联布局

1. 使用flex实现二联布局 思路&#xff1a;左侧为固定width&#xff0c;右侧为所有 <style type"text/css">.wrap {display: flex;justify-content: space-between;} ​.left,.right,{height: 100px;} ​.left {width: 200px;background: coral;} ​.right {…

iOS - Runloop介绍

文章目录 iOS - Runloop介绍1. 简介1.1 顾名思义1.2. 应用范畴1.3. 如果没有runloop1.4. 如果有了runloop 2. Runloop对象3. Runloop与线程4. 获取Runloop对象4.1 Foundation4.2 Core Foundation4.3 示例 5. Runloop相关的类5.1 Core Foundation中关于RunLoop的5个类5.2 CFRunL…

java复原IP 地址(力扣Leetcode93)

复原IP 地址 力扣原题链接 问题描述 有效 IP 地址正好由四个整数&#xff08;每个整数位于 0 到 255 之间组成&#xff0c;且不能含有前导 0&#xff09;&#xff0c;整数之间用 ‘.’ 分隔。 例如&#xff1a;“0.1.2.201” 和 “192.168.1.1” 是有效 IP 地址&#xff0c…

【CASS精品教程】CASS11台阶画法大全

文章目录 一、无边台阶二、有边台阶三、圆弧无边台阶四、U型台阶五、曲线U型台阶六、L型台阶一、无边台阶 点击【居民地】→【房屋附属】→【台阶】: 选择【两点边】即可。 两点边的绘制方法是,依次点击四个点,或者点击三个点后空格,注意台阶缺口(有白色线条)为下。 四…