本文主要是对介绍 Redis 数据类型会涉及到的几个概念做一个简单说明, 方便后面的学习。
对了后面的 Redis 的总结, 都是基于 Redis 5.x 版本的进行分析的。
1. 相关概念
1.1 二个小问题的思考
如果现在如果我提出 2 个问题
- Redis 的数据类型有哪些?
- Redis 的数据结构有哪些?
你会怎么回答呢?
1.2 概念的简单说明
这个是我在网上看到的一个段子:
在这个段子中
面试官想要的是 Redis 在使用时, 数据直接显示的格式, 也就是官方提供的给用户直接使用的数据结构。
官方的叫法是 data structures, 网上的一般叫做外部数据结构。
而面试者回答的 raw, int 等, 本身是从 Redis 源码出发, 数据在实现时的组织存储实现。
官方的叫法是 encoding (编码), 网上的一般叫法是内部数据结构,这一个更接近于我们认知中的数据结构。
内外数据结构和数据类型三者的关系如下:
数据结构(Data Structures):
纯粹的从一个使用者出发, 看到的数据的形式, 忽略掉内部的所有源码实现。
数据类型(Data Type):
从源码出发, 一个数据组织存储的具体的类型。Redis 提供了一个 type redisKey 的命令, 可以用来查看 key 对应的数据的数据类型。
编码类型 (Encoding Type):
数据类型的具体实现方式。Redis 也提供了一个 object encoding redisKey 的命令, 用来查看对应的 key 的编码类型。
数据类型可以理解为 Java 中各种集合的接口, 如 List, Set 等。
编码类型可以理解为 Java 中各种集合的接口的具体实现, 如 List 的实现有 ArrayList, LinkedList 等。
比如 Redis 的一个 set 命令, set key value, 存储 value 时, 已经确定了他的数据类型为 String, 然后会根据 value 是否可以转为整数, value 的长度, 从 String 的三个编码
int, embstr 和 raw 中选择一个进行数据的组织和存储。
2 Redis 当前已有的数据类型和编码
2.1 数据类型
在 5.x 版本的源码中, Redis 一共声明了 7 种数据类型
/** 可以在 server.h 中看到对应的定义 **/
#define OBJ_STRING 0 /* String object. */
#define OBJ_LIST 1 /* List object. */
#define OBJ_SET 2 /* Set object. */
#define OBJ_ZSET 3 /* Sorted set object. */
#define OBJ_HASH 4 /* Hash object. */
#define OBJ_MODULE 5 /* Module object. */
#define OBJ_STREAM 6 /* Stream object. */
2.2 编码类型
在 5.x 版本的源码中, Redis 一共声明了 11 种数据类型
/** 可以在 server.h 中看到对应的定义 **/
#define OBJ_ENCODING_RAW 0 /* Raw representation */
#define OBJ_ENCODING_INT 1 /* Encoded as integer */
#define OBJ_ENCODING_HT 2 /* Encoded as hash table */
#define OBJ_ENCODING_ZIPMAP 3 /* Encoded as zipmap */
#define OBJ_ENCODING_LINKEDLIST 4 /* No longer used: old list encoding. */
#define OBJ_ENCODING_ZIPLIST 5 /* Encoded as ziplist */
#define OBJ_ENCODING_INTSET 6 /* Encoded as intset */
#define OBJ_ENCODING_SKIPLIST 7 /* Encoded as skiplist */
#define OBJ_ENCODING_EMBSTR 8 /* Embedded sds string encoding */
#define OBJ_ENCODING_QUICKLIST 9 /* Encoded as linked list of ziplists */
#define OBJ_ENCODING_STREAM 10 /* Encoded as a radix tree of listpacks */
2.3 数据类型和编码的对应关系
OBJ_STRING 对应的编码类型为
OBJ_ENCODING_INT: 当字符串类型的值可以被解析为整数时, 同时不超过 long 的最大值时
OBJ_ENCODING_EMBSTR: 当字符串类型的值长度小于等于 44 时
OBJ_ENCODING_RAW: OBJ_ENCODING_INT 和 OBJ_ENCODING_EMBSTR 都不满足时
OBJ_LIST
OBJ_ENCODING_ZIPLIST: 列表元素数量较少且每个元素的长度较短时
OBJ_ENCODING_QUICKLIST: 列表元素数量较多时
OBJ_SET
OBJ_ENCODING_INTSET: 当集合中的元素都是整数类型且元素数量较少时
OBJ_ENCODING_HT: 当集合中的元素数量较多时
OBJ_ZSET
OBJ_ENCODING_ZIPLIST: 当有序集合中的元素数量较少且每个元素的长度较短时
OBJ_ENCODING_SKIPLIST: 当有序集合中的元素数量较多时
OBJ_HASH
OBJ_ENCODING_ZIPLIST: 当哈希对象中的键值对数量较少且每个键值对的键和值的长度都较短时
OBJ_ENCODING_HT: 当哈希对象中的键值对数量较多时
OBJ_MODULE
编码并不是 Redis 内置的编码方式, 而是为了支持模块开发而引入的一种编码方式。 每个模块可以根据自己的需求和设计选择适合的数据结构和编码方式来存储自定义数据类型
OBJ_STREAM
OBJ_ENCODING_STREAM: 唯一的选择
上面的数据类型和编码类型的对应关系, 只需要简单了解一下即可。
里面很多大概的描述, 比如较少, 较多等, 后面再详细说明, 因为里面很多会涉及到一些配置相关的。