【redis】五种数据类型和编码方式
文章目录
- 五种数据类型
- 编码方式
- string
- hash
- list
- set
- zset
- 查询内部编码
五种数据类型
- 字符串:
Java
中的String
- 哈希:
Java
中的HashMap
- 列表:
Java
中的List
- 集合:
Java
中的Set
- 有序集合:除了存
member
之外,还有权重score
(权重、分数)
Redis 底层在实现上述数据结构的时候,会在源码层面,针对上述实现进行特定优化,来达到节省时间/节省空间的效果
- 内部具体实现的数据结构还会有变化
Redis
向你承诺,现在我有个 hash 表,你进行查询、插入、删除操作,都保证时间复杂度是 O ( 1 ) O(1) O(1)- 但是,这个背后的实现,不一定就是一个标准的
hash
表,可能在特定的场景下,使用别的数据结构实现,但是仍然保证时间复杂度符合承诺
编码方式
- 数据结构:Redis 承诺给你的,也可以理解成数据类型
- 编码方式:Redis 内部底层的实现
同一个数据类型,背后可能的编码实现方式是不同的,会根据特定场景优化
string
string
:Redis
会自动适应,程序员在使用Redis
的时候一般感知不到raw
:最基本的字符串。底层就是持有byte
数组int
:Redis
通常也可以用来实现“计数”这样的功能(帖子的点赞数,评论数…)。当value
就是一个整数的时候,此时可能Redis
直接使用int
来保存embstr
:针对短字符串进行的特殊优化
hash
hash
hashtable
:最基本的哈希表(这里是Redis
内部的哈希表的实现,和Java
标准库中的HashTable
不一样)ziplist
:压缩列表,针对一些特殊的场景下,将数据进一步压缩,从而减少空间(在哈希表里面的元素较少的时候,可能就优化成ziplist
了)
[!quote] 为什么要压缩?为什么是元素少的时候才压缩?
Redis
上有很多key
,可能某些key
的value
是hash
。此时,如果key
特别多,对应的hash
也特别多,但是每个hash
又不大的情况下,就尽量去压缩,压缩之后就可以让整体占用的内存更小了- 压缩是一种优化措施,但在大量数据的情况下,压缩和解压会增加额外的计算开销。元素较多时,
Redis
通常会自动将存储方式从ziplist
转为hashtable
等更高效的存储方式,以避免在大量数据操作时发生性能瓶颈。
list
list
linkedlist
:链表:非常方便从中间位置查找删除ziplist
:压缩列表(和hash
里面的一样)
- 从
Redis 3.2
开始,引入了新的实现方式:quicklist
。其同时兼顾了linkedlist
和ziplist
的优点。quicklist
就是一个链表,每个元素又是一个ziplist
set
set
hashtable
intset
:集合中存的都是整数,就会被优化成intset
zset
zset
skiplist
:跳表,其也是链表,只是不同于普通的链表。每个节点上有多个指针域,巧妙地搭配这些指针域的指向,就可以做到从跳表上查询元素的复杂度是 O ( l o g N ) O(logN) O(logN)(类似于平衡二叉搜索树(如 AVL 树、红黑树))ziplist
:
查询内部编码
语法:
object encoding
Redis
会自动根据当前的事迹情况选择内部的编码方式,自动适应。那我们是否要记住,什么时候使用什么编码方式呢?
- 只记思想,不记数字!
网上的说法:如果字符串长度小于 39 字节,使用
embstr
,超过 39 字节,使用raw
- 记数字,没有任何意义
- 数字都是可配置的
- 数字是怎么来的?需要考证清楚
- 相比于知道数字,更重要的是知道数字是怎么得到的,就可以根据所处的实际场景,重新得到这样的数字