redis数据类型

前面结算了底层的数据类型。接下来介绍redis的五大基本类型string、hash、list、set、zset,为了便于操作,Redis定义了redisObjec结构体来表示string、hash、list、set、zset五种数据类型。

	typedef struct redisObject {
		//ype表示具体的数据类型,也就是string、hash、list、set、zset
        unsigned type:4;
        //encoding表示该类型的物理编码方式,同一种数据类型可能有不同的编码方式
        unsigned encoding:4;
        //lru字段表示当内存超限时采用LRU算法清除内存中的对象
        unsigned lru:REDIS_LRU_BITS; 
        //refcount表示对象的引用计数
        int refcount;
        //ptr指针指向真正的存储结构
        void *ptr;
    } robj;

以String为例。简单来看一下引用过程
在这里插入图片描述
这样理解应该就简单多了。
再来看redisObject的上层对象dictEntity,类似HashMap的entity。Redis给每个key-value键值对分配一个dictEntry,里面有着key和val的指针,next指向下一个dictEntry形成链表,这个指针可以将多个哈希值相同的键值对链接在一起,由此来解决哈希冲突问题(链地址法)。
在这里插入图片描述

这样设计的好处是,可以针对不同的使用场景,对5中常用类型设置多种不同的数据结构实现,从而优化对象在不同场景下的使用效率。无论是dictEntry对象,还是redisObject、SDS对象,都需要内存分配器(如jemalloc)分配内存进行存储。jemalloc作为Redis的默认内存分配器,在减小内存碎片方面做的相对比较好。比如jemalloc在64位系统中,将内存空间划分为小、大、巨大三个范围;每个范围内又划分了许多小的内存块单位;当Redis存储数据时,会选择大小最合适的内存块进行存储。通过数据的类型和大小来选择合适的底层数据类型来和合适的编码格式以及内存大小存储。
下面来看五个基本类型的底层类型选择

1. String

字符串对象的底层实现可以是整数集合、raw(sds)、embstr编码的sds。embstr编码是通过调用一次内存分配函数来分配一块连续的空间,而sds需要调用两次。
int编码字符串对象和embstr编码字符串对象在一定条件下会转化为raw编码字符串对象。embstr:<=39字节的字符串。int:8个字节的长整型。raw:大于39个字节的字符串
在这里插入图片描述
int类型如果添加了字符串会直接转为 raw也就是sds
互联网主要用于存储:缓存、限流、计数器、分布式锁、分布式Session

2. List

List对象的底层实现是quicklist(快速列表,是ziplist 压缩列表 和linkedlist 双端链表 的组合)。Redis中的列表支持两端插入和弹出,并可以获得指定位置(或范围)的元素,可以充当数组、队列、栈等。
老版本是根据数据的长度来分别使用ziplist和linkedlist存储的
在这里插入图片描述
新版本使用的是quickList
在这里插入图片描述
quickList 是 zipList 和 linkedList 的混合体。它将 linkedList 按段切分,每一段使用 zipList 来紧凑存储,多个 zipList 之间使用双向指针串接起来。因为链表的附加空间相对太高,prev 和 next 指针就要占去 16 个字节 (64bit 系统的指针是 8 个字节),另外每个节点的内存都是单独分配,会加剧内存的碎片化,影响内存管理效率。
在这里插入图片描述
quicklist 默认的压缩深度是 0,也就是不压缩。为了支持快速的 push/pop 操作,quicklist 的首尾两个 ziplist 不压缩,此时深度就是 1。为了进一步节约空间,Redis 还会对 ziplist 进行压缩存储,使用 LZF 算法压缩。

3. hash

Hash对象的底层实现可以是ziplist(压缩列表)或者hashtable(字典或者也叫哈希表)
Hash对象只有同时满足下面两个条件时,才会使用ziplist(压缩列表):1.哈希中元素数量小于512个;2.哈希中所有键值对的键和值字符串长度都小于64字节。
在这里插入图片描述

4. Set

Set集合对象的底层实现可以是intset(整数集合)或者hashtable(字典或者也叫哈希表)。
intset(整数集合)当一个集合只含有整数,并且元素不多时会使用intset(整数集合)作为Set集合对象的底层实现。
在这里插入图片描述

5. ZSet

Set有序集合对象底层实现可以是ziplist(压缩列表)或者skiplist(跳跃表)。当一个有序集合的元素数量比较多或者成员是比较长的字符串时,Redis就使用skiplist(跳跃表)作为ZSet对象的底层实现。
在这里插入图片描述

Redis支持多种数据类型,包括string、hash、list、set和sorted set等。其,string是最基本、最简单的数据类型,用于存储字符串。 Hash是用于存储键值对的数据结构,其的value只能存储字符串,不允许存储其他数据类型,也不存在嵌套现象。每个hash可以存储232 - 1个键值对,并可以灵活添加或删除对象属性。但需要注意的是,hash类型并不适合存储大量对象,也不应该将hash作为对象列表使用,因为遍历整体数据的效率可能会较低。 除了string和hash类型,Redis还支持list、set和sorted set等数据类型。List是一个有序的字符串列表,可以进行插入、删除和查找等操作。Set是一个无序的字符串集合,可以进行元素的添加、删除和查找操作,并且不允许重复元素的存在。Sorted Set是一个有序的字符串集合,每个元素都有一个对应的score,可以根据score进行排序和范围查找。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Redis 数据类型](https://blog.csdn.net/weixin_52851967/article/details/122670564)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值