Redis -【常用五大数据类型】

官网链接:http://www.redis.io
视频:Redis 6 尚硅谷
笔记全部来自于b站尚硅谷的Redis课程,可以配合是视频来享用~~

三、常用五大数据类型

哪里去获得redis常见数据类型操作命令http://www.redis.cn/commands.html

1 - Redis键(key)

key:

命令:
  (1)keys * : 查看当前库所有key    (匹配:keys *1)
  (2)exists key: 判断某个key是否存在
  (3)type key : 查看你的key是什么类型
  (4)del key  : 删除指定的key数据
  (5)unlink key : 根据value选择非阻塞删除(仅将keys从keyspace元数据中删除,真正的删除会在后续异步操作)
  (6)expire key 10 : 10秒钟,为给定的key设置过期时间
  (7)ttl key : 查看还有多少秒过期,-1表示永不过期,-2表示已过期
  (8)select  : 命令切换数据库
  (9)dbsize  : 查看当前数据库的key的数量
  (10)flushdb : 清空当前库
  (11)flushall: 通杀全部库

2 - Redis字符串(String)

3.2.1. 简介

String是Redis最基本的类型,你可以理解成与Memcached一模一样的类型,一个key对应一个value。
String类型是二进制安全的。意味着Redis的string可以包含任何数据。比如jpg图片或者序列化的对象。
String类型是Redis最基本的数据类型,一个Redis中字符串value最多可以是512M

3.2.2. 常用命令

String: k- key(键) v-value(值)

命令:
  (1)存:set k v  [另说明见下!]
  (2)取:get k         
  (3)追加字符:append k "追加字段" 
  (4)长度:strlen k
  (5)无该key时存:setnx k v:(只有在 key 不存在时设置 key 的值)
  (6)增指定值:incrby k [integer]
  (7)减指定值:decrby k [integer]
  (8)递增:incr k (一定是整数;如无值则赋0后加1)
  (9)递键:decr k (一定是整数;如无值则赋0后减1)
  
其他命令:
  (1)批量存:mset k1 v1 k2 v2...
  (2)批量取:mget k1 k2 k3 ....         
  (3)批量存:msetnx k1 v1 k2 v2...(当且仅当所有给定 key 都不存在,原子性,有一个失败则都失败)
  (4)范围取:getrange k 起始位置 结束位置(类似java中的substring,前包,后包)
  (5)取全部数据:getrange k 0 -1
  (6)覆盖值:setrange k 起始位置 v (<value>覆写<key>所储存的字符串值,从<起始位置>开始(索引从0开始))
  (7)过期时间:setex k 过期时间 value (设置键值的同时,设置过期时间,单位秒)
  (8)以新换旧:getset k v (设置了新值同时获得旧值)

存set的说明:

image-20220727111440940

  • NX:当数据库中key不存在时,可以将key-value添加数据库
  • XX:当数据库中key存在时,可以将key-value添加数据库,与NX参数互斥
  • EX:key的超时秒数
  • PX:key的超时毫秒数,与EX互斥

image-20220727113031192

image-20220727113111389

上面的值可能是2~200,因为i++不是原子操作,它分三步完成:获取i的值,进行+操作,赋值

3.2.3. 数据结构

String的数据结构为简单动态字符串(Simple Dynamic String,缩写SDS)。是可以修改的字符串,内部结构实现上类似于Java的ArrayList,采用预分配冗余空间的方式来减少内存的频繁分配

image-20220727123548075

如图中所示,内部为当前字符串实际分配的空间capacity一般要高于实际字符串长度len。当字符串长度小于1M时,扩容都是加倍现有的空间,如果超过1M,扩容时一次只会多扩1M的空间。需要注意的是字符串最大长度为512M。

3 - Redis列表(List)

3.3.1. 简介

单键多值
Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。

它的底层实际是个双向链表,对两端的操作性能很高,通过索引下标的操作中间的节点性能会较差。

image-20220727123852045

3.3.2. 常用命令

list:

概述:
元素插入
链表表头或结尾插入:高效,中间:低

存储list:
1.ArrayList使用数组方式:使用索引查询-块,新增删除时涉及位移操作-慢
2.LinkedList使用双向链接方式:每个元素记录前后元素指针
3.双向链表增加数据
4.双向链表删除数据

存储list常用命令:
`1.两端添加:lpush、rpush`
lpush list 1 2 3 #从左侧往list表中插入1 2 3
rpush list a b c #从右侧往list表中插入a b c 
`2.查看列表:lrange`
lrange list 0 -1 #从头到尾查看
lrange list 0 5  #从开始到第5个查看
`3.两端弹出:lpop、rpop (值在键在,值光键亡)`
lpop list #从左边弹出第一个数
rpop list #从尾部弹出第一个数
`4.获取列表元素个数:llen`
llen list #查看元素个数
`5.扩展命令:lpushx、rpushx、lrem、lset、rpoplppush`
lpushx list x #插入x到list表的开头(左边)
rpushx list y #插入y到list表的尾部(右边)
lrem list n value #从头到尾删除n个value
lrem list 2 3 #从头到尾删除2个3(从左到右)
lrem list -2 1  #从尾到头删除2个1(从右到左)
lrem list 0 2	#删除所有2
lset key n value 	#在key表第n个角标设置为value
lset list 3 mmm 	#在list表第3个角标设置mmm
linset list before a yy	 #在list表中a之前插入yy
linset list after b xx 	#在list表中b之后插入xx
rpoplpush list1 list2 	#从list1表的右边吐出压入到list2表的左边

3.3.3. 数据结构

List的数据结构为快速链表quickList

首先在列表元素较少的情况下会使用一块连续的内存存储,这个结构是ziplist,也即是压缩列表

它将所有的元素紧挨着一起存储,分配的是一块连续的内存。

当数据量比较多的时候才会改成quicklist

因为普通的链表需要的附加指针空间太大,会比较浪费空间。比如这个列表里存的只是int类型的数据,结构上还需要两个额外的指针prev和next。

image-20220727135259344

Redis将链表和ziplist结合起来组成了quicklist。也就是将多个ziplist使用双向指针串起来使用。这样既满足了快速的插入删除性能,又不会出现太大的空间冗余。

4 - Redis集合(Set)

3.4.1. 简介

Redis set对外提供的功能与list类似是一个列表的功能,特殊之处在于set是可以自动排重的,当你需要存储一个列表数据,又不希望出现重复数据时,set是一个很好的选择,并且set提供了判断某个成员是否在一个set集合内的重要接口,这个也是list所不能提供的。

Redis的Set是string类型的无序集合它底层其实是一个value为null的hash表,所以添加,删除,查找的复杂度都是O(1)

一个算法,随着数据的增加,执行时间的长短,如果是O(1),数据增加,查找数据的时间不变

3.4.2. 常用命令

Set:

Redis数据结构(Set): List允许出现重复数据,Set不允许出现重复数据;Set最大元素数量是4294967295
命令:
  (1)存:sadd 列名 [...]
  (2)删:srem 列名 [...]
  (3)查全:smembers 列名
  (4)查是否存在:sismember 列名 值,1表示存在,0表示不存在
  (5)差集:sdiff 列名1 列名2 ((列1中的,不包含在列2中的))
  (6)交集:sinter 列名1 列名2
  (7)并集:sunion 列名1 列名2
  (8)查数量:scard 列名
  (9)随机查<n>个值:srandmember 列名 <n>(不会从集合中删除)
  (10)随机吐出一个值:spop 列名
  (11)从集合A的值移动到集合B:smove 列名1 列名2 值 
  (12)将差集存到新集合中:sdiffstore 新列名 列名1 列名2
  (13)将交集存到新集合中:sinterstore 新列名 列名1 列名2
  (14)将并集存到新集合中:sunionstore 新列名 列名1 列名2

3.4.3. 数据结构

Set数据结构是dict字典,字典是用哈希表实现的。

Java中HashSet的内部实现使用的是HashMap,只不过所有的value都指向同一个对象。Redis的set结构也是一样,它的内部也使用hash结构,所有的value都指向同一个内部值。

5 - Redis哈希(Hash)

3.5.1. 简介

Redis hash 是一个键值对集合。

Redis hash是一个string类型的fieldvalue的映射表,hash特别适合用于存储对象
类似Java里面的Map<String,Object>

用户ID为查找的key,存储的value用户对象包含姓名,年龄,生日等信息,如果用普通的key/value结构来存储

主要有以下2种存储方式:

image-20220727140611227

3.5.2. 常用命令

Hash:

常用存储类型(Hash):每个可存4294967295个键值对
命令: 表名(key)(field)(value)
  (1)存:hset 表名 域 值 
  (2)批量存:hmset 表名 域 值 域 值...
  (2)取:hget 表名 域
  (4)批量取:hmget 表名 域 域 ...
  (5)取全:hgetall 表名
  (6)删除:hdel 表名 域...
  (7)全删:del 表名
  (8)增指定值:hincrby 表名 域 [integer](一定是整数)
  (9)判断存在:hexists 表名 域 (查看哈希表 key 中,给定域 field 是否存在)
  (10)设置域值:hsetnx 表名 f v (将hash表中域f的值设置为v,当且仅当field不存在时)
  (11)键值对数量:hlen 表名
  (12)取所有域():hkeys 表名(列出所有的field)
  (13)取所有值:hvals 表名(列出所有的value)

3.5.3. 数据结构

Hash类型对应的数据结构是两种:ziplist(压缩列表),hashtable(哈希表)。当field-value长度较短且个数较少时,使用ziplist,否则使用hashtable。

6 - Redis有序集合Zset(sorted set)

3.6.1. 简介

Redis有序集合zset与普通集合set非常相似,是一个没有重复元素的字符串集合。

不同之处是有序集合的每个成员都关联了一个评分(score),这个评分(score)被用来按照从最低分到最高分的方式排序集合中的成员。集合的成员是唯一的,但是评分可以是重复了 。

因为元素是有序的, 所以你也可以很快的根据评分(score)或者次序(position)来获取一个范围的元素。

访问有序集合的中间元素也是非常快的,因此你能够使用有序集合作为一个没有重复成员的智能列表。

3.6.2. 常用命令

Zset:

命令: 集合名(key) 评分(score)(value)
  (1)``:zadd 集合名 评分1 值1 评分2 值2...
  (2)`按下标取`:zrange 集合名 下标1 下标2 [WITHSCORES] 
  (返回有序集 key 中,下标在<下标1> <下标2>之间的元素,带WITHSCORES,可以让分数一起和值返回到结果集)
  (3)`按评分取`:zrangebyscore 集合名 min max [withscores] [limit offset count]
  (返回有序集 key 中,所有 score 值介于 min 和 max 之间(包括等于 min 或 max )的成员。有序集成员按 score 值递增(从小到大)次序排列)
  (4)`从大到小取`:zrevrangebyscore 集合名 max min [withscores] [limit offset count]   (同上,改为从大到小排列。)
  (5)`增指定值`:zincrby 集合名 增量 值(给值加上增量)
  (6)`删除`:zrem 集合名 值 
  (7)`统计`:zcount 集合名 min max (统计该集合,分数区间内的元素个数)
  (8)`排名`:zrank 集合名 值 (返回该值在集合中的排名,从0开始)

案例:如何利用zset实现一个文章访问量的排行榜?

3.6.3. 数据结构

SortedSet(zset)是Redis提供的一个非常特别的数据结构,一方面它等价于Java的数据结构Map<String, Double>,可以给每一个元素value赋予一个权重score,另一方面它又类似于TreeSet,内部的元素会按照权重score进行排序,可以得到每个元素的名次,还可以通过score的范围来获取元素的列表。

zset底层使用了两个数据结构
(1)hash,hash的作用就是关联元素value和权重score,保障元素value的唯一性,可以通过元素value找到相应的score值。
(2)跳跃表,跳跃表的目的在于给元素value排序,根据score的范围获取元素列表。

3.6.4. 跳跃表(跳表)

1、简介

​ 有序集合在生活中比较常见,例如根据成绩对学生排名,根据得分对玩家排名等。对于有序集合的底层实现,可以用数组、平衡树、链表等。数组不便元素的插入、删除;平衡树或红黑树虽然效率高但结构复杂;链表查询需要遍历所有效率低。Redis采用的是跳跃表。跳跃表效率堪比红黑树,实现远比红黑树简单。

2、实例

​ 对比有序链表和跳跃表,从链表中查询出51

(1)有序链表

image-20220727150205067

要查找值为51的元素,需要从第一个元素开始依次查找、比较才能找到。共需要6次比较。
(2)跳跃表

image-20220727150256931

从第2层开始,1节点比51节点小,向后比较。

21节点比51节点小,继续向后比较,后面就是NULL了,所以从21节点向下到第1层

在第1层,41节点比51节点小,继续向后,61节点比51节点大,所以从41向下

在第0层,51节点为要查找的节点,节点被找到,共查找4次。

从此可以看出跳跃表比有序链表效率要高

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值